TD22057 / insteon-mqtt

Python Insteon PLM <-> MQTT bridge
GNU General Public License v3.0
99 stars 43 forks source link

Add simulate button press for all actuators #9

Closed TD22057 closed 6 years ago

TD22057 commented 6 years ago

There is a way to simulate pressing a button on a remote, dimmer, etc module using an extended command. This has the benefit that it activates the scene attached to that button. Uses cmd1 = 0x30. For example, this command sends 0x30 to to device 48.3d.46 to trigger the group broadcast 0x01 to send command 0x11 (turn on). This triggers the dimmer to send a broadcast to activate the scene as if it was pressed. Could be very useful for triggering scenes. This should probably be a new mqtt topic as well for each device which would be like a switch. The only problem with that is it's hard to know if it's "on" or "off" since that doesn't make a lot of sense (is it the whole scene that has to be on or just the one device?).

sim = bytes( [
    0x02, 0x62,
    0x48, 0x3d, 0x46,
    0x1f,
    0x30, 0x00,
    0x01, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe ] )

# 02 62 48 3d 46 1f 30 00 01 00 00 11 00 00 00 00 00 00 00 00 00 be 06
# 02 50 48 3d 46 44 85 11 2f 30 00
# 02 50 48 3d 46 00 00 01 cf 11 00
# 02 50 48 3d 46 44 85 11 40 11 01
# 02 50 48 3d 46 44 85 11 4a 11 01
# 02 50 48 3d 46 11 03 01 cb 06 00
bfranske commented 6 years ago

Yes, this definitely starts to tie into scenes and a way to trigger scenes by button press. I think this is actually how Mr. House triggers Insteon scenes, by setting up a 'virtual button' on the PLM and then simulating pressing it. Insteon must have some way of deciding whether a scene is off or on already as buttons on my keypadlinc have status LEDs which change from off to on depending on the scene state. I can perhaps do some experimentation and determine when the status LED changes state.

bfranske commented 6 years ago

So after a bit of experimentation I think I can explain how state tracking is handled by Insteon devices themselves, namely the Keypadlinc. State is tracked for the scene entirely separately from the individual devices which make up the scene.

In other words, starting with all devices and the scene in the off state if you turn on all of the devices which make up the scene individually the status LED for the scene is still off. Similarly, if you start with all the devices and the scene turned on and turn off the individual devices the status LED will still show the scene being on.

This does create a bit of an interesting situation. If you start with the scene and devices turned on and then individually turn off each device which is a member of the scene the keypadlinc still thinks the scene is on so if you go up to it and press the button tied to the scene (theoretically to turn everything back on) nothing will happen because what you've really done is send the OFF command to the devices in the scene, it just so happened they were all already in the off state individually. You then need to press the scene toggle button a second time to get the devices to turn on via the scene.

The only time it doesn't work like this is when there is a dedicated off/on button for the scene instead of a toggle button (such as for group 1 on the 6 button keypadlinc). In that case even though the status LED will be showing the wrong state (showing on for the scene even though all devices were switched off individually) you can still press the on button and it will re-send the scene on command and immediately turn the devices back on without needing to 'catch-up' to the correct state first like a toggle button.

TD22057 commented 6 years ago

Some more notes on this: Group 1 works for any device as shown in the initial post. Sending that type of command simulates a button 1 press for dimmers, on/off modules, and keypad lincs. It does not work for the other groups/buttons on a keypadlinc. The command fails silently if the group number is changed to 3 for example.

If I update the modem<->keypadlinc database to have a bi-directional link for group 3, then the command does work. So having bidirectional links for all groups defined on the object seems to be required. One weird side affect of that is that group 3 on the modem is a virtual scene that can be triggered using the modem scene command (0x61). But in this case, since only the keypadlinc is member, it only toggles the keypadlinc state, not anything else. I probably need to make a more rigorous check of exactly what's required in the db to make this work for group 3 and what side affects that might have if multiple keypadlincs are attached. Will triggering group 3 trigger all of them, or just the addressed device?

TD22057 commented 6 years ago

Update: As part of fixing some keypadlink linking issues, I was able to test this more carefully. There needs to be a bi-directional link on group 1 (device -> modem to report updates, and modem -> device to send commands) - this is common for all devices. To receive broadcast commands to see when a button is checked, there needs to be a group N device -> modem link. That same link (group N device controller -> modem responder) must be present to send a simulated scene command to group N on the device. The reverse (modem -> device) is not necessary.

TD22057 commented 6 years ago

Status:

  1. sending cmd=0x30 with payload 0x11 to any group 0x01 item triggers the device to turn on and it sends out the broadcast to trigger the scene. So turning on a group 1 button scene works.
  2. sending the same cmd with payload 0x13 (off) will send out the broadcast message to turn off the scene but will not turn off the device itself (no idea why). So turning off a group 1 button scene kinda works.
  3. sending either command to a non-group 1 item (like a button on a keypadlinc) doesn't work at all. The message is ACK'ed but nothing happens. Not sure what I was doing 2 days ago that I thought this was working but I can't get it to work at all now.
TD22057 commented 6 years ago

Update:

  1. sending off commands turns the device on. It still broadcasts an off command, but the device itself always turns on. Sending an immediate off fails. If I wait until the final broadcast clean up is received, then a regular off can be sent. So "off" for a scene has to be simulated with a little delay.
  2. non 1 groups do work - see issue #21 - a bug in the db code caused this to look like a failure.
TD22057 commented 6 years ago

Update:

  1. I added a special callback for off commands. So sending a scene off sends the scene off broadcast command (which updates all the other devices but not the "host"). When the broadcast clean up is sent, then a manual off command is sent to the host device to get it's state in line with everything else. Sending the off before the cleanup has no affect, so this work around is needed.
  2. The fix for issue #21 fixes the non-group 1 problem. It still requires that the modem be a controller for the device on that group though.

So because of 3 above, it looks like I'll need to reserve the virtual PLM modem scene numbers from 2-10 to handle those group number for sending scene commands. I did verify that having two keypadlincs as responders to the modem group 3 only trips the correct one when sending the scene command.

I still need to do some testing, add this code to the other actuators, and build some MQTT templates for the scene commands but it looks like everything is working fine.

TD22057 commented 6 years ago

I've added on/off scene topics and payloads for Switch, Dimmer, and KeypadLinc. These are the same as the on/off inputs but instead of just controlling the device, they simulate clicking the button. They only support on and off commands. I've updated config.yaml and the docs w/ the new examples.

larizzo commented 6 years ago

How does it work in Home-Assistant to trigger a scene? I added this but the scene isn't being triggered:

- platform: mqtt
  name: "Home"
  state_topic: 'insteon/3d.8f.f8/state/3'
  command_topic: 'insteon/3d.8f.f8/scene/3'
TD22057 commented 6 years ago

Be sure to run the pair command first. New db entries are required. And grab the latest dev branch, I submitted and update this morning.