Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add I/O Linc Garage Door Control and Status Kit #12

Closed
larizzo opened this issue Dec 14, 2017 · 22 comments
Closed

Add I/O Linc Garage Door Control and Status Kit #12

larizzo opened this issue Dec 14, 2017 · 22 comments

Comments

@larizzo
Copy link

larizzo commented Dec 14, 2017

I'd love to get support for the Insteon Garage Door Sensor. I tried just adding it as a switch and battery senor but that didn't work. If you need any info I can provide any debugging logs or information. I have a working solution right now so not priority, just be nice to be able to completely switch to this for my Insteon.

http://www.insteon.com/garage-door-control-kit/

@larizzo larizzo changed the title I/O Linc Garage Door Control and Status Kit Add I/O Linc Garage Door Control and Status Kit Dec 14, 2017
@TD22057
Copy link
Owner

TD22057 commented Dec 14, 2017

Should be very easy if you can post the logs. Link it to the modem and trigger the sensor portion to see what it's sending out when the sensor trips. Then link it as a responder to something and trip that button to see what gets sent to it. It has to be a simple re-use of the code that's already there - basically I just need to see the group numbers and on/off codes that are being used for each piece (input and output). The momentary option might be a little different though. I looked around but I can't find a developers guide anywhere. Misterhouse has some code for it but it's in perl and it's really hard for me to figure out.

@TD22057
Copy link
Owner

TD22057 commented Dec 15, 2017

Try running the following script. I use it for debugging commands. From looking at the openhab docs, it looks like the relay will turn on and off using a standard switch command (0x11=on, 0x13=off) and the sensor will report changes via the same system (group 1 broadcast). So edit the script to point at the PLM modem and set the IOLinc address, then save the script below to a file "inst_test.py", then do this (activate the env w/ the insteon-mqtt dependencies first). Send the byte commands, wait a few seconds, and call read() which will print the results. Then go trip the sensor on the iolinc module and call read() again to see what the device is sending as a message.

python -i inst_test.py
>>> port.write(on)
>>> read()
...
>>> port.write(off)
>>> read()
...
# go trip the sensor on the IO linc
>>> read()

# try reading the sensor state:
>>> port.write(ping1)
>>> read()

# different ping cmd
>>> port.write(ping2)
>>> read()

inst_test.py:

import serial
import time
import binascii
from io import StringIO

port = serial.Serial( port="/dev/insteon",
                      baudrate=19200,
                      parity=serial.PARITY_NONE,
                      stopbits=serial.STOPBITS_ONE,
                      bytesize=serial.EIGHTBITS,
                      timeout=0 )
while not port.is_open:
    print( "port not open?" )
    time.sleep( 1 )

print( "port variable defined and ready" )

def tohex( data ):
    s = binascii.hexlify(data).decode()
    o = StringIO()
    for i in range( 0, len( s ), 2 ):
        o.write( s[i] )
        o.write( s[i+1] )
        o.write( ' ' )
    return o.getvalue()

# use port.write( bytes ) to send a message

def read():
    if port.inWaiting():
        data = port.read(1024)
        print("Read %d: %s" % ( len(data), tohex(data)))
        return data
    print("No bytes to read")
    return None

# Put the device add rhere:
a1, a2, a3 = 0x3a, 0x29, 0x84

on = bytes( [
    0x02, 0x62,  # header
    a1, a2, a3,
    0x00, # flags
    0x11, 0xFF,  # turn on level 255
    ] )
off = bytes( [
    0x02, 0x62,  # header
    a1, a2, a3,
    0x00, # flags
    0x13, 0x00,  # turn off
    ] )

ping1 = bytes( [
    0x02, 0x62,
    a1, a2, a3,
    0x00,
    0x19, 0x00,
    ] )

ping2 = bytes( [
    0x02, 0x62,
    a1, a2, a3,
    0x00,
    0x19, 0x01,
    ] )

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

Ok I was able to test some stuff I'll try and explain here and the outputs.

