Skip to content

Commit

Permalink
Merge branch 'manual' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
TD22057 committed Feb 5, 2019
2 parents 80a8b6b + 276be40 commit 3dc6079
Show file tree
Hide file tree
Showing 19 changed files with 605 additions and 202 deletions.
5 changes: 5 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
switches to be used in automation triggers (thanks @NickWaterton).
([Issue #66][I66]).

- Added support for manual mode state reporting (holding buttons down).
Supported by dimmer, keypadlinc, remote, and switch (thanks
@NickWaterton). ([Issue #104][I104]).

- New command 'get_model' added to the command line tool to retrieve and save
the Insteon device cat, sub_cat, and firmware revision (thanks @krkeegan).
([Issue #55][I55]).
Expand Down Expand Up @@ -218,3 +222,4 @@
[I88]: https://github.com/TD22057/insteon-mqtt/issues/88
[I95]: https://github.com/TD22057/insteon-mqtt/issues/95
[I97]: https://github.com/TD22057/insteon-mqtt/issues/97
[I104]: https://github.com/TD22057/insteon-mqtt/issues/104
38 changes: 37 additions & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,15 @@ mqtt:
state_topic: 'insteon/{{address}}/state'
state_payload: '{{on_str.upper()}}'

# Manual mode (holding down a button) is triggered once when the button
# is held and once when it's released. Available variables for
# templating are address (see above), name (see above), and:
# manual_str = 'up'/'off'/'down'
# manual = 1/0/-1
# manual_openhab = 2/1/0
#manual_state_topic: 'insteon/{{address}}/manual_state'
#manual_state_payload: '{{manual_str.upper()}}'

# Input on/off command. Similar functionality to the cmd_topic
# but only for turning the device on and off. The output of
# passing the payload through the template must match the following:
Expand Down Expand Up @@ -251,6 +260,15 @@ mqtt:
state_payload: >
{ "state" : "{{on_str.upper()}}", "brightness" : {{level_255}} }
# Manual mode (holding down a button) is triggered once when the button
# is held and once when it's released. Available variables for
# templating are address (see above), name (see above), and:
# manual_str = 'up'/'off'/'down'
# manual = 1/0/-1
# manual_openhab = 2/1/0
#manual_state_topic: 'insteon/{{address}}/manual_state'
#manual_state_payload: '{{manual_str.upper()}}'

# Input on/off command. Similar functionality to the cmd_topic
# but only for turning the device on and off. The output of
# passing the payload through the template must match the following:
Expand Down Expand Up @@ -468,7 +486,6 @@ mqtt:
# - no concept of separate heat and cool set points
# - no humidity state
# - no status state

thermostat:
# Output state change topic and payload. Available variables for
# templating in all cases are:
Expand Down Expand Up @@ -559,6 +576,16 @@ mqtt:
state_topic: 'insteon/{{address}}/state/{{button}}'
state_payload: '{{on_str.upper()}}'

# Manual mode (holding down a button) is triggered once when the button
# is held and once when it's released. Available variables for
# templating are address (see above), name (see above), button (see
# above), and:
# manual_str = 'up'/'off'/'down'
# manual = 1/0/-1
# manual_openhab = 2/1/0
#manual_state_topic: 'insteon/{{address}}/manual_state'
#manual_state_payload: '{{manual_str.upper()}}'

#------------------------------------------------------------------------
# Fan Linc
#------------------------------------------------------------------------
Expand Down Expand Up @@ -699,6 +726,15 @@ mqtt:
dimmer_state_payload: >
{ "state" : "{{on_str.upper()}}", "brightness" : {{level_255}} }
# Manual mode (holding down a button) is triggered once when the button
# is held and once when it's released. Available variables for
# templating are address (see above), name (see above), and:
# manual_str = 'up'/'off'/'down'
# manual = 1/0/-1
# manual_openhab = 2/1/0
#manual_state_topic: 'insteon/{{address}}/manual_state'
#manual_state_payload: '{{manual_str.upper()}}'

# Input on/off command. For button 1, this will set the load. For other
# buttons, it just set the button LED. The output of passing the payload
# through the template must match the following:
Expand Down
158 changes: 103 additions & 55 deletions docs/mqtt.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,15 @@ which can be used in the templates:
- 'fast' is 1 if the mode is fast, 0 otherwise
- 'instant' is 1 if the mode is instant, 0 otherwise

Manual state output is invoked when a button on the device is held down.
Manual mode flags are UP or DOWN (when the on or off button is pressed and
held), and STOP (when the button is released. Manual template variables are
name, address, and:

- 'manual_str' = 'up'/'off'/'down'
- 'manual' = 1/0/-1
- 'manual_openhab' = 2/1/0

Input state change messages have the following variables defined which
can be used in the templates:

Expand Down Expand Up @@ -446,17 +455,20 @@ using upper case ON an OFF payloads.

```
switch:
# Output state change:
state_topic: 'insteon/{{address}}/state'
state_payload: '{{on_str}}'
# Output state change:
state_topic: 'insteon/{{address}}/state'
state_payload: '{{on_str}}'
# Direct change only changes the load:
on_off_topic: 'insteon/{{address}}/set'
on_off_payload: '{ "cmd" : "{{value.lower()}}" }'
manual_state_topic: 'insteon/{{address}}/manual_state'
manual_state_payload: '{{manual_str.upper()}}'
# Scene change simulates clicking the switch:
scene_topic: 'insteon/{{address}}/scene'
scene_payload: '{ "cmd" : "{{value.lower()}}" }'
# Direct change only changes the load:
on_off_topic: 'insteon/{{address}}/set'
on_off_payload: '{ "cmd" : "{{value.lower()}}" }'
# Scene change simulates clicking the switch:
scene_topic: 'insteon/{{address}}/scene'
scene_payload: '{ "cmd" : "{{value.lower()}}" }'
```

When the switch changes state a message like `ON` or `OFF` is
Expand Down Expand Up @@ -484,6 +496,15 @@ which can be used in the templates:
- 'fast' is 1 if the mode is fast, 0 otherwise
- 'instant' is 1 if the mode is instant, 0 otherwise

Manual state output is invoked when a button on the device is held down.
Manual mode flags are UP or DOWN (when the on or off button is pressed and
held), and STOP (when the button is released. Manual template variables are
name, address, and:

- 'manual_str' = 'up'/'off'/'down'
- 'manual' = 1/0/-1
- 'manual_openhab' = 2/1/0

Input state change messages have the following variables defined which
can be used in the templates:

Expand All @@ -510,24 +531,27 @@ using a JSON format that contains the level using the tag
"brightness".

```
switch:
# Output state change:
state_topic: 'insteon/{{address}}/state'
state_payload: '{ "state" : "{{on_str}}", "brightness" : {{level_255}} }'
dimmer:
# Output state change:
state_topic: 'insteon/{{address}}/state'
state_payload: '{ "state" : "{{on_str}}", "brightness" : {{level_255}} }'
# Input state change for the load:
on_off_topic: 'insteon/{{address}}/set'
on_off_payload: '{ "cmd" : "{{json.state}}" }'
manual_state_topic: 'insteon/{{address}}/manual_state'
manual_state_payload: '{{manual_str.upper()}}'
# Scene change simulates clicking the switch:
scene_topic: 'insteon/{{address}}/scene'
scene_payload: '{ "cmd" : "{{value.lower()}}" }'
# Input state change for the load:
on_off_topic: 'insteon/{{address}}/set'
on_off_payload: '{ "cmd" : "{{json.state}}" }'
# Scene change simulates clicking the switch:
scene_topic: 'insteon/{{address}}/scene'
scene_payload: '{ "cmd" : "{{value.lower()}}" }'
# Dimming control:
level_topic: 'insteon/{{address}}/level'
level_payload: >
{ "cmd" : "{{json.state}}",
"level" : {{json.brightness}} }
# Dimming control:
level_topic: 'insteon/{{address}}/level'
level_payload: >
{ "cmd" : "{{json.state}}",
"level" : {{json.brightness}} }
```

Expand Down Expand Up @@ -585,22 +609,22 @@ matching the Home Assistant MQTT fan configuration.

```
fan_linc:
# Output state change:
fan_state_topic: 'insteon/{{address}}/fan/state'
fan_state_payload: '{{on_str}}'
# Output state change:
fan_state_topic: 'insteon/{{address}}/fan/state'
fan_state_payload: '{{on_str}}'
# Input on/off change (payload should be 'ON' or 'OFF')
fan_on_off_topic: 'insteon/{{address}}/fan/set'
fan_on_off_payload: '{ "cmd" : "{{value.lower}}" }'
# Input on/off change (payload should be 'ON' or 'OFF')
fan_on_off_topic: 'insteon/{{address}}/fan/set'
fan_on_off_payload: '{ "cmd" : "{{value.lower}}" }'
# Output speed state change.
fan_speed_topic: 'insteon/{{address}}/fan/speed/state'
fan_speed_payload: '{{level_str}}'
# Output speed state change.
fan_speed_topic: 'insteon/{{address}}/fan/speed/state'
fan_speed_payload: '{{level_str}}'
# Input fan speed change (payload should be 'off', 'low', 'medium',
# or 'high'.
fan_speed_set_topic: 'insteon/{{address}}/fan/speed/set'
fan_speed_set_payload: '{ "cmd" : "{{value.lower}}" }'
# Input fan speed change (payload should be 'off', 'low', 'medium',
# or 'high'.
fan_speed_set_topic: 'insteon/{{address}}/fan/speed/set'
fan_speed_set_payload: '{ "cmd" : "{{value.lower}}" }'
```


Expand Down Expand Up @@ -635,32 +659,44 @@ The button change defines the following variables for templates:
- 'fast' is 1 if the mode is fast, 0 otherwise
- 'instant' is 1 if the mode is instant, 0 otherwise

Manual state output is invoked when a button on the device is held down.
Manual mode flags are UP or DOWN (when the on or off button is pressed and
held), and STOP (when the button is released. Manual template variables are
name, address, and:

- 'manual_str' = 'up'/'off'/'down'
- 'manual' = 1/0/-1
- 'manual_openhab' = 2/1/0

A sample remote control topic and payload configuration is:

```
keypad_linc:
# Output on/off state change:
btn_state_topic: 'insteon/{{address}}/state/{{button}}'
btn_state_payload: '{{on_str.upper()}}'
# Output on/off state change:
btn_state_topic: 'insteon/{{address}}/state/{{button}}'
btn_state_payload: '{{on_str.upper()}}'
# Output dimmer state changes.
dimmer_state_topic: 'insteon/{{address}}/state/1'
state_payload: '{ "state" : "{{on_str}}", "brightness" : {{level_255}} }'
# Output dimmer state changes.
dimmer_state_topic: 'insteon/{{address}}/state/1'
state_payload: '{ "state" : "{{on_str}}", "brightness" : {{level_255}} }'
manual_state_topic: 'insteon/{{address}}/manual_state/{{button}}'
manual_state_payload: '{{manual_str.upper()}}'
# Input on/off state change. For any button besides 1, this just
# updates the LED state.
btn_on_off_topic: 'insteon/{{address}}/set/{{button}}'
btn_on_off_payload: '{ "cmd" : "{{json.state}}" }'
# Input on/off state change. For any button besides 1, this just
# updates the LED state.
btn_on_off_topic: 'insteon/{{address}}/set/{{button}}'
btn_on_off_payload: '{ "cmd" : "{{json.state}}" }'
# Input dimmer control
level_topic: 'insteon/{{address}}/level/1'
level_payload: >
{ "cmd" : "{{json.state}}",
"level" : {{json.brightness}} }
# Input dimmer control
level_topic: 'insteon/{{address}}/level/1'
level_payload: >
{ "cmd" : "{{json.state}}",
"level" : {{json.brightness}} }
# Scene input - simulates clicking the button.
btn_scene_topic: 'insteon/{{address}}/scene/{{button}}'
btn_scene_payload: '{ "cmd" : "{{value.lower()}}" }'
# Scene input - simulates clicking the button.
btn_scene_topic: 'insteon/{{address}}/scene/{{button}}'
btn_scene_payload: '{ "cmd" : "{{value.lower()}}" }'
```

---
Expand Down Expand Up @@ -772,12 +808,24 @@ The button change defines the following variables for templates:
- 'fast' is 1 if the mode is fast, 0 otherwise
- 'instant' is 1 if the mode is instant, 0 otherwise

Manual state output is invoked when a button on the device is held down.
Manual mode flags are UP or DOWN (when the on or off button is pressed and
held), and STOP (when the button is released. Manual template variables are
name, address, and:

- 'manual_str' = 'up'/'off'/'down'
- 'manual' = 1/0/-1
- 'manual_openhab' = 2/1/0

A sample remote control topic and payload configuration is:

```
remote:
state_topic: 'insteon/{{address}}/state/{{button}}'
state_payload: '{{on_str.upper()}}'
manual_state_topic: 'insteon/{{address}}/manual_state/{{button}}'
manual_state_payload: '{{manual_str.upper()}}'
```

---
Expand Down
12 changes: 7 additions & 5 deletions insteon_mqtt/Modem.py
Original file line number Diff line number Diff line change
Expand Up @@ -604,17 +604,19 @@ def handle_received(self, msg):
device.handle_received(msg)

#-----------------------------------------------------------------------
def handle_scene(self, group, cmd):
def handle_scene(self, msg):
"""Callback for scene simulation commanded messages.
This callback is run when we get a reply back from triggering a scene
on the device. If the command was ACK'ed, we know it worked. The
device will then update the states on the devices in the scene.
Args:
group: (int) The group (scene) being ACK'ed.
cmd: (int) The group command (0x11 for on, 0x13 for off).
msg: (InptStandard) Broadcast message from the device. Use
msg.group to find the group and msg.cmd1 for the command.
"""
group = msg.group

responders = self.db.find_group(group)
LOG.debug("Found %s responders in group %s", len(responders), group)
LOG.debug("Group %s -> %s", group, [i.addr.hex for i in responders])
Expand All @@ -626,7 +628,7 @@ def handle_scene(self, group, cmd):
if device:
LOG.info("%s broadcast to %s for group %s", self.label,
device.addr, group)
device.handle_group_cmd(self.addr, group, cmd)
device.handle_group_cmd(self.addr, msg)
else:
LOG.warning("%s broadcast - device %s not found", self.label,
elem.addr)
Expand Down Expand Up @@ -674,7 +676,7 @@ def run_command(self, **kwargs):
"cmd %s with args: %s", self.addr, cmd, str(kwargs))

#-----------------------------------------------------------------------
def handle_group_cmd(self, addr, group, cmd):
def handle_group_cmd(self, addr, msg):
"""Handle a group command addressed to the modem.
This is called when a broadcast message is sent from a device that is
Expand Down
8 changes: 4 additions & 4 deletions insteon_mqtt/device/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,13 +665,13 @@ def handle_broadcast(self, msg):
if device:
LOG.info("%s broadcast to %s for group %s", self.label,
device.addr, group)
device.handle_group_cmd(self.addr, group, msg.cmd1)
device.handle_group_cmd(self.addr, msg)
else:
LOG.warning("%s broadcast - device %s not found", self.label,
elem.addr)

#-----------------------------------------------------------------------
def handle_group_cmd(self, addr, group, cmd):
def handle_group_cmd(self, addr, msg):
"""Respond to a group command for this device.
This is called when this device is a responder to a scene.
Expand All @@ -681,8 +681,8 @@ def handle_group_cmd(self, addr, group, cmd):
Args:
addr: (Address) The device that sent the message. This is the
controller in the scene.
group: (int) The group being triggered.
cmd: (int) The command byte being sent.
msg: (InptStandard) Broadcast message from the device. Use
msg.group to find the group and msg.cmd1 for the command.
"""
# Default implementation - derived classes should specialize this.
LOG.info("Device %s ignoring group cmd - not implemented", self.label)
Expand Down
Loading

0 comments on commit 3dc6079

Please sign in to comment.