elric91 / homeassistant_zigate

Custom components for Home Assistant
MIT License
22 stars 5 forks source link

Display RSSI #8

Closed max5962 closed 4 years ago

max5962 commented 6 years ago

Hello, New Zigate firmware can send the Received Signal Strength Indication in the getDeviceslist response. Can you implement this ? COuld be a great tools to identify some signal reception error :)

ISO-B commented 6 years ago

Sure. It first need to be added to pyzigate.

elric91 commented 6 years ago

getDeviceList (8015) implemented in pyzigate (master, not published in pypi yet)

max5962 commented 6 years ago

Hello, thanks for the commit :)

I'm using the getDeviceList(8015) but it seems not working properly.

I sent to the zigate (zigate.raw_command) :

{
"cmd":"0015"
} 

i received :

2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate] --------------------------------------
2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate] REQUEST      : 0015
2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate]   # standard : 01 00 15 00 00 15 03
2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate]   # encoded  : b'01021015021002101503'
2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate] (timestamp : 10:48:14)
2018-03-16 10:48:14 DEBUG (SyncWorker_30) [zigate] --------------------------------------
2018-03-16 10:48:14 DEBUG (MainThread) [zigate] --------------------------------------
2018-03-16 10:48:14 DEBUG (MainThread) [zigate] RESPONSE 8000 : Status
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   * Status              : Success
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - Sequence            : b'00'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - Response to command : b'0015'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   # encoded : b'01800210021002159002100210021015021003'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   # decoded : 0180 00 00 05 90 00 00 00 15 0003
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   (@timestamp : 10:48:14)
2018-03-16 10:48:14 DEBUG (MainThread) [zigate] --------------------------------------
2018-03-16 10:48:14 DEBUG (MainThread) [zigate] RESPONSE 8015 : Unknown Message
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - After decoding  : b'8015004f5800841f00158d000201b1e50030010add00158d000225157c005702b4b500158d000225379a002403f3eb00158d0001b97f5b00200469a000158d0001de63da003a05224000158d000223a59d005400'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - MsgType         : b'8015'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - MsgLength       : b'004f'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - ChkSum          : b'58'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - Data            : b'00841f00158d000201b1e50030010add00158d000225157c005702b4b500158d000225379a002403f3eb00158d0001b97f5b00200469a000158d0001de63da003a05224000158d000223a59d005400'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   - RSSI            : b'00'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   # encoded : b'01801502104f580210841f0210158d021002120211b1e50210300211021add0210158d0210021225157c0210570212b4b50210158d0210021225379a0210240213f3eb0210158d02100211b97f5b021020021469a00210158d02100211de63da02103a021522400210158d0210021223a59d021054021003'
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   # decoded : 0180 15 00 4F 58 00 84 1F 00 15 8D 00 02 01 B1 E5 00 30 01 0A DD 00 15 8D 00 02 25 15 7C 00 57 02 B4 B5 00 15 8D 00 02 25 37 9A 00 24 03 F3 EB 00 15 8D 00 01 B9 7F 5B 00 20 04 69 A0 00 15 8D 00 01 DE 63 DA 00 3A 05 22 40 00 15 8D 00 02 23 A5 9D 00 54 0003
2018-03-16 10:48:14 DEBUG (MainThread) [zigate]   (@timestamp : 10:48:14)

MsgLength : b'004f' => 75 bytes - 4 bytes (MsgType) - 4 bytes ( Msg Length ) - 2 bytes ( checksum ) = 65 bytes.

According Zigate documentation : "<device list – data each entry is 13 bytes>" => 65/13 => 5 devices data.

i manually decoded the data :

01 80 15
00 4F
58

DEVICE LIST : 
00
   84 1F
   00 15 8D 00 02 01 B1 E5
   00
   30 => RSSI
01
   0A DD
   00 15 8D 00 02 25 15 7C
   00
   57 => RSSI

02
   B4 B5
   00 15 8D 00 02 25 37 9A
   00
   24 => RSSI
03 
   F3 EB
   00 15 8D 00 01 B9 7F 5B
   00
   20 => RSSI

04
   69 A0
   00 15 8D 00 01 DE 63 DA
   00
   3A => RSSI

05
   22 40
   00 15 8D 00 02 23 A5 9D
   00
   54 => RSSI

0003

Zigate response seems to be good.

lolorc commented 6 years ago

it would be nice if we could use the RSSI within HASS

elric91 commented 6 years ago

@max5962 : Strange that it is not working in pyzigate (tested it once again yesterday ... it was working) : are you using 0.1.3.post1 (latest) ?

max5962 commented 6 years ago

Hello @elric91 I'm confirm, i'm using the last pyzigate ... @lolorc are you experiencing the same issue ?

btw It could help, if you could log the version for the component and the zigate ( for investigate ) : ) EDIT 1 : uninstall and reinstall pyzigate, same issue

elric91 commented 6 years ago

I have good news and bad news :smile:

GOOD : seems your zigate is working properly

from collections import OrderedDict
from binascii import unhexlify
dcd =pyzigate.conversions.zgt_decode_struct
struct = OrderedDict([('ID', 8), ('addr', 16), ('IEEE', 64), ('power_source', 'int8'), ('link_quality', 'int8'),
                                   ('next', 'rawend')])
data = unhexlify(b'00841f00158d000201b1e50030010add00158d000225157c005702b4b500158d000225379a002403f3eb00158d0001b97f5b00200469a000158d0001de63da003a05224000158d000223a59d005400')

