Skip to content

Commit

Permalink
Merge pull request #11 from rospogrigio/improvements
Browse files Browse the repository at this point in the history
Improvements
  • Loading branch information
rospogrigio authored Dec 15, 2021
2 parents 0a0606d + b357d15 commit 337891f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
4 changes: 1 addition & 3 deletions custom_components/airbnk_mqtt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
lock_devices = {}
for dev_id, dev_config in device_configs.items():
if dev_config[CONF_DEVICE_MQTT_TYPE] == CONF_CUSTOM_MQTT:
lock_devices[dev_id] = CustomMqttLockDevice(
hass, dev_config, entry.options
)
lock_devices[dev_id] = CustomMqttLockDevice(hass, dev_config, entry.options)
else:
lock_devices[dev_id] = TasmotaMqttLockDevice(
hass, dev_config, entry.options
Expand Down
2 changes: 1 addition & 1 deletion custom_components/airbnk_mqtt/airbnk_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ async def getCloudDevices(hass, userId, token):
res = {}
deviceConfigs = {}
for dev_data in json_data["data"] or []:
if not dev_data["boardModel"].isnumeric():
if dev_data["deviceType"][0] in ["W", "F"]:
_LOGGER.info("Device '%s' is filtered out", dev_data["deviceName"])
else:
res[dev_data["sn"]] = dev_data["deviceName"]
Expand Down
49 changes: 41 additions & 8 deletions custom_components/airbnk_mqtt/custom_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import logging
import time
from typing import Callable
from textwrap import wrap

from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.components import mqtt
Expand Down Expand Up @@ -68,15 +67,17 @@ class CustomMqttLockDevice:
cmd = {}
cmdSent = False
last_advert_time = 0
last_telemetry_time = 0
is_available = False
retries_num = DEFAULT_RETRIES_NUM
curr_try = 0

def __init__(self, hass: HomeAssistant, device_config, entry_options):
_LOGGER.debug("Setting up CustomMqttLockDevice for sn %s", device_config["sn"])
self.hass = hass
self._callbacks = set()
self._lockConfig = device_config
self._codes_generator = AirbnkCodesGenerator()
mac_addr = self._lockConfig[CONF_MAC_ADDRESS]
self._lockData = self._codes_generator.decryptKeys(
device_config["newSninfo"], device_config["appKey"]
)
Expand All @@ -102,9 +103,10 @@ def device_info(self):

def check_availability(self):
curr_time = int(round(time.time()))
deltatime = curr_time - self.last_advert_time
# _LOGGER.debug("Last reply was %s secs ago", deltatime)
if deltatime >= MAX_NORECEIVE_TIME:
deltatime1 = curr_time - self.last_advert_time
deltatime2 = curr_time - self.last_telemetry_time
# _LOGGER.debug("Last reply was %s - %s secs ago", deltatime1, deltatime2)
if min(deltatime1, deltatime2) >= MAX_NORECEIVE_TIME:
self.is_available = False

@property
Expand Down Expand Up @@ -173,6 +175,8 @@ def register_callback(self, callback: Callable[[], None]) -> None:
def parse_telemetry_message(self, msg):
# TODO
_LOGGER.debug("Received telemetry %s", msg)
self.last_telemetry_time = int(round(time.time()))
self.is_available = True

def parse_adv_message(self, msg):
_LOGGER.debug("Received adv %s", msg)
Expand Down Expand Up @@ -210,20 +214,34 @@ def parse_operation_message(self, msg):

msg_state = payload["success"]
if msg_state is False:
_LOGGER.error("Failed sending command: returned %s", msg_state)
self.curr_state = LOCK_STATE_FAILED
raise Exception("Failed sending command: returned %s", msg_state)
if self.curr_try < self.retries_num:
self.curr_try += 1
time.sleep(0.5)
_LOGGER.debug("Retrying: attempt %i", self.curr_try)
self.curr_state = LOCK_STATE_OPERATING
for callback_func in self._callbacks:
callback_func()
self.send_mqtt_command()
else:
_LOGGER.error("No more retries: command FAILED")
self.curr_state = LOCK_STATE_FAILED
for callback_func in self._callbacks:
callback_func()
raise Exception("Failed sending command: returned %s", msg_state)
return

msg_sign = payload["sign"]
if msg_sign == self.cmd["sign"]:
self.cmdSent = True

self.parse_new_lockStatus(payload["lockStatus"])

for callback_func in self._callbacks:
callback_func()

async def operateLock(self, lock_dir):
_LOGGER.debug("operateLock called (%s)", lock_dir)
self.curr_try = 0
self.cmdSent = False
self.curr_state = LOCK_STATE_OPERATING
for callback_func in self._callbacks:
Expand All @@ -234,12 +252,27 @@ async def operateLock(self, lock_dir):
self.cmd["command1"] = "FF00" + opCode[0:36].decode("utf-8")
self.cmd["command2"] = "FF01" + opCode[36:].decode("utf-8")
self.cmd["sign"] = self._codes_generator.systemTime
self.send_mqtt_command()

def send_mqtt_command(self):
mqtt.publish(
self.hass,
BLEOpTopic % self._lockConfig[CONF_MQTT_TOPIC],
json.dumps(self.cmd),
)

def parse_new_lockStatus(self, lockStatus):
_LOGGER.debug("Parsing new lockStatus: %s", lockStatus)
bArr = bytearray.fromhex(lockStatus)
if bArr[0] != 0xAA or bArr[3] != 0x02 or bArr[4] != 0x04:
_LOGGER.error("Wrong lockStatus msg: %s", lockStatus)
return

lockEvents = (bArr[10] << 24) | (bArr[11] << 16) | (bArr[12] << 8) | bArr[13]
self.lockEvents = lockEvents
self.voltage = ((float)((bArr[14] << 8) | bArr[15])) * 0.01
self.curr_state = (bArr[16] >> 4) & 3

def parse_MQTT_advert(self, mqtt_advert):
_LOGGER.debug("Parsing advert msg: %s", mqtt_advert)
bArr = bytearray.fromhex(mqtt_advert)
Expand Down
6 changes: 3 additions & 3 deletions custom_components/airbnk_mqtt/tasmota_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,6 @@ async def async_parse_MQTT_message(self, msg):
msg_state = payload[msg_type]["state"]
if "FAIL" in msg_state:
_LOGGER.error("Failed sending frame: returned %s", msg_state)
self.curr_state = LOCK_STATE_FAILED
for callback_func in self._callbacks:
callback_func()

if self.curr_try < self.retries_num:
self.curr_try += 1
Expand All @@ -276,6 +273,9 @@ async def async_parse_MQTT_message(self, msg):
await self.async_sendFrame1()
else:
_LOGGER.error("No more retries: command FAILED")
self.curr_state = LOCK_STATE_FAILED
for callback_func in self._callbacks:
callback_func()
raise Exception("Failed sending frame: returned %s", msg_state)

return
Expand Down

0 comments on commit 337891f

Please sign in to comment.