B4A Library PhilipsHUE SDK - Control your HUE System

A B4J Version is available here.

HUE

Author:
Version: 0.41

Requirements:
1- You need to follow the instructions here to get your "Username" which you them can use to Authenticate your app against the SDK.
Once you have the username (kind of a Unique ID) you can use this username and adapt the Examplecode which actually uses my Username. You need to change it to yours for sure.
- You Device must be connected to the same Network as your HueBridge(s)

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim sdk As PHHueSDK
    Dim APselected As PHAccessPoint
    Dim BridgeSelected As PHBridge
    ' Define here the username you got using the registration with the Bridge debug tool
    ' See https://www.developers.meethue.com/documentation/getting-started
    ' to learn how to create the "Username" for you to Access the SDK
    Private HUEusername = "ofmxXcuFVe0okMRIxcyaSQRMtqTFBS9ANBjfCboI"
    Dim hueoverview As Map

    ' Only used when using the httpapi. Not needed here.
    'Private bridgeURL As String = "http://192.168.192.109/api/"&HUEusername&"/"
    Private lvhue As ListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
    hueoverview.Initialize

    ' Initialize the HUESDK and then the Manager inside the SDK
    sdk.Initialize("HUE","QuickStartApp")
    sdk.InitManager

    ' Setup the AccessPoint manually here.
    Dim ap As PHAccessPoint
    ap.Initialize("")
    ap.IpAddress = "192.168.192.109"    ' IP of AccessPoint
    ap.MacAddress = "00:17:88:12:CB:6E" ' Mac-Address
    ap.BridgeId = "001788FFFE12CB6E"    ' ID (usually the Mac without :)
    ap.Username = HUEusername           ' Define the Username here to gain Access to this AccessPoint
    ' Connect the SDK with the AccessPoint
    sdk.connect(ap)
    wait for HUE_onBridgeConnected(bridge As PHBridge, info As String)
    Log($"Activity_Create.HUE_onBridgeConnected(${bridge},${info})"$)
    BridgeSelected = bridge

    'sdk.addBridge(bridge)
    Dim lights As List
    lights = bridge.AllLights
    Dim lightnames As List = sdk.getLightNames(lights)

    If lights.IsInitialized Then
        If lights.Size > 0 Then
            For i = 0 To lights.Size-1
                Dim light As PHLight = lights.Get(i)
                Dim state As PHLightState = light.LastKnownLightState
                Dim name As String = lightnames.Get(i)
                hueoverview.Put("LightName"&light.Identifier,name)   
                Log($"Light = ${name} = ${light.Identifier} / Manufacturer = ${light.ManufacturerName} Model ${light.ModelNumber} LightType = ${light.LightType}"$)
                hueoverview.Put("Light"&light.Identifier,light)
                hueoverview.Put("LightState"&light.Identifier,state)
            Next
        End If
    End If

    Dim groups As List
    groups = bridge.AllGroups
    If groups.IsInitialized Then
        If groups.Size > 0 Then
            For i = 0 To groups.Size-1
                Dim group As PHGroup = groups.Get(i)
                Log($"Group = ${group.Name} / Type = ${group.GroupType} UniqueID = ${group.UniqueId}"$)
                lvhue.AddSingleLine2(group.Name,group)
                Dim grlights As List = group.LightIdentifiers
                If grlights.IsInitialized And grlights.Size > 0 Then
                    For o = 0 To grlights.Size -1
                        Dim light As PHLight = hueoverview.Get("Light"&grlights.Get(o))
                        Dim state As PHLightState = hueoverview.Get("LightState"&grlights.Get(o))
                        Log($"${light.Identifier}: ${hueoverview.Get("LightName"&grlights.Get(o))} ${light.ModelNumber} - ${light.LightType}"$)
                        lvhue.AddTwoLines2(light.Identifier&": "&hueoverview.Get("LightName"&grlights.Get(o)),$"${light.ModelNumber} - ${light.LightType}"$,Array(light,state))
                    Next
                End If
                'Log(group.LightIdentifiers)
            Next
        End If
    End If

    Dim sensors As List
    sensors = bridge.AllSensors
    If sensors.IsInitialized Then
        If sensors.Size > 0 Then
            For i = 0 To sensors.Size-1
                Dim sensor As PHSensor = sensors.Get(i)
                Log($"Sensor = ${sensor.Name} / Type = ${sensor.ModelId} - ${sensor.ManufacturerName} - UniqueID = ${sensor.UniqueId}"$)
            Next
        End If
    End If




    Log("Rules: "&bridge.AllRules)
    Log("Scenes: "&bridge.AllScenes)
    'Log("Sensors: "&bridge.AllSensors)
    Log("AllShedules: "&bridge.getAllSchedules(True))
    Log("AllTimers: "&bridge.getAllTimers(True))

End Sub