DOOR OPENED When I did the following.

>>> port.write(on)
8
>>> read()
No bytes to read

NOTHING HAPPENED ### I think this is normal as I believe it's just ON that does anything since it's a relay.

>>> port.write(off)
8
>>> read()
No bytes to read

DOOR CLOSED

>>> port.write(on)
8
>>> read()
No bytes to read
>>> port.write(ping1)
8
>>> read()
No bytes to read
>>> port.write(ping2)
8
>>> read()
No bytes to read

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

DOOR OPEN SENSOR

17-12-15 19:15:56 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 13 00
2017-12-15 19:15:56 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:15:56 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 13 00
2017-12-15 19:15:57 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_CLEANUP grp: 01 cmd: 13 01
2017-12-15 19:15:57 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00
2017-12-15 19:15:57 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:15:57 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00


DOOR CLOSED SENSOR

2017-12-15 19:16:02 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 11 00
2017-12-15 19:16:02 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:16:02 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 11 00
2017-12-15 19:16:03 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_CLEANUP grp: 01 cmd: 11 01
2017-12-15 19:16:03 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00
2017-12-15 19:16:03 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:16:03 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00

DOOR BUTTON PRESS TO OPEN

2017-12-15 19:17:58 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 13 00
2017-12-15 19:17:58 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:17:58 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 13 00
2017-12-15 19:17:59 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_CLEANUP grp: 01 cmd: 13 01
2017-12-15 19:17:59 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00
2017-12-15 19:17:59 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:17:59 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00

DOOR BUTTON PRESS TO CLOSE


2017-12-15 19:18:54 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 11 00
2017-12-15 19:18:54 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:18:54 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 11 00
2017-12-15 19:18:56 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_CLEANUP grp: 01 cmd: 11 01
2017-12-15 19:18:56 INFO Protocol: Read 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00
2017-12-15 19:18:56 ERROR Broadcast: Unknown broadcast device 34.89.34
2017-12-15 19:18:56 WARNING Protocol: No read handler found for message type 0x50: Std: 34.89.34 Type.ALL_LINK_BROADCAST grp: 01 cmd: 06 00






@TD22057
Copy link
Owner

TD22057 commented Dec 16, 2017

Thanks - that's exactly what I needed. Should be easy to add tonight or tomorrow morning.

@TD22057
Copy link
Owner

TD22057 commented Dec 16, 2017

Couple of more items: the IOLinc can be momentary or latching - it looks like when it's momentary only the on command is used. If it's in latching mode, then both commands are needed. Also, can you edit both ping commands and retry them? I think they should work but I think I had one byte wrong.

ping1 = bytes( [
    0x02, 0x62,
    a1, a2, a3,
    0x0f,
    0x19, 0x00,
    ] )

ping2 = bytes( [
    0x02, 0x62,
    a1, a2, a3,
    0x0f,
    0x19, 0x01,
    ] )
