Homeseer HSM200 Zwave LED On/Off and Color Control

Tags: #<Tag:0x00007f738fdf4cb0>

There are a few threads on this subject over the years, which I’ll link below for reference. It looks to me like many of the hooks to control this device are available but they don’t seem to automatically appear when the device is added to the network. The (crude) documentation that comes with the device indicates that COMMAND_CLASS_COLOR must be implemented to control the LED.

It looks like there are tests in HA to test this feature of OpenZwave: https://github.com/home-assistant/core/search?q=COMMAND_CLASS_COLOR&unscoped_q=COMMAND_CLASS_COLOR

However, grepping for COMMAND_CLASS_COLOR in /config for both OZW 1.4 and 1.6 comes up empty – I’m not sure if this is meaningful or not. When I attach the device, there is this block in the zwave configuration xml:

			<CommandClass id="51" name="COMMAND_CLASS_COLOR" version="1" request_flags="2" innif="true" colorchannels="28">
				<Instance index="1" />
				<Value type="string" genre="user" instance="1" index="0" label="Color" units="#RRGGBB" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="#000000" />
				<Value type="list" genre="user" instance="1" index="1" label="Color Index" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" vindex="0" size="18">
					<Item label="Off" value="0" />
					<Item label="Cool White" value="1" />
					<Item label="Warm White" value="2" />
					<Item label="Red" value="3" />
					<Item label="Lime" value="4" />
					<Item label="Blue" value="5" />
					<Item label="Yellow" value="6" />
					<Item label="Cyan" value="7" />
					<Item label="Magenta" value="8" />
					<Item label="Silver" value="9" />
					<Item label="Gray" value="10" />
					<Item label="Maroon" value="11" />
					<Item label="Olive" value="12" />
					<Item label="Green" value="13" />
					<Item label="Purple" value="14" />
					<Item label="Teal" value="15" />
					<Item label="Navy" value="16" />
					<Item label="Custom" value="17" />
				</Value>
				<Value type="int" genre="system" instance="1" index="2" label="Color Channels" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="-2147483648" max="2147483647" value="28" />
			</CommandClass>

It has the same command class ID as the HA tests but… where does this information come from? It seems like the color control information is there but nothing from HA sees this and creates an entity to set/control these features (like light.hms200_entity). Where does the information to populate the xml come from – is this extracted fromt he device itself upon attach? Also, is there any example from which I can create the necessary modifications to HA to cause a light (or switch, whatever) entity to be created when this device is attached?

Also, it appears something may not be complete in the way the device is pulled in: here are the first few lines from the zwave config xml:

	<Node id="28" name="EZM" location="" basic="4" generic="7" specific="1" roletype="5" devicetype="3079" nodetype="0" type="Notification Sensor" listening="true" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" secured="true" query_stage="Complete">
		<Manufacturer id="c" name="HomeSeer Technologies">
			<Product type="4" id="1" name="Unknown: type=0004, id=0001" />
		</Manufacturer>

It’s the Product type = 4, id=1, name=Unknown line that appears suspect. Thanks for any help. This is a pretty cool device that I figured I would experiment with, and having the LED work will be a big plus (somewhat justifying the price tag). Here are a few past posts that have been left hanging unresolved:


For more details on the solution see this post: Homeseer HSM200 Zwave LED On/Off and Color Control

The following excerpt is from the get_device function in zwave/light.py. It looks like it’s handling “COMMAND_CLASS_SWITCH_COLOR” but doesn’t handle COMMAND_CLASS_COLOR – thus, a light entity will get created if the config xml includes COMMAND_CLASS_SWITCH_COLOR but not for one that contains COMMAND_CLASS_COLOR? Does anyone know if this is the spot at which handling should be added? If so, I can try to figure out how to have a light added with on/off state and a color attribute.

OZW’s COMMAND_CLASS_COLOR is the same thing as HA zwave’s const.COMMAND_CLASS_SWITCH_COLOR.

HA will only create light entities for devices that look like lights. The device classes need to match what HA thinks is a light, plus the node must support COMMAND_CLASS_SWITCH_MULTILEVEL. After that, COLOR is an optional value.

Since the device is reporting generic="7" specific="1", it doesn’t match the schema for a light. In HA those would be detected as GENERIC_TYPE_SENSOR_NOTIFICATION and SPECIFIC_TYPE_NOTIFICATION_SENSOR respectively. The node still needs to report MULTILEVEL_SWITCH command though, as HA doesn’t appear to support color binary switches.

The OpenZWave Beta would have the same problem, however you’d be able to control the device independently using MQTT, bypassing HA.

So it seems it may not be as simple as I initially thought to get HA to create a light entity for this device. It does support MULTILEVEL_SWITCH:

			<CommandClass id="38" name="COMMAND_CLASS_SWITCH_MULTILEVEL" version="2" innif="true">
				<Instance index="1" />
				<Value type="byte" genre="user" instance="1" index="0" label="Level" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
				<Value type="button" genre="user" instance="1" index="1" label="Bright" units="" read_only="false" write_only="true" verify_changes="false" poll_intensity="0" min="0" max="0" />
				<Value type="button" genre="user" instance="1" index="2" label="Dim" units="" read_only="false" write_only="true" verify_changes="false" poll_intensity="0" min="0" max="0" />
				<Value type="bool" genre="system" instance="1" index="3" label="Ignore Start Level" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="True" />
				<Value type="byte" genre="system" instance="1" index="4" label="Start Level" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
			</CommandClass>