dcd(struct, data[5:])
OrderedDict([('ID', b'00'),
             ('addr', b'841f'),
             ('IEEE', b'00158d000201b1e5'),
             ('power_source', 0),
             ('link_quality', 48),
             ('next',
              b'\x01\n\xdd\x00\x15\x8d\x00\x02%\x15|\x00W\x02\xb4\xb5\x00\x15\x8d\x00\x02%7\x9a\x00$\x03\xf3\xeb\x00\x15\x8d\x00\x01\xb9\x7f[\x00 \x04i\xa0\x00\x15\x8d\x00\x01\xdec\xda\x00:\x05"@\x00\x15\x8d\x00\x02#\xa5\x9d\x00T\x00')])

so it's working (just have to go recursive to get all devices)

BAD : I don't get why 8015 is routed as unknown message ... would you mind posting the part of interface.py (the file on your HASS server) related to 8015 handling ? (it should start with a elif msg_type == b'8015':)

max5962 commented 6 years ago

Is that enough ? :)

grep -A 10 -B 10 "8015" interface.py
        # Version List
        elif msg_type == b'8010':
            struct = OrderedDict([('major', 'int16'), ('installer', 'int16')])
            msg = self.decode_struct(struct, msg_data)

            ZGT_LOG.debug('RESPONSE : Version List')
            ZGT_LOG.debug('  - Major version     : {}'.format(msg['major']))
            ZGT_LOG.debug('  - Installer version : {}'.format(msg['installer']))

        # Device list
        elif msg_type == b'8015':
            ZGT_LOG.debug('RESPONSE : Version List')

            while True:
                struct = OrderedDict([('ID', 8), ('addr', 16), ('IEEE', 64), ('power_source', 'int8'),
                                      ('link_quality', 'int8'), ('next', 'rawend')])
                msg = self.decode_struct(struct, msg_data)
                self.set_external_command(ZGT_CMD_LIST_DEVICES, **msg)
                ZGT_LOG.debug('  * deviceID     : {}'.format(msg['ID']))
                ZGT_LOG.debug('  - addr         : {}'.format(msg['addr']))
                ZGT_LOG.debug('  - IEEE         : {}'.format(msg['IEEE']))
max5962 commented 6 years ago

I’m trying to help but even if i add more log in the pyzigate code ( it doesn’t appear ). I’m using docker :

Add more logs

  1. open docker container bash
  2. pip/pip3 install --no-cache-dir -U --upgrade zigate-python/
  3. restart docker.

It doesnt work ( no added logs). I need help

max5962 commented 6 years ago

BIG NEWS :+1: Upgraded to the latest version of HASS ( 15.3 ) solved all my issues :

  1. illuminance
  2. RSSI

The ticket can be closed ( and add the information in the README :) ) thanks

lolorc commented 6 years ago

and do you get them as attributes in HASS ?

max5962 commented 6 years ago

no but it's a great idea !!!

lolorc commented 6 years ago

i guess there's no reason to close this issue then since it's opened in the HASS_zigate component :) no point in printing illuminance and RSSI without making them available to HASS for automation & stuff

max5962 commented 6 years ago

In order to get them as attributes in HASS, you just has to add that line : self.set_device_property(msg['addr'], b'01' , "Link quality", '{}'.format(msg['link_quality'])) Just after that line : ZGT_LOG.debug(' - Link Quality : {}'.format(msg['link_quality']))

lolorc commented 6 years ago

ever thought of doing a PR for this ? :) I guess you need to handle endpoint correctly, it's not always 01

max5962 commented 6 years ago

@lolorc totaly agree with that but i do not have time :) I will try to write some code this WE

lolorc commented 6 years ago

;-) I'm using it for one aqara sensor and several osram plug, I also have the same issue you have reported elsewhere : link quality is not updated when the main state doesn't change, for instance the plug state doesn't change quite often, subsequently rssi values are not updated. I guess a proper PR would imply changes in both ZiGate & homeassisant_zigate.

max5962 commented 6 years ago

@elric91 @ISO-B There is a way to retreive the endpoint of a known device ( in the self object) ? ( i'd like to do a PR ) Here the code :

elif msg_type == b'8015':
            ZGT_LOG.debug('RESPONSE : Version List')
            while True:
                struct = OrderedDict([('ID', 8), ('addr', 16), ('IEEE', 64), ('power_source', 'int8'),
                                      ('link_quality', 'int8'), ('next', 'rawend')])
                msg = self.decode_struct(struct, msg_data)
                self.set_external_command(ZGT_CMD_LIST_DEVICES, **msg)
                ZGT_LOG.debug('  * deviceID     : {}'.format(msg['ID']))
                ZGT_LOG.debug('  - addr         : {}'.format(msg['addr']))
                ZGT_LOG.debug('  - IEEE         : {}'.format(msg['IEEE']))
                ZGT_LOG.debug('  - Power Source : {}'.format(msg['power_source']))
                ZGT_LOG.debug('  - Link Quality : {}'.format(msg['link_quality']))
                ZGT_LOG.debug('  - TEST : 15/06 20H34')
                ZGT_LOG.debug(**self._known_devices**)
                if int(msg['link_quality']) != 255:
                    self.set_device_property(msg['addr'], **b'01'** , "Link quality", '{}'.format(msg['link_quality']))
                else:
                    ZGT_LOG.error('{} dead ? '.format(msg['ID']))

                if len(msg['next']) < 13:
                    break
                else:
                    msg_data = msg['next']

The best way i found i to store in _known_devices object the "addr" and the "endpoint". As soon as the code is updated i will do a PR.

max5962 commented 6 years ago

Pull request on Zigate and home_assistant_zigate done ! :)