Skip to content

Commit

Permalink
First cut at fanlinc support to fix #4
Browse files Browse the repository at this point in the history
  • Loading branch information
TD22057 committed Dec 9, 2017
1 parent bee7ba2 commit dd7fa2e
Show file tree
Hide file tree
Showing 15 changed files with 614 additions and 32 deletions.
97 changes: 86 additions & 11 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#==========================================================================
logging:
# 10=DEBUG, 20=INFO, 30=WARNING, 40=ERROR
level: 20
level: 10

# Print messages to the screen.
#screen: False
Expand All @@ -27,19 +27,19 @@ logging:
insteon:
# Serial device:
# USB PLM modem
port: "/dev/insteon"
port: '/dev/insteon'
#baudrate: 19200

# Network socket:
# Insteon HUB PLM network
#port: "socket://192.168.1.5:9761"
#port: 'socket://192.168.1.5:9761'

# PLM modem Insteon hex address
address: 44.85.11

# Device database file storage location.
#storage: "/var/lib/insteon-mqtt"
storage: "data"
#storage: '/var/lib/insteon-mqtt'
storage: 'data'

# Automatically refresh device states and databases (if needed) at
# startup. This may be slow depending on the number of devices.
Expand All @@ -52,27 +52,31 @@ insteon:
devices:
# On/off switch devices (outlets, wall switches, appliance modules, etc).
switch:
- 37.2d.35: "lamp1"
- 37.2d.35: 'lamp1'

# Dimming devices (outlets, wall switches, lamp modules, etc).
dimmer:
- 3a.29.84: "lamp2"
- 3a.29.84: 'lamp2'
- 48.3d.46
- 48.b0.ad

# Battery powered motion sensors.
motion:
- 21.d6.d9: "front door"
- 21.d6.d9: 'front door'

# Battery powered mini remotes
mini_remote4:

mini_remote8:
- 3f.07.d4: "remote1"
- 3f.07.d4: 'remote1'

# Smoke bridge module
smoke_bridge:
- 44.a3.79: "smoke alarm"
- 44.a3.79: 'smoke alarm'

# FanLinc fan controller (dimmer+fan)
fan_linc:
- 11.22.33

#------------------------------------------------------------------------
# FUTURE: Insteon scene definitions.
Expand Down Expand Up @@ -192,7 +196,7 @@ mqtt:
# value = the input payload
# json = the input payload converted to json. Use json.VAR to extract
# a variable from a json payload.
level_topic: "insteon/{{address}}/level"
level_topic: 'insteon/{{address}}/level'
# NOTE: HASS JSON switch doesn't send brightness in some cases
# when actuated so handle that here in the template code. The
# other HASS MQTT options also have this problem.
Expand Down Expand Up @@ -310,4 +314,75 @@ mqtt:
state_topic: 'insteon/{{address}}/state/{{button}}'
state_payload: '{{on_str.upper()}}'

#------------------------------------------------------------------------
# Fan Linc
#------------------------------------------------------------------------

# A FanLinc is a dimmer switch (Insteon group 1) plus a fan control
# (group 2). The dimmer MQTT messages use the dimmer settings
# above. The settings here are just for the fan input and output.
# The dimmer settings can be used to turn the fan on and off (and
# report on/off state changes).
#
# NOTE: Both the fan state and fan speed state topics will be
# published on ANY fan change. So if you only need one of them, you
# can put both payloads in a single message and set the other inputs
# to blank (which will turn off the output).
#
# In Home Assistant, use the dimmer example above for the light and
# use MQTT fan with a configuration like this for the fan:
# fan:
# - platform: mqtt
# command_topic: 'insteon/aa.bb.cc/fan/set'
# state_topic: 'insteon/aa.bb.cc/fan/state'
# speed_command_topic: 'insteon/aa.bb.cc/fan/speed/set'
# speed_state_topic: 'insteon/aa.bb.cc/fan/state'
fan_linc:
# Output fan state change topic and payload. This message is sent
# whenever the fan state changes for any reason. Available
# variables for templating are:
# address = 'aa.bb.cc'
# name = 'device name'
# on = 0/1
# on_str = 'off', 'on'
# level = 0, 1, 2, 3
# level_str = 'off', 'low', 'medium', 'high'
fan_state_topic: 'insteon/{{address}}/fan/state'
fan_state_payload: '{{on_str.upper()}}'

# Fan 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 payload must match the following:
# { "cmd" : "on"/"off" }
# Available variables for templating are:
# address = 'aa.bb.cc'
# name = 'device name'
# value = the input payload
# json = the input payload converted to json. Use json.VAR to extract
# a variable from a json payload.
fan_on_off_topic: 'insteon/{{address}}/fan/set'
fan_on_off_payload: '{ "cmd" : "{{value.lower()}}" }'

