Skip to content

Commit

Permalink
Support adding custom devices!
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Sep 27, 2020
1 parent 8592d2a commit 711c042
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
30 changes: 30 additions & 0 deletions custom_components/xiaomi_gateway3/gateway3.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@

_LOGGER = logging.getLogger(__name__)

RE_NWK_KEY = re.compile(r'lumi send-nwk-key (0x.+?) {(.+?)}')


class Gateway3(Thread):
pair_model = None
pair_payload = None

def __init__(self, host: str, token: str, config: dict):
super().__init__(daemon=True)

Expand Down Expand Up @@ -332,6 +337,8 @@ def on_message(self, client: Client, userdata, msg: MQTTMessage):
if msg.topic == 'zigbee/send':
payload = json.loads(msg.payload)
self.process_message(payload)
elif self.pair_model and msg.topic.endswith('/commands'):
self.process_pair(msg.payload)

def setup_devices(self, devices: list):
"""Add devices to hass."""
Expand Down Expand Up @@ -430,6 +437,29 @@ def process_message(self, data: dict):
device['init'] = payload
self.setup_devices([device])

def process_pair(self, raw: bytes):
# get shortID and eui64 of paired device
if b'lumi send-nwk-key' in raw:
# create model response
payload = f"0x18010105000042{len(self.pair_model):02x}" \
f"{self.pair_model.encode().hex()}"
m = RE_NWK_KEY.search(raw.decode())
self.pair_payload = json.dumps({
'sourceAddress': m[1],
'eui64': '0x' + m[2],
'profileId': '0x0104',
'clusterId': '0x0000',
'sourceEndpoint': '0x01',
'destinationEndpoint': '0x01',
'APSCounter': '0x01',
'APSPlayload': payload
}, separators=(',', ':'))

# send model response "from device"
elif b'zdo active ' in raw:
mac = self.device['mac'][2:].upper()
self.mqtt.publish(f"gw/{mac}/MessageReceived", self.pair_payload)

def process_ble_event(self, raw: Union[bytes, str]):
data = json.loads(raw[10:])['params'] \
if isinstance(raw, bytes) else json.loads(raw)
Expand Down
16 changes: 16 additions & 0 deletions custom_components/xiaomi_gateway3/remote.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging

from homeassistant.components import persistent_notification
from homeassistant.components.remote import ATTR_DEVICE
from homeassistant.helpers.entity import ToggleEntity

Expand Down Expand Up @@ -32,10 +33,20 @@ def update(self, data: dict = None):
if 'pairing_start' in data:
self._state = True
self.schedule_update_ha_state()

elif 'pairing_stop' in data:
self._state = False
self.schedule_update_ha_state()

self.gw.pair_model = None

elif 'added_device' in data:
text = "New device:\n" + '\n'.join(
f"{k}: {v}" for k, v in data['added_device'].items()
)
persistent_notification.async_create(self.hass, text,
"Xiaomi Gateway 3")

def turn_on(self):
self.gw.send(self.device, {'pairing_start': 60})

Expand All @@ -48,3 +59,8 @@ async def async_send_command(self, command, **kwargs):
if cmd == 'ble':
raw = kwargs[ATTR_DEVICE].replace('\'', '"')
self.gw.process_ble_event(raw)
elif cmd == 'pair':
model: str = kwargs[ATTR_DEVICE]
self.gw.pair_model = (model[:-3] if model.endswith('.v1')
else model)
self.turn_on()

0 comments on commit 711c042

Please sign in to comment.