Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for "lightbulbs" connected to Hue #142

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions accessories/Hue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Basic Hue integration
Allows control of incompatible Accessories like Osram Lightify Plugs (Osram Smart+)

I have no idea if this is a good implementation, but it works for me :D
"""
import logging
import signal
import certifi
import requests
import urllib3

from pyhap.accessory import Bridge, Accessory
from pyhap.accessory_driver import AccessoryDriver
from pyhap.const import CATEGORY_LIGHTBULB

logging.basicConfig(level=logging.INFO)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe leave this to the module that starts HAP, e.g. the main.py

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you decide to remove it, can you use logger = logging.getLogger(__name__)


http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED',
ca_certs=certifi.where())

# no auto discovery yet, see the getting started guide on how to get the secret
# https://www.developers.meethue.com/documentation/getting-started
hue_ip = ""
hue_secret = ""


class LightBulb(Accessory):

category = CATEGORY_LIGHTBULB

def __init__(self, *args, id, **kwargs):
super().__init__(*args, **kwargs)

serv_light = self.add_preload_service('Lightbulb')
self.char_on = serv_light.configure_char(
'On', setter_callback=self.set_bulb)

self.id = id

def __setstate__(self, state):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not needed now (if you don't plan to pickle the accessory)

self.__dict__.update(state)

@Accessory.run_at_interval(10)
def run(self):
r = requests.get("http://{}/api/{}/lights/{}".format(hue_ip, hue_secret, self.id))
r.raise_for_status()
self.char_on.set_value(r.json()['state']['on'])
logging.info("get status for light {}".format(self.id))

def set_bulb(self, value):
logging.info("setting state: {}".format(value))
if value:
r = requests.put("http://{}/api/{}/lights/{}/state".format(hue_ip, hue_secret, self.id), json={"on": True})
r.raise_for_status()
else:
r = requests.put("http://{}/api/{}/lights/{}/state".format(hue_ip, hue_secret, self.id), json={"on": False})
r.raise_for_status()
logging.info(r.content)


def get_bridge():
"""Call this method to get a Bridge instead of a standalone accessory."""
bridge = Bridge(display_name='Bridge')

# discover hue lights
r = requests.get("http://{}/api/{}/lights".format(hue_ip, hue_secret))
r.raise_for_status()

for key, value in r.json().items():
id = key
name = value["name"]
logging.info("Found light: {} - {}".format(id, name))
light = LightBulb(display_name=name, id=id)
bridge.add_accessory(light)

return bridge


acc = get_bridge()
# Start the accessory on port 51826
driver = AccessoryDriver(acc, port=51826)
# We want KeyboardInterrupts and SIGTERM (kill) to be handled by the driver itself,
# so that it can gracefully stop the accessory, server and advertising.
signal.signal(signal.SIGINT, driver.signal_handler)
signal.signal(signal.SIGTERM, driver.signal_handler)
# Start it!
driver.start()