homemate-bridge icon indicating copy to clipboard operation
homemate-bridge copied to clipboard

Add support for energy sensor on S31

Open boojew opened this issue 6 years ago • 16 comments

Requires https://github.com/insertjokehere/python-hassdevice/pull/1

boojew avatar Feb 03 '19 22:02 boojew

Hmm. Found a bug in which the switch doesn’t always respond to MQTT commands. I’ll fix this during the week

boojew avatar Feb 04 '19 05:02 boojew

Ok so I checked closer and my PR didnt cause instability with Homemate.. My test box did ;) It's all good now. One thing to note is that I rarely see energy update events on the "wire"; however, when the homemate app is open, it seems to send one every few seconds .- so my guess is that there is a cmd to send to tell it to send them; however, I can't get the stream_decode.py to work. I have the 16 character key, but I always get the complaint about the keysize.. any feedback?

bens-MBP:research babecassis$ python3 stream_decode.py mobile 
Switch sends
Magic: b'hd'
Length: 186 (True)
Type: b'pk'
CRC32: (2406255143, 2406255143, True)
id: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Traceback (most recent call last):
  File "stream_decode.py", line 70, in <module>
    print(crypto(v))
  File "stream_decode.py", line 34, in crypto
    algorithms.AES(keys[payload[4]]),
  File "/usr/local/lib/python3.7/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py", line 30, in __init__
    self.key = _verify_key_size(self, key)
  File "/usr/local/lib/python3.7/site-packages/cryptography/hazmat/primitives/ciphers/algorithms.py", line 17, in _verify_key_size
    len(key) * 8, algorithm.name
ValueError: Invalid key size (136) for AES.

boojew avatar Feb 06 '19 02:02 boojew

At a guess, you've either got a trailing new line character at the end of the orvibo.key file, or you've written the base64 encoded version rather than the raw bytes.

Try something like: echo -n kh..... > orvibo.key

insertjokehere avatar Feb 07 '19 04:02 insertjokehere

Thanks! I will clean this all up and try again soon!

boojew avatar Feb 10 '19 13:02 boojew

For the key, I get b'khggd54865.....' w/o a new line at the end... I have tried it in that format and without the b''.. No luck. W/o the b'' it is 16 alphanumerics.

Oh and to get the key, I'm doing python3 find_key.py kepler.apk > orvibo.key

boojew avatar Feb 11 '19 02:02 boojew

@insertjokehere - any idea about the key?

boojew avatar Feb 16 '19 23:02 boojew

@boojew I've updated stream_decode.py to accept a keys file in the same format as the main application; give that a go?

insertjokehere avatar Feb 17 '19 01:02 insertjokehere

No love...

root@skywarp:/tmp/homemate-bridge/research# python3 stream_decode.py stream.yaml
Traceback (most recent call last):
  File "stream_decode.py", line 14, in <module>
    int(k): base64.b64decode(v) for k, v in json.load(f)
  File "stream_decode.py", line 14, in <dictcomp>
    int(k): base64.b64decode(v) for k, v in json.load(f)
ValueError: too many values to unpack (expected 2)

Keys.json looks like this: {"112": "a2hnZ2Q1NDg2N<redactedbits>"}

I should also mention, stream.yaml is your example file - not one I generated. In case you have 5 minutes, I'm also including my pcap in case you could decode and put in back here - just so I can continue testing the energy capture. Thanks!

s31.txt

boojew avatar Feb 17 '19 19:02 boojew

I've updated stream_decode.py again (missed .items()) - it should work now. The decoded version of you capture is attached

s31_decoded.txt

insertjokehere avatar Feb 18 '19 21:02 insertjokehere

Looks like it's cmd 128 that tells the switch to respond with the power related stuff. Is there a way to send that command as the heartbeat I guess?

mssmison avatar Feb 18 '19 22:02 mssmison

I was able to get this to work. I have commited some code in https://github.com/boojew/homemate-bridge/blob/master/src/homemate_bridge/cli.py and I will tune it over the next few days.

If anyone wants to try it, check out https://hub.docker.com/r/boojew/homemate-bridge. Be sure to pass the pass the keyfile as a volume or env and pass the host as the env variable MQTT_HOST

boojew avatar Mar 12 '19 02:03 boojew

@boojew hows the tuning going?

mkormendy avatar May 27 '19 23:05 mkormendy

@boojew I'm getting this error when I attempt to use your fork of this plugin:

Traceback (most recent call last):
  File "/usr/local/bin/homemate-bridge", line 11, in <module>
    load_entry_point('homemate-bridge', 'console_scripts', 'homemate-bridge')()
  File "/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py", line 489, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2793, in load_entry_point
    return ep.load()
  File "/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2411, in load
    return self.resolve()
  File "/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2417, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/██████████/homemate-bridge/src/homemate_bridge/cli.py", line 18, in <module>
    from hassdevice.devices import Switch, Sensor
ImportError: cannot import name 'Sensor' from 'hassdevice.devices'

mkormendy avatar May 28 '19 02:05 mkormendy

what units is the energy variable in? Kwh?

mike391 avatar Sep 30 '21 21:09 mike391

I know this is ancient, but I just picked up a bunch of S31 switches and was hoping to get 'em integrated into my home assistant instance. Got my MQTT broker running in home assistant, and am able to connect to it from other devices on the network. Got my "PK" encryption key from the kepler.apk. Set up a simple docker-compose in my portainer instance:

version: "3"
services:
  ###########################
  # Homemate to MQTT bridge for S31 Orvibo Switches
  # Fork of https://github.com/insertjokehere/homemate-bridge
  ###########################
  homemate-bridge:
    image: boojew/homemate-bridge
    volumes:
      - /docker/mountpoints/homematebridge/keys.json:/config/keys.json
    environment:
      - MQTT_HOST="192.168.0.115"

But unfortunately I'm getting this error: socket.gaierror: [Errno -2] Name or service not known

Any ideas what might be going awry here? ':D

I'm able to ping the MQTT broker from other containers within my portainer instance so it should be able to see the 0.115 IP... are there other environment variables I'm missing here? I've got an account configured in home assistant to access the MQTT broker, how would I go about configuring that for this bridge?

Eamourinho avatar Jun 13 '24 18:06 Eamourinho

@Eamourinho - wow, I'm glad that people are still finding this useful.

I don't really remember how any of this works, but two guesses:

  • Paho (the library that we use to connect to MQTT servers) is treating the IP address as a host name and trying to look it up for some reason - if the stack trace points you towards paho.mqtt.client then its probably something like that; not sure how you'd approach solving it
  • Something to do with your container environment not allowing the script to bind to 0.0.0.0 to listen for connections from the switches. I'd suggest adding network_mode: "host" to your compose file and seeing if that does something

While I'm here, @boojew sorry you got such a terse code review back in the day, thanks for putting in the effort to put your changes up for others to use.

insertjokehere avatar Jun 26 '24 03:06 insertjokehere