Skip to content

Commit

Permalink
Fix BLE data processing AlexxIT#114
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Nov 21, 2020
1 parent aa857eb commit 35421e9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 31 deletions.
50 changes: 20 additions & 30 deletions custom_components/xiaomi_gateway3/core/gateway3.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

RE_NWK_KEY = re.compile(r'lumi send-nwk-key (0x.+?) {(.+?)}')
RE_MAC = re.compile('^0x0*')
RE_JSON = re.compile(b'{.+}')
# MAC reverse
RE_REVERSE = re.compile(r'(..)(..)(..)(..)(..)(..)')

Expand Down Expand Up @@ -349,11 +348,18 @@ def on_message(self, client: Client, userdata, msg: MQTTMessage):
if 'miio' in self._debug:
_LOGGER.debug(f"[MI] {msg.payload}")

if self.ble:
if b'_async.ble_event' in msg.payload:
self.process_ble_event(msg.payload)
elif b'properties_changed' in msg.payload:
self.process_mesh_data(msg.payload)
if self.ble and (
b'_async.ble_event' in msg.payload or
b'properties_changed' in msg.payload
):
try:
for raw in utils.extract_jsons(msg.payload):
if b'_async.ble_event' in raw:
self.process_ble_event(raw)
elif b'properties_changed' in raw:
self.process_mesh_data(raw)
except:
_LOGGER.warning(f"Can't read BT: {msg.payload}")

elif msg.topic.endswith('/heartbeat'):
payload = json.loads(msg.payload)
Expand Down Expand Up @@ -537,18 +543,10 @@ def process_zb_message(self, payload: dict):
self.debug(f"{did} <= LQI {payload['linkQuality']}")

def process_ble_event(self, raw: Union[bytes, str]):
try:
if isinstance(raw, bytes):
# fix two json bug
if b'}{' in raw:
raw = raw[:raw.index(b'}{') + 1]
m = RE_JSON.search(raw)
data = json.loads(m[0])['params']
else:
data = json.loads(raw)
except:
self.debug(f"Wrong BLE input: {raw}")
return
if isinstance(raw, bytes):
data = json.loads(raw)['params']
else:
data = json.loads(raw)

self.debug(f"Process BLE {data}")

Expand Down Expand Up @@ -644,18 +642,10 @@ def process_ble_retain(self, did: str, payload: dict):
handler(payload)

def process_mesh_data(self, raw: Union[bytes, list]):
try:
if isinstance(raw, bytes):
# fix two json bug
if b'}{' in raw:
raw = raw[:raw.index(b'}{') + 1]
m = RE_JSON.search(raw)
data = json.loads(m[0])['params']
else:
data = raw
except:
self.debug(f"Wrong Mesh* input: {raw}")
return
if isinstance(raw, bytes):
data = json.loads(raw)['params']
else:
data = raw

# not always Mesh devices
self.debug(f"Process Mesh* {data}")
Expand Down
11 changes: 10 additions & 1 deletion custom_components/xiaomi_gateway3/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re
import uuid
from datetime import datetime
from typing import Optional
from typing import Optional, List

from aiohttp import web
from homeassistant.components.http import HomeAssistantView
Expand Down Expand Up @@ -413,6 +413,15 @@ def migrate_unique_id(hass: HomeAssistantType):
registry.async_update_entity(entity.entity_id, new_unique_id=uid)


RE_JSON = re.compile(b'{.+}')


def extract_jsons(raw) -> List[bytes]:
"""There can be multiple concatenated json on one line."""
m = RE_JSON.search(raw)[0]
return m.replace(b'}{', b'}\n{').split(b'\n')


TITLE = "Xiaomi Gateway 3 Debug"
NOTIFY_TEXT = '<a href="%s" target="_blank">Open Log<a>'
HTML = (f'<!DOCTYPE html><html><head><title>{TITLE}</title>'
Expand Down

0 comments on commit 35421e9

Please sign in to comment.