-
Notifications
You must be signed in to change notification settings - Fork 24
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
Dongle v47 support #61
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,7 @@ class Packet(object): | |
NOTIFY_SENSOR_SCAN = MAKE_CMD(TYPE_ASYNC, 0x20) | ||
NOITFY_SYNC_TIME = MAKE_CMD(TYPE_ASYNC, 0x32) | ||
NOTIFY_EVENT_LOG = MAKE_CMD(TYPE_ASYNC, 0x35) | ||
NOTIFY_HMS_EVENT = MAKE_CMD(TYPE_ASYNC, 0x55) | ||
|
||
def __init__(self, cmd, payload=bytes()): | ||
self._cmd = cmd | ||
|
@@ -238,6 +239,16 @@ def __str__(self): | |
s += "AlarmEvent: sensor_type=%s, state=%s, battery=%d, signal=%d" % self.Data | ||
elif self.Type == 'status': | ||
s += "StatusEvent: sensor_type=%s, state=%s, battery=%d, signal=%d" % self.Data | ||
elif self.Type == 'water': | ||
s += "WaterEvent: water=%d ext_water=%d has_ext=%d battery=%d signal=%d" % self.Data | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do the values of |
||
elif self.Type == 'climate': | ||
s += "ClimateEvent: temperature=%d humidity=%d battery=%d signal=%d" % self.Data | ||
elif self.Type == 'keypadMode': | ||
s += "KeypadModeEvent: mode=%d, battery=%d signal=%d" % self.Data | ||
elif self.Type == 'keypadMotion': | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
s += "KeypadModeEvent: motion=%d, battery=%d signal=%d" % self.Data | ||
elif self.Type == 'keypadPin': | ||
s+= "KeyPadPinEvent: pin=%s battery=%d signal=%d" % self.Data | ||
else: | ||
s += "RawEvent: type=%s, data=%s" % (self.Type, bytes_to_hex(self.Data)) | ||
return s | ||
|
@@ -288,7 +299,13 @@ def _OnSensorAlarm(self, pkt): | |
# is reporting way to high to actually be humidity. | ||
sensor_type = "leak:temperature" | ||
sensor_state = "%d.%d" % (alarm_data[5], alarm_data[6]) | ||
e = SensorEvent(sensor_mac, timestamp, "state", (sensor_type, sensor_state, alarm_data[2], alarm_data[8])) | ||
e = SensorEvent(sensor_mac, timestamp, "state", (sensor_type, sensor_state, alarm_data[2], alarm_data[8])) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a mismatch here between what is getting sent to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
else: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the value of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, is I found a potentially relevant discussion here: #29 (comment), but there was never any answer from @jellybob 🤔 |
||
temperature = alarm_data[0x05] | ||
humidity = alarm_data[0x07] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment leftover from #32 mentions that |
||
battery = alarm_data[0x02] | ||
signal = alarm_data[0x0A] | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
e = SensorEvent(sensor_mac, timestamp, "climate", (temperature, humidity, battery, signal)) | ||
else: | ||
e = SensorEvent(sensor_mac, timestamp, "raw_%02X" % event_type, alarm_data) | ||
|
||
|
@@ -305,6 +322,46 @@ def _OnEventLog(self, pkt): | |
msg = pkt.Payload[9:] | ||
log.info("LOG: time=%s, data=%s", tm.isoformat(), bytes_to_hex(msg)) | ||
|
||
def _OnHMSEvent(self, pkt): | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
payloadSubType = pkt.Payload[0x0E] | ||
if payloadSubType == 0x12: | ||
#Water sensor event | ||
typeByte, mac = struct.unpack_from(">B8s", pkt.Payload); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like this and the next line are duplicated, along with some common payload data (like battery)... |
||
mac = mac.decode('ascii') | ||
water = pkt.Payload[0x0F] | ||
ext_water = pkt.Payload[0x10] | ||
has_ext = pkt.Payload[0x11] | ||
signal = pkt.Payload[0x14] | ||
battery = pkt.Payload[0x0C] | ||
e = SensorEvent(mac, datetime.datetime.utcnow(), "water", (water, ext_water, has_ext, battery, signal)) | ||
self.__on_event(self, e) | ||
elif payloadSubType == 0x0A or payloadSubType == 0x02: | ||
typeByte, mac = struct.unpack_from(">B8s", pkt.Payload); | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mac = mac.decode('ascii') | ||
battery = pkt.Payload[0x0C] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one is consistently (for me anyways) a value of around 150... How can we figure the actual battery value from that? |
||
signal = pkt.Payload[pkt.Payload[0x0A] + 0x0B] | ||
if pkt.Payload[0x0E] == 0x02: | ||
mode = pkt.Payload[0x0F] + 1 | ||
e = SensorEvent(mac, datetime.datetime.utcnow(), "keypadMode", (mode, battery, signal)) | ||
self.__on_event(self, e) | ||
else: | ||
motion = pkt.Payload[0x0F] | ||
e = SensorEvent(mac, datetime.datetime.utcnow(), "keypadMotion", (motion, battery, signal)) | ||
self.__on_event(self, e) | ||
elif payloadSubType == 0x08: | ||
typeByte, mac = struct.unpack_from(">B8s", pkt.Payload); | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mac = mac.decode('ascii') | ||
battery = pkt.Payload[0x0C] | ||
signal = pkt.Payload[pkt.Payload[0xA] + 0xB] | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
pinBytes = pkt.Payload[0xF:(0xF + pkt.Payload[0xA] - 6)] | ||
pinIntList = [str(int) for int in list(pinBytes)] | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pinStr = "".join(pinIntList) | ||
|
||
e = SensorEvent(mac, datetime.datetime.utcnow(), "keypadPin", (pinStr, battery, signal)) | ||
self.__on_event(self, e) | ||
|
||
|
||
def __init__(self, device, event_handler): | ||
self.__lock = threading.Lock() | ||
self.__fd = os.open(device, os.O_RDWR | os.O_NONBLOCK) | ||
|
@@ -317,6 +374,7 @@ def __init__(self, device, event_handler): | |
Packet.NOITFY_SYNC_TIME: self._OnSyncTime, | ||
Packet.NOTIFY_SENSOR_ALARM: self._OnSensorAlarm, | ||
Packet.NOTIFY_EVENT_LOG: self._OnEventLog, | ||
Packet.NOTIFY_HMS_EVENT: self._OnHMSEvent, | ||
} | ||
|
||
self._Start() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ | |
# import time | ||
|
||
import paho.mqtt.client as mqtt | ||
import wyzesense | ||
#import wyzesense | ||
from retrying import retry | ||
|
||
|
||
|
@@ -466,6 +466,103 @@ def on_event(WYZESENSE_DONGLE, event): | |
|
||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}" | ||
mqtt_publish(state_topic, event_payload) | ||
elif(event.Type == "water"): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this one should also probably be |
||
(water, ext_water, has_ext, battery, signal) = event.Data | ||
# Build event payload | ||
event_payload = { | ||
'event': event.Type, | ||
'available': True, | ||
'mac': event.MAC, | ||
'device_class': 'leak', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll double-check, but I believe the device class Home Assistant uses is |
||
'last_seen': event.Timestamp.timestamp(), | ||
'last_seen_iso': event.Timestamp.isoformat(), | ||
'signal_strength': signal * -1, | ||
'battery': battery, | ||
'state' : { | ||
'water' : water, | ||
'ext_water' : ext_water, | ||
'has_ext' : has_ext | ||
} | ||
} | ||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}" | ||
mqtt_publish(state_topic, event_payload) | ||
elif(event.Type == "keypadMotion"): | ||
(motion, battery, signal) = event.Data | ||
# Build event payload | ||
event_payload = { | ||
'event': event.Type, | ||
'available': True, | ||
'mac': event.MAC, | ||
'device_class': 'motion', | ||
'last_seen': event.Timestamp.timestamp(), | ||
'last_seen_iso': event.Timestamp.isoformat(), | ||
'signal_strength': signal * -1, | ||
'battery': battery, | ||
'state' : motion | ||
} | ||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}" | ||
mqtt_publish(state_topic, event_payload) | ||
elif(event.Type == "keypadMode"): | ||
(mode, battery, signal) = event.Data | ||
# Build event payload | ||
event_payload = { | ||
'event': event.Type, | ||
'available': True, | ||
'mac': event.MAC, | ||
'device_class': 'keypadMode', | ||
'last_seen': event.Timestamp.timestamp(), | ||
'last_seen_iso': event.Timestamp.isoformat(), | ||
'signal_strength': signal * -1, | ||
'battery': battery, | ||
'state' : mode | ||
} | ||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}/mode" | ||
mqtt_publish(state_topic, event_payload) | ||
elif(event.Type == "keypadPin"): | ||
(pinBytes, battery, signal) = event.Data | ||
# Build event payload | ||
event_payload = { | ||
'event': event.Type, | ||
'available': True, | ||
'mac': event.MAC, | ||
'device_class': 'keypadPin', | ||
'last_seen': event.Timestamp.timestamp(), | ||
'last_seen_iso': event.Timestamp.isoformat(), | ||
'signal_strength': signal * -1, | ||
'battery': battery, | ||
'state' : pinBytes | ||
} | ||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}/pin" | ||
mqtt_publish(state_topic, event_payload) | ||
elif(event.Type == "climate"): | ||
(temperature, humidity, battery, signal) = event.Data | ||
# Build event payload | ||
event_payload = { | ||
'event': event.Type, | ||
'available': True, | ||
'mac': event.MAC, | ||
'device_class': 'climate', | ||
'last_seen': event.Timestamp.timestamp(), | ||
'last_seen_iso': event.Timestamp.isoformat(), | ||
'signal_strength': signal * -1, | ||
'battery': battery, | ||
'state' : { | ||
'temperature' : temperature, | ||
'humidity' : humidity | ||
} | ||
} | ||
LOGGER.debug(event_payload) | ||
|
||
state_topic = f"{CONFIG['self_topic_root']}/{event.MAC}" | ||
mqtt_publish(state_topic, event_payload) | ||
else: | ||
|
@@ -480,6 +577,8 @@ def on_event(WYZESENSE_DONGLE, event): | |
# Initialize logging | ||
init_logging() | ||
|
||
import wyzesense | ||
drinfernoo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Initialize configuration | ||
init_config() | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should either be
'state'
, or preferably we should change this and the leak portion to'leak'
or'water'
.