I don’t want just a light, I want the other entities plus a light. Controlling from MQTT with the OZW beta is an acceptable option, however, if there’s not a reasonably simple path to get a light entity created for this device. Thanks for the info.

Well you have the best case scenario. All you should have to do is modify the discovery schema to allow “notification sensor” device types to have lights.

const.DISC_COMPONENT: "light",
        const.DISC_GENERIC_DEVICE_CLASS: [
            const.GENERIC_TYPE_SWITCH_MULTILEVEL,
            const.GENERIC_TYPE_SWITCH_REMOTE,
            const.GENERIC_TYPE_SENSOR_NOTIFICATION,
        ],
        const.DISC_SPECIFIC_DEVICE_CLASS: [
            const.SPECIFIC_TYPE_POWER_SWITCH_MULTILEVEL,
            const.SPECIFIC_TYPE_SCENE_SWITCH_MULTILEVEL,
            const.SPECIFIC_TYPE_NOT_USED,
            const.SPECIFIC_TYPE_NOTIFICATION_SENSOR,
        ],

You should then get a light entity with a color wheel to set the RGB values.

You can download the existing zwave component and install it as a custom component (copy all files to <config_dir>/custom_components/zwave.

Otherwise, you could submit an issue to HA. It’s unlikely anyone will update the zwave integration for you. Probably someone would update the ozw integration but you’d need to submit an MQTT dump.

That’s better than I expected. I have no issues with generating and maintaining a custom component for a deprecated (or at least, on its way out) feature. If it works, what are the odds of a pull request being accepted? I’d be willing to go through the hassle if ozw is far enough out that someone else might benefit.

I’ll update once I get a chance to test. I’m assuming I need to remove the node and reattach it, not just restart?

I think they might accept a PR, but I can’t say for sure.

You shouldn’t need to remove the node, just restart HA after the component is added.

I did this, restarted HA, and indeed a light entity is created. There may be more modifications required, no matter what I put into the light.turn_on service data it seems to send color “#ff00000000” when the device wants #ff0000 or “Red” for example. Here is what is sent (doesn’t actually turn the light on):

2020-09-01 11:35:17.102 Info, Node028, Value::Set - COMMAND_CLASS_COLOR - Color - 0 - 1 - #ff00000000
2020-09-01 11:35:17.103 Info, Node028, Color::SetValue - Setting Color value
2020-09-01 11:35:17.103 Detail, Node028, Queuing (Send) ColorCmd_Set (Node=28): 0x01, 0x14, 0x00, 0x13, 0x1c, 0x0d, 0x33, 0x05, 0x05, 0x02, 0xff, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x25, 0xf8, 0xfc
2020-09-01 11:35:17.103 Detail, Node028, Queuing (Send) ColorCmd_Get (Node=28): 0x01, 0x0a, 0x00, 0x13, 0x1c, 0x03, 0x33, 0x03, 0x02, 0x25, 0xf9, 0x17
2020-09-01 11:35:17.104 Detail, Node028, Queuing (Send) ColorCmd_Get (Node=28): 0x01, 0x0a, 0x00, 0x13, 0x1c, 0x03, 0x33, 0x03, 0x03, 0x25, 0xfa, 0x15
2020-09-01 11:35:17.104 Detail, Node028, Queuing (Send) ColorCmd_Get (Node=28): 0x01, 0x0a, 0x00, 0x13, 0x1c, 0x03, 0x33, 0x03, 0x04, 0x25, 0xfb, 0x13

which is followed with a series of Gets, one of which is:

2020-09-01 11:35:17.269 Info, Node028, Response RTT 41 Average Response RTT 40
2020-09-01 11:35:17.269 Info, Node028, Received a updated Color from Device: #000000
2020-09-01 11:35:17.269 Detail, Node028, Refreshed Value: old value=#000000, new value=#000000, type=string
2020-09-01 11:35:17.269 Detail, Node028, Changes to this value are not verified
2020-09-01 11:35:17.269 Detail, Node028, Refreshed Value: old value=0, new value=0, type=list
2020-09-01 11:35:17.269 Detail, Node028, Changes to this value are not verified
2020-09-01 11:35:17.269 Detail, Node028,   Expected reply and command class was received
2020-09-01 11:35:17.269 Detail, Node028,   Message transaction complete

From the first link in my original post, there is a sequence that works (that poster was using the OpenZwave Control Panel to test):

2018-05-30 21:59:16.681 Info, Node041, Value::Set - COMMAND_CLASS_COLOR -  - 1 - 1 - Red
2018-05-30 21:59:16.682 Info, Node041, Color::SetValue - Setting Color Index Value (Fake)
2018-05-30 21:59:16.682 Detail, Node041, Queuing (Send) ColorCmd_Set (Node=41): 0x01, 0x10, 0x00, 0x13, 0x29, 0x09, 0x33, 0x05, 0x03, 0x02, 0xff, 0x03, 0x00, 0x04, 0x00, 0x25, 0xaf, 0x99
2018-05-30 21:59:16.683 Detail, Node041, Queuing (Send) ColorCmd_Get (Node=41): 0x01, 0x0a, 0x00, 0x13, 0x29, 0x03, 0x33, 0x03, 0x02, 0x25, 0xb0, 0x6b
2018-05-30 21:59:16.683 Detail, Node041, Queuing (Send) ColorCmd_Get (Node=41): 0x01, 0x0a, 0x00, 0x13, 0x29, 0x03, 0x33, 0x03, 0x03, 0x25, 0xb1, 0x6b
2018-05-30 21:59:16.683 Detail, Node041, Queuing (Send) ColorCmd_Get (Node=41): 0x01, 0x0a, 0x00, 0x13, 0x29, 0x03, 0x33, 0x03, 0x04, 0x25, 0xb2, 0x6f

<snip>

2018-05-30 21:59:16.824 Info, Node041, Response RTT 37 Average Response RTT 36
2018-05-30 21:59:16.824 Info, Node041, Received a updated Color from Device: #FF0000
2018-05-30 21:59:16.824 Detail, Node041, Refreshed Value: old value=#008000, new value=#FF0000, type=string
2018-05-30 21:59:16.824 Detail, Node041, Changes to this value are not verified
2018-05-30 21:59:16.824 Detail, Node041, Refreshed Value: old value=13, new value=3, type=list
2018-05-30 21:59:16.824 Detail, Node041, Changes to this value are not verified
2018-05-30 21:59:16.824 Detail, Node041,   Expected reply and command class was received
2018-05-30 21:59:16.824 Detail, Node041,   Message transaction complete

I perused the light.py in the zwave component and it’s always (seemingly) sending a variable called ‘rgbw’ which must have information other than just the RGB light color. Maybe need to modify this file as well with a quirk for this device?

What is the value of the light entity’s supported_features attribute?

I think the zwave integration code is pretty broken. The ozw version of the code has been updated quite a bit to properly support RGB. I think your problem is related to this section of code:

It correctly sets the RGB values. It then checks if a white value is supported, which in your case is not true, but the last else is incorrectly appending the white values to the color string anyways.

OpenZWave doesn’t really care what values you set, it just passes them to the device. It’s looking like the device ignores the command if unexpected color values are set. I suspect if you delete the else block it will work properly, at least in your case.

Supported features is reported as 49, I think the following is the decoder ring:

SUPPORT_BRIGHTNESS = 1
SUPPORT_COLOR_TEMP = 2
SUPPORT_EFFECT = 4
SUPPORT_FLASH = 8
SUPPORT_COLOR = 16
SUPPORT_TRANSITION = 32
SUPPORT_WHITE_VALUE = 128

I played with that section including hardcoding rgbw to “#ff0000” and somewhere the additional 4 0s are still being appended before sent to the the device. I wonder if it has to do with “SUPPORT_WHITE_VALUE” being set – there is a comment in the light.py file that “openzwave appends white channels that are present”. I don’t see where these bits are set, it doesn’t look like in discovery.

It’s not set, you just said so yourself. 49 is BRIGHTNESS, COLOR and TRANSITION, which matches your xml cache file.

It looks like there is yet again another bug with this code. If you don’t specify a white value, self._white is set to 0 (line 381). So it’s actually line 390 where the extra values are set, because 0 is not None.

Also, don’t forget to restart HA if you change any of the component files.

Yeah, major brain slippage LOL. I have been restarting HA after making changes, I still think something else is modifying the result. I have the following as the last few lines in the file:

        rgbw = "$ff0000"
        self.values.color.data = rgbw

        super().turn_on(**kwargs)

I explicitly set the variable to what I want it to be and the additional zeroes still get sent. The entity also reports rgb_color of 255,255,255 so something is broken in the way the status is being read back as well.

I must have been pretty tired or distracted last night. I was making changes to light.py in the git repo, not in my custom_component folder. Commenting out the suspect if/else section (Homeseer HSM200 Zwave LED On/Off and Color Control) along with the discovery changes (Homeseer HSM200 Zwave LED On/Off and Color Control) allow the light to be controlled. I’m using the light.turn_on service call with this data:

entity_id: light.upstairs_motion_led
rgb_color: [255,0,0]
brightness: 255

Also working instead of rgb_color:

color_name: Red

The list of colors is in the zwave config xml (or in my original post in this thread).

For some reason the first command issued throws an error, the second works and this pattern continues so I still need to look into that. I also plan to come up with an acceptable pull request to fix this in general, and reference that with a feature request to the new ozw integration to have it fixed there as well.

Thanks @freshcoast for the help! I’m marking one of your posts as the solution and I’ll edit my original post to point to this one as a summary.