```

@TD22057
Copy link
Owner

TD22057 commented Dec 16, 2017

When you recorded the door open/close sensor packets, I assume you didn't open/close the door using the iolinc right? Because I see a potential problem in that there are really two devices here - a switch (momentary or latching) and a sensor. But stupidly, they both report on group 1 so when a broadcast message from group 1 is sent, there is really no way to know if that's the sensor or the switch. From looking at the openhab code, sending ping1 should report back on the switch state and ping2 should report back the sensor state. But in every other device, those would be broadcast on different groups. So to keep them in sync, it might require seeing the broadcast message and then sending two poll request messages to update the state of each device. I'll have to give this some more thought.

For the momentary garage door case, this doesn't matter that much probably - but for a latching relay case where the relay is really a switch, I'm not sure. Also - for a garage door, check the manual: https://cache-m2.smarthome.com/manuals/2450.pdf
Momentary C mode uses both commands and hooks the sensor in to correctly open and close the door. In that case, both on and off are used. It sounds like your linc is in Momentary A mode where only the on command is used.

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

I'm using it as momentary switch which is why only ON does anything I assume. I know in Openhab it's configured as two different devices and when I trigger the garage door to open the switch doesn't really know what state it's in it just sends ON then returns to OFF and you can send ON again. What we could do is configure it as a toggle switch?

When I did my test I opened the door by hand and didn't push the button to insure we only got the sensor in the logs. I can do more test if you need.

I don't think this is the result you expected?

>>> port.write(ping1)
8
>>> read()
No bytes to read
>>> port.write(ping2)
8
>>> read()
No bytes to read

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

Actually just looked and it's setup that ON or OFF closes relay.
screenshot 2017-12-16 at 9 02 33 am

@TD22057
Copy link
Owner

TD22057 commented Dec 16, 2017

Yes - I'm totally confused. Based on the openhab code here and here, 0x19 should be the standard status request command but it doesn't seem to be working.

And based on the quick start guide here, I was going to tell you to try momentary 3 mode. I think momentary 3 should allow you to just put the iolinc address in the insteon-mqtt on/off switch block and it should work to toggle the door and show the state. But your chart makes it look like you're already in that mode so I'm extra confused.

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

One thing I just realized I'm actually using the status of my keypadlic to tell me if the garage door is open or not and not the switch for the garagelink in openhab. I don't recall why but maybe it wasn't showing the status properly in openhab so I just used to button status since it gets updated.

@TD22057
Copy link
Owner

TD22057 commented Dec 16, 2017

So maybe the openhab status settings are wrong. Try checking that it's in momentary 3 config and "on" equals "door up" (if that's configurable) and then put it in insteon-mqtt as a switch. I think then the switch status will show if the door is up/down and toggling will toggle the door. If that works, kill insteon-mqtt and toggle the door (so the setting when insteon-mqtt starts is wrong), then try sending a refresh command (cmd line tool) and see if it updates. I might have to just spend the $30 to get one so I can test it here.

@larizzo
Copy link
Author

larizzo commented Dec 16, 2017

Your right it does work as a switch and shows the status correctly even when I open it from another method. Only thing that's weird is the OFF doesn't close the door I have to turn off the switch and ON again and then it will close. But I was having this issue before so maybe it's something on my side of the configuration.

EDIT: fixed "doesn't close"

@TD22057
Copy link
Owner

TD22057 commented Dec 17, 2017

FYI I found one of these on ebay w/ the sensors for $30 so I bought it. Will be a week before I get it but I can do real testing then and figure out what the best set of commands to support is.

@larizzo
Copy link
Author

larizzo commented Dec 17, 2017

Great! I hope you have a use for it at least? I do find it really handy to open my garage with my phone and I also use it to alert me that I forgot to close the garage. I can't figure out how to change the "modes" so once you do that if you can explain it to me... I just want to make sure I'm really on Mode B cause it seems more like I'm on Mode A. I see the mode from the Insteon Hub but maybe the PLM is different some how.

@TD22057
Copy link
Owner

TD22057 commented Dec 17, 2017

I was originally going to use an arduino module I built awhile ago to control the garage door but the iolinc is simpler so I do have a use for it. Check the owners manual here page 10 - it has instructions. I think we/you want Momentary C mode. In that mode, ON always opens the door, OFF always closes the door, and the sensor will show ON as the door open. Once it's in momentary C mode, the regular on/off switch should work perfectly (I think).

@larizzo
Copy link
Author

larizzo commented Dec 17, 2017

I found something that seems to explain the behavior from the ISY forums.

The confusion about Relay On/Off versus door opener movement is due to the fact that the Smarthome documentation assumes a Scene is used to control the I/O Linc Relay. Since Smarthome devices cannot send Direct On/Off commands (except PLM with HA), only Scene On/Off commands, all the Smarthome doc describes device operation relative to Scene usage.

Sending a Direct On command to the Relay ALWAYS turns the Relay On. Being a garage door implementation Momentary mode (any of the three) automatically turns the Relay Off to simulate manual button operation. The Direct Off command serves no functional purpose as the Relay is always automatically turned Off with Momentary mode.

Basically the way I read it is if you speak directly with the garage IOlinc the off will never work in Momentary Press mode as it auto sends the off. It's a relay so you are asking it to stop closng the relay. The only way to get ON/OFF is to use a scene/group.

I created a scene with my insteon hub and added my keypad with group # that was create and the ON/OFF works then way I expected.

So for now I'll just live with the ON only working till you support the scene/groups.

@TD22057
Copy link
Owner

TD22057 commented Dec 17, 2017

Weird - that's the opposite of what the docs says for momentary C. Momentary C is specifically for garage doors and trips the relay with a direct ON command only if the door is down and trips the relay with a direct OFF command only if the door is up (at least that's how I read the user's guide - I'll test it out when mine gets here).

@TD22057
Copy link
Owner

TD22057 commented Dec 22, 2017

OK - I got my IOLinc in today and I know what's happening. The device works like this:

  • broadcast messages from the IOLinc->modem show the sensor state regardless of the relay state or mode. 0x11 = sensor open (magnets not touching). 0x13 = sensor closed (magnets touching).
  • as far as I can see, there is no way to get the state of the relay from the device
  • direct messages to the IOLinc trip the relay. 0x11 (on) sets the relay on (either latching or momentary) regardless of mode. 0x13 (off) sets the relay off in latching mode (ignored in momentary)
  • broadcast messages from other controllers (i.e. scenes) trip the relay correctly depending on the momentary a/b/c settings.

I'll have to think about what this means. The sensor is fairly easy - when a broadcast is received, it will update the sensor state and send out an MQTT message. The commanding is more complicated. I think sending an on or off command with a force=1 flag should send a direct on/off command to always trip the relay that direction. Otherwise on/off should use a broadcast flag so that it behaves correctly. So I need to implement a pair() method that connects one of the virtual modem scene ID numbers to the IOLinc and then the on/off commands will send out a broadcast message using that scene ID so the IOLinc will work correctly.

@TD22057
Copy link
Owner

TD22057 commented Dec 31, 2017

OK - now that #9 is complete, I can get this finished. It will have options for forcing the relay on/off or triggering the "scene" which is the more likely way to use it as it will respect the momentary a/b/c settings.

@TD22057
Copy link
Owner

TD22057 commented Jan 1, 2018

Update:
I've added a new command 'get-flags' to the command line and MQTT which gets the "operating flags" bit set and prints them. I only added support for the IOLinc class but it allows reporting of the latching/momentary A/B/C mode as well as whether the sensor state should be "inverted" or not. I did a big test of each latching mode combined with every way to actuate the device. The goal is to get broadcast messages only when the sensor changes (not the relay) and to have the relay respond correctly depending on the mode.

TL&DR: the direct and simulated scene command are worthless - they always trips the relay so it ignores momentary C and some send a status update with the relay status, not the sensor status. The only "good" way to trip the IOLinc correctly is to have a simulated scene defined on the modem and trip that (or by sending a simulated scene command to a linked controller like keypad button).

Here's the full break down

    Latching mode
      - Click set button by hand.  Toggles relay on or off.  But it also
        emits a status update for the relay, not the sensor.  [BAD]

      - Send on command.  Relay turns on.  No state update. [GOOD]
      - Send off command.  Relay turns on.  No state update. [GOOD]

      - Send scene simulation on command.  Relay turns on.  Status update
        with ON payload sent.  [BAD]
      - Send scene simulation Off command.  Relay turns off.  Status update
        with OFF payload sent.  [BAD]

      - Click controller button (or send modem scene) on.  Relay turns on.
        No state update.  [GOOD]
      - Click controller button (or send modem scene) off.  Relay turns
        off. No state update.  [GOOD]

    Momemtary A:
      ON turns relay on, then off after delay.  OFF is ignored.  (this can be
      reversed - depends on the state of the relay when paired - i.e D1 in
      the link db responder line)

      - Click set button by hand.  Relay turns on, then off.  Emits a state
        ON update but no OFF update.  [BAD]

      - Send on.  Relay turns on, then off after delay.  No state
        update. [GOOD]
      - Send off.  Relay does nothing.  No state update. [GOOD]

      - Send scene simulation on command.  Relay turns on, then off after
        delay.  Status update with ON payload sent. [BAD]
      - Send scene simulation Off command.  Nothing happens.

      - Click controller button (or send modem scene) on.  Relay turns on,
        then off after delay.  No state update.  [GOOD]
      - Click controller button (or send modem scene) off.  Nothing happens.

    Momentary B:
      ON or OFF turns relay on, then off after delay.

      - Click set button by hand.  Relay turns on, then off after delay.
        Emits a state ON update but no OFF update.  [BAD]

      - Send on.  Relay turns on, then off after delay.  No state
        update. [GOOD]
      - Send off.  Relay does nothing.  No state update. [GOOD]

      - Send scene simulation on command.  Relay turns on, then off after
        delay.  Status update with ON payload sent. [BAD]
      - Send scene simulation Off command.  Relay turns on, then off after
        delay.  Status update with OFF payload sent.  [BAD]

      - Click controller button (or send modem scene) on.  Relay turns on,
        then off after delay.  No state update.  [GOOD]
      - Click controller button (or send modem scene) off.  Relay turns on,
        then off after delay.  No state update.  [GOOD]

    Momentary C:
      ON turns relay on only if sensor is in correct state (state of device
      when linked - i.e. D1 in the link db responder line).

      - Click set button by hand.  Relay turns on, then off after delay.
        Emits a state ON update but no OFF update.  [BAD]

      - Send on.  Relay turns on, then off after delay.  No state
        update.  [GOOD] - But this ignores the sensor value [BAD?]
      - Send off.  Relay does nothing.  No state update. [GOOD]

      - Send scene simulation on command.  Relay turns on, then off after
        delay.  Status update with ON payload sent.  Ignores sensor value
        [BAD]
      - Send scene simulation Off command.  Relay turns on, then off after
        delay.  Status update with ON payload sent.  Ignores sensor value
        [BAD]

      - Click controller button (or send modem scene) on.  Relay turns on,
        then off after delay.  No state update.  [GOOD]  Sensor value is
        handled correctly.
      - Click controller button (or send modem scene) off.  Relay turns on,
        then off after delay.  No state update.  [GOOD]  Sensor value is
        handled correctly.

Not about Momentary C: If you click a keypadlinc button, it will toggle. The IOLinc may not do anything though - i.e. if the sensor is already in that state, it won't fire. But the keypad button has toggled so now it's LED on/off is wrong. Might be some way to "fix" this but it's not obvious whether or not it's a good idea or not. Might be nice to have an option to FORCE a controller of the IO linc to always be in the correct state to show the door open or closed.

TD22057 added a commit that referenced this issue Jan 2, 2018
Added IOLinc support and automatic virtual scene creation for correct relay triggering.
Fixes #12, fixes #24.
@TD22057
Copy link
Owner

TD22057 commented Jan 2, 2018

Fixed. During pair(), the IOLinc class will create a virtual modem scene (modem N -> iolinc 1) link where N is a free number >= 20. The IOLinc class will then know to correctly trigger the relay it will tell the modem to send a simulated group N scene broadcast. So using the on/off command on the IOLinc forces the relay state to on or off. Using the scene command uses the "normal" rules of the IOLinc and respects the latching, momentary a/b/c rules.

I've also added command line tools for getting and setting the relay flags. Run ```scripts/insteon-mqtt config.yaml get_flags aa.bb.cc`` to see the current flags and set_flags allows for changing them. With issue #20 added (multi-group link creation), it's now possible to link the IOLinc status to a button on a keypad in software.

Future addition will be to allow changing of the delay time but I don't think that's overly important at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants