mantorok1 / homebridge-omnilink-platform

Homebridge Plugin for HAI/Leviton Omni series Security & Home Automation Systems
Apache License 2.0
12 stars 0 forks source link

OmniLink serial protocol support #19

Closed Riveloper closed 1 year ago

Riveloper commented 1 year ago

Is your feature request related to a problem? Please describe:

I've discovered that mine as well as a lot of these systems have older firmware that doesn't support the OmniLink II protocol.

Describe the solution you'd like:

I've found repositories where others have written Java or .net applications that work with the original non tcp protocol through the IP address of the Omni unit. Without a physical firmware chip upgrade that has become almost impossible to find, this would be a huge feature you may consider integrating. It took me months to figure this out and thought I would share since I have found none of the platforms integrating with Omni have done so yet.

Describe alternatives you've considered:

Additional context:

mantorok1 commented 1 year ago

Hi @Riveloper, I'm not familiar with the OmniLink serial protocol but I did manage to find a document (PDF) that describes how to use it. I'll take a look and see if I'm able to integrate it into the plugin. Do you know the firmware version of your Omni controller? Also, I'm not able to test the serial port functionality on my own Omni controller. Would you be willing to beta test it for me (assuming I decide to proceed with the development)?

Riveloper commented 1 year ago

I'd be happy to test. Search GitHub for OmniLink and you should find a Java repo built for the serial protocol.

Almost the same as tcp but without the header and would require pinging the unit for state of device periodically.

Works on old school UDP, signals where a command is sent and no confirmation return. Used to be how home automation all worked.

Most older large homes use these systems by different manufacturers.

TCP is great, but most people don't understand these homes have 50 or more wired devices that are decades before new smart home tech.

mantorok1 commented 1 year ago

Thanks @Riveloper, in your case how do you connect to the Omni controller via the serial port? The old RS-232 ports are no longer standard on modern computers so wondering if you use some sort of adapter to go from a USB port to the Omni's serial port. Also, what operating system will you be using for Homebridge? One last thing do you know the Omni controller's firmware version? Some responses from the controller could be different from version 3.0 onwards. My plugin currently only supports version 3.0+ as it would be difficult (ie. more work) to support earlier versions.

Riveloper commented 1 year ago

The Ethernet port supports the serial protocol over a network. I can ping the device but since it lacks ability to communicate using TCP, it was used mostly to send commands.

Until the updated firmware chip which if added enabled the OmniLink II protocol which was basically just TCP.

To make things simple they mostly used the same ASCII format on both for communication to accessories.

Riveloper commented 1 year ago

Also Mac OS is what I've been running Homebridge On.

And you are correct about firmware. If it was 3.0 it would have the OmniLink II and wouldn't need the serial communications feature.

I'm on version 2.14.

People can go buy a chip to upgrade, but they are hard to, if not impossible to find.

People who haven't upgraded end up just removing the system and all accessories and sell it. Such a waste.

mantorok1 commented 1 year ago

Oh, I think I misunderstood. I thought you meant an actual serial port (like RS-232 or RS-485). There is an API document for the serial port (version 3.0) and its for the OmniLink protocol but there's no mention of using it over Ethernet with UDP.

I also have the API documents for version 2.16 & 3.0 of the OmniLink II protocol but it still only mentions TCP nothing about UDP.

I found the Matodak/omnilink repo in GitHub which supports both the serial and network (ethernet) protocols but looking in the doc folder I can only find the same API docs that I have although the serial protocol one is an older version (2.12)

Can you provide any further info about using a serial protocol over ethernet and UDP?

mantorok1 commented 1 year ago

I've been having a look at the java code in more detail but I don't know that language very well. From what I can understand the "OmniLink" protocol works for both serial (eg RS-232) as well as ethernet using UDP. The "OmniLink II" protocol only works for ethernet using TCP. It's strange though that none of the API docs I have mention the OmniLink (serial) protocol being available for ethernet/UDP

mantorok1 commented 1 year ago

Hi @Riveloper, could I get you to try something to see if the UDP connectivity works as I expect. Please download and install the Packet Sender tool from https://packetsender.com/download. Its free and there's a Mac version. I have a Mac too BTW. Start the app and enter the IP address and port of your Omni controller. Select the UDP protocol from the dropdown. In the ASCII textbox enter some text like "hello" and click "Send". In the log at the bottom you should see your request and hopefully some sort of response from the Omni