# Output fan speed state change topic and payload. Set to empty
# to turn off. The same templating variables are available as
# fan_state_topic agove.
fan_speed_topic: 'insteon/{{address}}/fan/speed/state'
fan_speed_payload: '{{level_str}}'

# Fan speed change command. Similar functionality to the cmd_topic
# but only for turning the device on and off. The output of
# passing the payload through the payload must match the following:
# { "cmd" : SPEED }
# where
# SPEED = 0, 1, 2, 3 (for off, low, medium, high)
# or = "off", "low", "medium", "high"
# Available variables for templating are:
# address = 'aa.bb.cc'
# name = 'device name'
# value = the input payload
# json = the input payload converted to json. Use json.VAR to extract
# a variable from a json payload.
fan_speed_set_topic: 'insteon/{{address}}/fan/speed/set'
fan_speed_set_payload: '{ "cmd" : "{{value.lower}}" }'

#----------------------------------------------------------------
6 changes: 4 additions & 2 deletions insteon_mqtt/cmd_line/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ def parse_args(args):
sp = sub.add_parser("start", help="Start the Insteon<->MQTT server.")
sp.add_argument("config", metavar="config.yaml", help="Configuration "
"file to use.")
sp.add_argument("-l", "--log", metavar="log_File",
help="Logging file to use. Use 'stdout' for the screen.")
sp.add_argument("-l", "--log", metavar="log_file",
help="Logging file to use.")
sp.add_argument("-ls", "--log-screen", action="store_true",
help="Log to the screen")
sp.add_argument("--level", metavar="log_level", type=int,
help="Logging level to use. 10=debug, 20=info,"
"30=warn, 40=error, 50=critical")
Expand Down
8 changes: 1 addition & 7 deletions insteon_mqtt/cmd_line/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ def start(args, cfg):
# Initialize the logging system either using the command line
# inputs or the config file. If these vars are None, then the
# config file logging data is used.
log_screen, log_file = None, None
if args.log == 'stdout':
log_screen = True
elif args.log:
log_file = args.log

log.initialize(args.level, log_screen, log_file, config=cfg)
log.initialize(args.level, args.log_screen, args.log, config=cfg)

# Create the network event loop and MQTT and serial modem clients.
loop = network.Manager()
Expand Down
7 changes: 4 additions & 3 deletions insteon_mqtt/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
# Configuration file input description to class map.
devices = {
'dimmer' : device.Dimmer,
'motion' : device.Motion,
'switch' : device.Switch,
'smoke_bridge' : device.SmokeBridge,
'fan_linc' : device.FanLinc,
'mini_remote4' : functools.partial(device.Remote, num=4),
'mini_remote8' : functools.partial(device.Remote, num=8),
'motion' : device.Motion,
'smoke_bridge' : device.SmokeBridge,
'switch' : device.Switch,
}


Expand Down
3 changes: 2 additions & 1 deletion insteon_mqtt/device/Base.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ def refresh(self, force=False):
# current value. If it's different, it will send a database
# download command to the device to update the database.
msg = Msg.OutStandard.direct(self.addr, 0x19, 0x00)
msg_handler = handler.DeviceRefresh(self, force, num_retry=3)
msg_handler = handler.DeviceRefresh(self, self.handle_refresh, force,
num_retry=3)
self.protocol.send(msg, msg_handler)

#-----------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions insteon_mqtt/device/Dimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def on(self, level=0xFF, instant=False):
if self._level == level:
LOG.info("Dimmer %s '%s' is already on %s", self.addr, self.name,
level)
self.signal_level_changed.emit(self, level)
self.signal_level_changed.emit(self, self._level)
return

# Send an on or instant on command.
Expand Down Expand Up @@ -161,7 +161,7 @@ def off(self, instant=False):
LOG.info("Dimmer %s cmd: off", self.addr)
if self._level == 0:
LOG.info("Dimmer %s '%s' is already off", self.addr, self.name)
self.signal_level_changed.emit(self, 0)
self.signal_level_changed.emit(self, self._level)
return

# Send an off or instant off command.
Expand Down Expand Up @@ -323,7 +323,7 @@ def handle_ack(self, msg):
LOG.debug("Dimmer %s ACK: %s", self.addr, msg)
self._set_level(msg.cmd2)

elif msg.flags.Dimmer == Msg.Flags.Type.DIRECT_NAK:
elif msg.flags.type == Msg.Flags.Type.DIRECT_NAK:
LOG.error("Dimmer %s NAK error: %s", self.addr, msg)

#-----------------------------------------------------------------------
Expand Down
Loading

0 comments on commit dd7fa2e

Please sign in to comment.