Skip to content

API Philips Hue

ARIbemoss edited this page May 11, 2017 · 1 revision

[Back to BEMOSS Connectivity Layer]

API Interface: Philips Hue


API interface code


Attributes

This API interface supports the following attributes that can be found from the device:

#!python

status          GET    POST      ON/OFF status of light
xy              GET    POST      color in xy format 
hue             GET    POST      hue of light (0-65535)
bri             GET    POST      brightness of light (0-100)
sat             GET    POST      saturation of light (0-100)
number_lights   GET              Number of lights connected to hub
effect          GET    POST      Effects like colorloop

Capabilities

This API interface supports three methods: getDeviceStatus, setDeviceStatus, and identifyDevice.

The getDeviceStatus method, if called, sends a HTTP GET request to the device IP address, and receives the data from the device as a JSON format response:

#!python

    def getDeviceStatus(self):
        _urlData = self.get_variable("address")
        try:
            _deviceUrl = urllib2.urlopen(_urlData)
            print(" {0}Agent is querying its current status (status:{1}) please wait ...".
                  format(self.variables.get('agent_id', None), _deviceUrl.getcode()))
            if (_deviceUrl.getcode() == 200): #200 means data is get successfully
                #currentstatus = self.getDeviceStatusJson(deviceUrl.read().decode("utf-8"))
                self.getDeviceStatusJson(_deviceUrl.read().decode("utf-8")) #convert string data to JSON object then interpret it
                self.printDeviceStatus()
            else:
                print (" Received an error from server, cannot retrieve results " + str(_deviceUrl.getcode()))
        except:
            print('ERROR: classAPI_PhilipsHue failed to getDeviceStatus')

The getDeviceStatusJson is a supporting method that parses the JSON response from device and converts the attribute names appropriate to OS layer according to the API between OS and Connectivity layer.

#!python

    def getDeviceStatusJson(self,data):  
        # Use the json module to load the string data into a dictionary
        _theJSON = json.loads(data)
        #1. status
        if _theJSON["action"]["on"] == True:
            self.set_variable('status',"ON")
        else:
            self.set_variable('status',"OFF")
        #2. brightness convert to %
        self.set_variable('brightness',int(round(float(_theJSON["action"]["bri"])*100/255,0)))
        #3. color convert to RGB 0-255
        self.set_variable('hue', _theJSON["action"]["hue"])
        self.set_variable('xy', _theJSON["action"]["xy"])
        self.set_variable('ct', _theJSON["action"]["ct"])
        self.set_variable('color', self.convertcolorxyYtoRGB(self.get_variable('xy'),float(_theJSON["action"]["bri"])/255))
        #4. saturation convert to %
        self.set_variable('saturation',int(round(float(_theJSON["action"]["sat"])*100/255,0)))
        self.set_variable('effect',_theJSON["action"]["effect"])
        self.set_variable('colormode',_theJSON["action"]["colormode"])
        for k in _theJSON["lights"]:
            self.set_variable("lights{}".format(k), k)
        self.set_variable('number_lights', len(_theJSON["lights"]))
        self.set_variable('name',_theJSON["name"])

The setDeviceStatus method receives attributes to change in device as arguments from the OS layer in JSON format. It checks for message format validity and then converts the attribute names to the names appropriate for device. It then sends the attributes with new values as JSON format data in the POST request to device IP address. It returns back to OS 1 or 0 for 'success' or 'failure' respectively.

#!python

    def setDeviceStatus(self, postmsg):
        setDeviceStatusResult = True
        #Ex. postmsg = {"on":True,"bri":100,"hue":50260,"sat":200}
        _urlData = self.get_variable("address")
        if self.isPostMsgValid(postmsg) == True: #check if the data is valid
            _data = json.dumps(self.convertPostMsg(postmsg))
            _data = _data.encode(encoding='utf_8')
            _request = urllib2.Request(_urlData+'action')
            _request.add_header('Content-Type','application/json')
            _request.get_method = lambda: 'PUT'
            try:
                _f = urllib2.urlopen(_request, _data) #when include data this become a POST command
                print(" {0}Agent for {1} is changing its status with {2} please wait ..."
                .format(self.variables.get('agent_id', None), self.variables.get('model', None), postmsg))
                print(" after send a POST request: {}".format(_f.read().decode('utf-8')))
            except:
                print("ERROR: classAPI_PhilipsHue connection failure! @ setDeviceStatus")
                setDeviceStatusResult = False
        else:
            print("The POST message is invalid, try again\n")
        return setDeviceStatusResult

Finally, the identifyDevice method, if called, sends a colorloop change request to device. It then waits for 10 seconds and then reverts the status back to previous status. Like setDeviceStatus, it returns boolean 1/0 for success/failure.

#!python

    def identifyDevice(self):
        identifyDeviceResult = False
        # _urlData = self.get_variable("address")
        print(" {0}Agent for {1} is identifying itself by doing colorloop. Please observe your lights"
              .format(self.variables.get('agent_id',None), self.variables.get('model',None)))
        try:
            self.setDeviceStatus({"effect": "colorloop"})
            time_iden = 10 #time to do identification
            t0 = time.time()
            self.seconds = time_iden
            while time.time() - t0 <= time_iden:
                self.seconds = self.seconds - 1
                print("wait: {} sec".format(self.seconds))
                time.sleep(1)
            self.setDeviceStatus({"effect": "none"})
            identifyDeviceResult = True
        except:
            print("ERROR: classAPI_PhilipsHue connection failure! @ identifyDevice")
        return identifyDeviceResult

[Back to BEMOSS Connectivity Layer]

Clone this wiki locally