Riveloper commented 1 year ago

I'm out of town till Monday but will try then.

I read your other comments and believe we both are in agreement that there is some, 'mystery', almost to this forgotten original protocol.

The more I learn about it, the more I believe this would be superior to even those who currently use the newer OmniLink II protocol. Mainly because this is how the engineers originally designed and intended the system to be controlled.

I'm linking to a forum where you can read some others experience attempting to use an Arduino over the serial connection, implementing this protocol. Comparing it to TCP, they claim it is far faster.

Unfortunately you have to read nearly the entire back-and-forth, to see the type of issues ran into, and solution. click here

Also in case you don't know, even the Omni systems that now support OmniLink II and TCP, also support the old protocol over UDP as part of the firmware.

mantorok1 commented 1 year ago

No worries.

Yeah UDP will be faster but packets can get lost so some sort of retry logic is needed to handle it.

The OmniLink II protocol has the advantage of being able to send event notifications which the OmniLink one doesn't have as its purely request/response. This means the plugin will have to poll the status of all devices at regular intervals so things like motion sensors won't show the correct realtime status.

Unfortunately OmniLink seems to be missing a number of messages that the OmniLink II has which I use in the plugin so this could end up being a lot of work.

Anyway lets just see if we can get the connectivity sorted out first.

mantorok1 commented 1 year ago

Hi @Riveloper, have you had a chance to try the Packet Sender tool?

I've also written a small nodejs script that you can try (see below). It will send a "Login" command to the Omni controller over UDP and hopefully get back an ACKNOWLEDGE message. You just need to:

  1. Install nodejs on your Mac if don't already have it
  2. Save the below script with the name index.js
  3. Set the port, IP address and security code for your Omni controller on the first 3 lines and save
  4. Run it using: node index.js

When I try this I don't get a response:

$ node index.js
Sending command [90,5,32,1,2,3,4,32,157] to server 192.168.1.210:4369
Command sent successfully

Please run and post the output you receive. Make sure you obfuscate the security code before posting the results.

Here's the index.js script:

const omniPort = 4369;
const omniAddress = '192.168.1.210';
const securityCode = '1234';

var udp = require('dgram');

var client = udp.createSocket('udp4');

var command = getLoginCommand(securityCode);

client.on('message', function(msg, info){
    console.log('Received response [%s] from server: %s:%d\n', [...msg].toString(), info.address, info.port);
});

console.log('Sending command [%s] to server %s:%d', [...command].toString(), omniAddress, omniPort);
client.send(command, omniPort, omniAddress, function(error){
    if(error) {
        console.error('Command failed', error);
        client.close();
    } else {
        console.log('Command sent successfully');
    }
});

function getLoginCommand(securityCode) {
    command = Buffer.from([0x5A, 0x05, 0x20]);
    securityDigits = Buffer.from([...securityCode].map(Number));
    message = Buffer.concat([command, securityDigits]);

    crc = Buffer.alloc(2);
    crc.writeUInt16LE(generateCrc(message));

    message = Buffer.concat([message, crc]);

    return message;
};

function generateCrc(message) {
    const updateCrc = (crc, data) => {
      const poly = 0xA001;

      crc = crc ^ data;
      for (let i = 1; i <= 8; i++) {
        const flag = (crc & 1) !== 0;
        crc = crc >> 1;
        if (flag) {
          crc = crc ^ poly;
        }
      }

      return crc;
    };

    let crc = 0;
    for (let i = 1; i < message.length; i++) {
      crc = updateCrc(crc, message[i]);
    }

    return crc;
};
mantorok1 commented 1 year ago

Hi @Riveloper, I've confirmed that UDP is supported by my Omni controller as I can use "PC Access" to connect to it using UDP. However I'm not able to get it to work using NodeJS with the above code. This is a major blocker to being able to support UDP on my plugin.

It looks like it is still possible to obtain the EPROM chips required to upgrade the firmware on older Omni models. I think this may be your best option for the moment. my:ro control appears to have them: https://www.myrocontrol.com/shop/product/leviton-omni-pro-ii-security-automation-upgrade-chip-20a04-2upg/

mantorok1 commented 1 year ago

Stale