You can change the Lightstate as this
please note how the Value is set in the Code above. The point is that we need to have both Objects. The Light object and it´s LightState object which we get from the SDK.

B4X:
Sub lvhue_ItemClick (Position As Int, Value As Object)
    Log($"Itemclick(${Position}, ${Value})"$)
    Dim obj() As Object = Value
    Dim light As PHLight = obj(0)
    Dim state As PHLightState = obj(1)
    Log("Lightstate is "&state.ON)
    If state.ON Then
        state.ON = False
        BridgeSelected.updateLightState(light,state)
    Else
        state.ON = True
        BridgeSelected.updateLightState(light,state)
    End If
End Sub

NOTES:
- If you do not have a username then you can use the SDK to search for AccessPoints which then will raise an event for the Bridge found. If you want to use this bridge then you probably need to authenticate (calling the method of the sdk)...
Once you are authenticated you can use the bridge.
Until you you quit your app. Once closed you need to authenticate again after a new search.

The best way is to register a username an connect to your Bridge using username and known IP. Using a valid username give your direct access to the bridge.

HAVE FUN :)

Some Notes about user findings (Thank you @johndb!)

To change the state of a Light/Group/Screne:
It appears that you must create a new PHLightState object, set the parameters that you would like to adjust, and pass the new object to the updateLightState function. This eliminates the blinking and provides a smooth transition.
B4X:
Sub lvhue_ItemClick (Position As Int, Value As Object)
    Log($"Itemclick(${Position}, ${Value})"$)
    Dim obj() As Object = Value
    Dim light As PHLight = obj(0)
    Dim state As PHLightState = obj(1)
    Dim NewLightState As PHLightState
    NewLightState.Initialize("")
    NewLightState.Brightness = 254 ' 125
    NewLightState.X = 0.4574
    NewLightState.Y = 0.41
    BridgeSelected.updateLightState(light,NewLightState)
End Sub

Infos about Cached Updates:
This problem above has been solved. Here are my lessons learned to date:
  1. You must create a new PHLightState object, set the parameters that you would like to adjust, and pass the new object to the updateLightState function. This eliminates the blinking and provides a smooth transition.
  2. You cannot use "wait for <object>_onCacheUpdated(cacheNotifications As List, bridge As PHBridge)" after your "updateLightState" function call. It may not be called. The "_onCacheUpdated" event will only be called if a particular state is different than the light's current state in one of the LightState parameters. All of the "updateLightState" calls are queued for execution in the library. The "_onCacheUpdated(cacheNotifications" event will only we called if there is a change in one of the LightState parameters.
  3. You can use "wait for <object>_onAccessPointsFound(.." directly after the function call "sdk.search(True,True)".
  4. You can use "wait for <object>_onBridgeConnected (..." directly after the function call "sdk.connect(<access point>)".
I'll post more when I discover other operational anomalies as I encounter them. I hope this helps other users who would like to explore this library.
 

Attachments

  • HUEV0.2.zip
    433.3 KB · Views: 368
  • PhilipsHueExample.zip
    9.4 KB · Views: 396
  • HUEV0.21.zip
    446.8 KB · Views: 376
  • HUEV0.3.zip
    450.1 KB · Views: 386
  • HUEV0.41.zip
    64.4 KB · Views: 361
Last edited:

DonManfred

Expert
Licensed User
Longtime User
B4X:
    "onAccessPointsFound(APs As List)",
    "onAuthenticationRequired(ap As PHAccessPoint)",
    "onBridgeConnected(bridge As PHBridge, info As String)",
    "onCacheUpdated(cacheNotifications As List, bridge As PHBridge)",
    "onConnectionLost(as As PHAccessPoint)",
    "onConnectionResumed(bridge As PHBridge)",
    "onError(code As Int, message As String)",
    "onParsingErrors(errors As List)"

These events are all from the SDKwrapper. It is ONE listener which is listening and who raises these Events. The listener is created when initializing the SDK
 

johndb

Active Member
Licensed User
Longtime User
Great lib !

Do you at which rate you can change the color of a light ?

I ask this because a few years ago I wrote this App : https://play.google.com/store/apps/details?id=fr.free.julienGley.ebulbMusic
it follows music at a quite decent speed. Milight are connected via UDP which is very fast.
I don't have any Hue... Would it worth to buy one to try to port my App ?
I'm not sure how fast you can control the lights. The HUE API uses the RESTful interface for HUE component control. I think that the library that @DonManfred wrapped would interface the HUE system in a similar manner. I have finished my multi-band audio filter code and will be integrating the HUE lighting control within a week or two so I'll let you know how fast the control is. I like your app by the way :)

Cheers,

John
 
Last edited:

freedom2000

Well-Known Member
Licensed User
Longtime User
I'm not sure how fast you can control the lights. The HUE API uses the RESTful interface for HUE component control. I think that the library that @DonManfred wrapped would interface the HUE system in a similar manner. I have finished my multi-band audio filter code and will be integrating the HUE lighting control within a week or two so I'll let you know how fast the control is. I like your app by the way :)

Cheers,

John
RestFul is using tcp if I am right ? Probably slower than UDP !
Thank you keep us informed of your progress (and to like my App ;))
 

johndb

Active Member
Licensed User
Longtime User
@DonManfred. I have written the HUE code in a class and have discovered a problem with the sdk's "_onCacheUpdated" event. It is not called in response to an "updateLightState" call when the event sub is located in the class. The other events such as "_onBridgeConnected" and "_onAuthenticationRequired" are called properly. Could the callback for "onCacheUpdated" in the library be hardwired to the activity by error instead of dynamic?

Thanks for your help,

John
This problem above has been solved. Here are my lessons learned to date:
  1. You must create a new PHLightState object, set the parameters that you would like to adjust, and pass the new object to the updateLightState function. This eliminates the blinking and provides a smooth transition.
  2. You cannot use "wait for <object>_onCacheUpdated(cacheNotifications As List, bridge As PHBridge)" after your "updateLightState" function call. It may not be called. The "_onCacheUpdated" event will only be called if a particular state is different than the light's current state in one of the LightState parameters. All of the "updateLightState" calls are queued for execution in the library. The "_onCacheUpdated(cacheNotifications" event will only we called if there is a change in one of the LightState parameters.
  3. You can use "wait for <object>_onAccessPointsFound(.." directly after the function call "sdk.search(True,True)".
  4. You can use "wait for <object>_onBridgeConnected (..." directly after the function call "sdk.connect(<access point>)".
I'll post more when I discover other operational anomalies as I encounter them. I hope this helps other users who would like to explore this library.

Cheers,

John
 
Last edited:

johndb

Active Member
Licensed User
Longtime User
RestFul is using tcp if I am right ? Probably slower than UDP !
Thank you keep us informed of your progress (and to like my App ;))
You are correct, RESTful communications uses tcp/ip protocol. The way the HUE system works is that you can consider the HUE Bridge as an WEB Server which communicates with external programs using RESTful communications. The Bridge communicates with the Lights using ZigBee Light Link protocol over RF(2.4 Ghz). All of the lights are on a radio mesh network whereby each light can "talk" to other lights, extending the range of the "mesh" network.

Tcp/ip is actually fairly fast in most modern WIFI devices including the HUE bridge so I think speeds would be quite good. The ZigBee radio network communications is also very fast as it uses a very optimized protocol on its radio network. I'll let you know how fast it is as I'll be pushing it to its limit. :D

Update: See post #27 for speed results.

John
 
Last edited:

johndb

Active Member
Licensed User
Longtime User
You are correct, RESTful communications uses tcp/ip protocol. The way the HUE system works is that you can consider the HUE Bridge as an WEB Server which communicates with external programs using RESTful communications. The Bridge communicates with the Lights using ZigBee Light Link protocol over RF(2.4 Ghz). All of the lights are on a radio mesh network whereby each light can "talk" to other lights, extending the range of the "mesh" network.

Tcp/ip is actually fairly fast in most modern WIFI devices including the HUE bridge so I think speeds would be quite good. The ZigBee radio network communications is also very fast as it uses a very optimized protocol on its radio network. I'll let you know how fast it is as I'll be pushing it to its limit. :D

John
I ran some speed tests for changing various states on lights. The rate at which can change the various states (i.e. on, off, intensity, color) is not that great. You can get a minimum rate of 50ms for a short burst of about 1-2 seconds without commands being skipped. It appears that the Bridge's command buffer isn't very large and can't maintain a sustained burst interval rate. This sustained rate is much less as you add more lights. At 100ms sustained command throughput, it would appear that a reliable single light change is suitable for around 10-15 seconds before the HUE starts skipping commands. The system response gets worse as you add more lights.

Under normal operations such as turning on and off lights, changing colors, and that sort of thing by the normal HUE user, the response would be acceptable as they are not pushing a high burst of commands. So, it appears that short bursts will give you acceptable results but sending sustained commands for lengthy intervals will not.

I'm still playing with this to see if I can better results ... :)

Let me clear that under normal operation the HUE system is great for lighting control and this library does just that. I'm pushing the boundaries for an audio driven multi-frequency band light organ that I'm designing which requires operation that is pushing the limits of the HUE system.

Your experience may vary ...
 
Last edited:

freedom2000

Well-Known Member
Licensed User
Longtime User
Let me clear that under normal operation the HUE system is great for lighting control and this library does just that. I'm pushing the boundaries for an audio driven multi-frequency band light organ that I'm designing which requires operation that is pushing the limits of the HUE system.

Your experience may vary ...

If you want to follow music, the output should be at quite high freq...
Keep us informed I like these stuffs :)
 

johndb

Active Member
Licensed User
Longtime User
If you want to follow music, the output should be at quite high freq...
Keep us informed I like these stuffs :)
I like this stuff too :D
The bandpass filter system I developed will handle up to 30 bands comfortably but for music I like to limit it to 8. I'll limit my bands to 3 for my color organ lighting control project due to light control limitations. We're going off topic here and I'm sure that @DonManfred won't like that. We can take this PM or create another topic.

John
 

johndb

Active Member
Licensed User
Longtime User
Hue motion sensors are capable of sensing light levels, temperatures, determining whether it is night or day, and motion detection. Is this library capable of accessing these features and if so how?

Thanks for your help,

John
 

DonManfred

Expert
Licensed User
Longtime User
Is this library capable of accessing these features and if so how?
i don´t know. You must try. I do not have such a device and do not know what kind of data (objects) it needs.
I guess it should work if it is a HUE Compponent. But if they are specific Objecttypes then the ib needs an update to support them.
 

johndb

Active Member
Licensed User
Longtime User
i don´t know. You must try. I do not have such a device and do not know what kind of data (objects) it needs.
I guess it should work if it is a HUE Compponent. But if they are specific Objecttypes then the ib needs an update to support them.
Is your library a wrap of an existing library or did you write the library with a direct RESTful interface? If it was a wrap could you please provide a link to your source library?

Thanks,

John
 

DonManfred

Expert
Licensed User
Longtime User
There is no source library. I started with the docs and the provided jar from phillips. I wrapped all Objects i needed to get all my HUE "Devices" working.

But i now ordered a MotionSensor at eBay. I´ll update the lib as soon at it arrives with the new needed Objects...

ETA: I already added some new Objects :D
- PHDaylightSensorState, PHDaylightSensor
- PHGenericStatusSensorState, PHGenericStatusSensor
- PHGeofenceSensorState, PHGeofenceSensor
- PHHumiditySensorState, PHHumiditySensor
- PHOpenCloseSensorState, PHOpenCloseSensor
- PHPresenceSensorState, PHPresenceSensor
- PHTemperatureSensorState, PHTemperatureSensor

For now you can try the version attached. I´ll update if i get the Motionsensor....

Please create a NEW Thread if you encounter any problem. Stop posting to the library thread please.

PD: I don´t know how the Presencesensor or the GeoFenceSensor works... But i would like to know; if you have any useful informations about these please share them :)
 

Attachments

  • HUEV0.4.zip
    61.9 KB · Views: 252
Last edited:

DonManfred

Expert
Licensed User
Longtime User
For now you can try the version attached. I´ll update if i get the Motionsensor....
Ok, i got the Motion sensor... 0.4 is nearly OK with it. Only one object was missing to wrap. The PHDaylightSensorConfiguration
It is added to V0.41.

I´ll update Post #1 with the new one.

From what i saw. Each of the Sensors do have a correspondending "Sensorconfiguration" which encapsulate the device specific properties. The BaseSensorConfiguration is the Parent of all Sensors. For now only the Daylightsensorconfiguration is wrapped.

If you are missing more Objects; feel free to sponsor a sample "device" to me ;-) . I´ll be glad to extend the Library.
 

johndb

Active Member
Licensed User
Longtime User
Ok, i got the Motion sensor... 0.4 is nearly OK with it. Only one object was missing to wrap. The PHDaylightSensorConfiguration
It is added to V0.41.

I´ll update Post #1 with the new one.

From what i saw. Each of the Sensors do have a correspondending "Sensorconfiguration" which encapsulate the device specific properties. The BaseSensorConfiguration is the Parent of all Sensors. For now only the Daylightsensorconfiguration is wrapped.

If you are missing more Objects; feel free to sponsor a sample "device" to me ;-) . I´ll be glad to extend the Library.
Thank you very much @DonManfred for your work. I'll test out the updated library for the devices that I currently have in my home and will let you you know the outcome.

Thanks again,

John
 

johndb

Active Member
Licensed User
Longtime User
Ok, i got the Motion sensor... 0.4 is nearly OK with it. Only one object was missing to wrap. The PHDaylightSensorConfiguration
It is added to V0.41.

I´ll update Post #1 with the new one.

From what i saw. Each of the Sensors do have a correspondending "Sensorconfiguration" which encapsulate the device specific properties. The BaseSensorConfiguration is the Parent of all Sensors. For now only the Daylightsensorconfiguration is wrapped.

If you are missing more Objects; feel free to sponsor a sample "device" to me ;-) . I´ll be glad to extend the Library.
I ran your example 2 (post #2). It does not return a list of sensors just an empty list whereas prior to the latest library version the sample code received a complete list of sensors.
 
Top