Skip to content

Commit

Permalink
performance improve
Browse files Browse the repository at this point in the history
  • Loading branch information
niceboy committed Mar 13, 2024
1 parent f0d4da0 commit 0014f31
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 79 deletions.
4 changes: 2 additions & 2 deletions custom_components/aqara_gateway/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
# migrate data (also after first setup) to options
if entry.data:
hass.config_entries.async_update_entry(entry, data={},
options=entry.data)
options=entry.data)

await _setup_logger(hass)

Expand Down Expand Up @@ -194,7 +194,7 @@ def __init__(self, gateway: Gateway, device: dict, attr: str):

self._unique_id = f"{self.device['mac']}_{self._attr}"
self._name = (self.device['device_name'] + ' ' +
self._attr.replace('_', ' ').title())
self._attr.replace('_', ' ').title())

self.entity_id = f"{DOMAIN}.{self._unique_id}"

Expand Down
Empty file modified custom_components/aqara_gateway/binary_sensor.py
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion custom_components/aqara_gateway/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async def async_step_discovery_confirm(self, user_input=None):
return self.async_show_form(
step_id="discovery_confirm",
description_placeholders={"name": self._name,
"device_info": self._device_info}
"device_info": self._device_info}
)

async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
Expand Down
22 changes: 12 additions & 10 deletions custom_components/aqara_gateway/core/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,18 @@
POWER = "power"
VOLTAGE = "voltage"

DOMAINS = ['air_quality',
'alarm_control_panel',
'binary_sensor',
'climate',
'cover',
'light',
'remote',
'select',
'sensor',
'switch']
DOMAINS = [
'air_quality',
'alarm_control_panel',
'binary_sensor',
'climate',
'cover',
'light',
'remote',
'select',
'sensor',
'switch'
]

UNITS = {
SensorDeviceClass.BATTERY: PERCENTAGE,
Expand Down
98 changes: 57 additions & 41 deletions custom_components/aqara_gateway/core/gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Optional
from random import randint
from paho.mqtt.client import Client, MQTTMessage
from datetime import datetime

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Event, HomeAssistant
Expand Down Expand Up @@ -57,7 +58,7 @@ def __init__(self, hass: HomeAssistant, host: str, config: dict, **options):

self._debug = options.get('debug', '') # for fast access
self.parent_scan_interval = (-1 if options.get('parent') is None
else options['parent'])
else options['parent'])
self.default_devices = config['devices'] if config else None

self.devices = {}
Expand Down Expand Up @@ -165,7 +166,7 @@ async def async_run(self):
if not self._mqtt_connect() or not self._prepare_gateway():
if self.host in self.hass.data[DOMAIN]["mqtt"]:
self.hass.data[DOMAIN]["mqtt"].remove(self.host)
await asyncio.sleep(60)
await asyncio.sleep(10)
continue

self._mqttc.loop_start()
Expand Down Expand Up @@ -199,36 +200,36 @@ def _prepare_gateway(self, get_devices: bool = False):
device_name = Utils.get_device_name(self._model).lower()
if "g2h pro" in device_name:
shell = TelnetShellG2HPro(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g2h" in device_name:
shell = TelnetShellG2H(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "e1" in device_name:
shell = TelnetShellE1(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g3" in device_name:
shell = TelnetShellG3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m2 2022" in device_name:
shell = TelnetShellM2POE(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m1s 2022" in device_name:
shell = TelnetShellM1S22(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m3" in device_name:
shell = TelnetShellM3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
else:
shell = TelnetShell(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
shell.login()
processes = shell.get_running_ps()
processes = shell.get_running_ps("mosquitto")
public_mosquitto = shell.check_public_mosquitto()
if not public_mosquitto:
self.debug("mosquitto is not running as public!")

if "/data/bin/mosquitto -d" not in processes:
if "mosquitto" not in processes or not public_mosquitto:
if "mosquitto" not in processes or not public_mosquitto:
if "/data/bin/mosquitto -d" not in processes:
shell.run_public_mosquitto()

if get_devices:
Expand All @@ -251,21 +252,27 @@ def _get_devices(self, shell):
try:
# 1. Read coordinator info
value = {}

zb_coordinator = shell.get_prop("sys.zb_coordinator")
model = shell.get_prop("persist.sys.model")
prop_raw = shell.get_prop("")
data = re.search(r"\[sys\.zb_coordinator\\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
zb_coordinator = data.group(1) if data else shell.get_prop("sys.zb_coordinator")
data = re.search(r"\[persist\.sys\.model\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
model = data.group(1) if data else shell.get_prop("persist.sys.model")
if len(zb_coordinator) >= 1:
raw = shell.read_file(zb_coordinator, with_newline=False)
did = shell.get_prop("persist.sys.did")
model = shell.get_prop("ro.sys.model")
data = re.search(r"\[persist\.sys\.did\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
did = data.group(1) if data else shell.get_prop("persist.sys.did")
data = re.search(r"\[persist\.sys\.model\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
model = data.group(1) if data else shell.get_prop("ro.sys.model")
elif any(name in model for name in [
'lumi.gateway', 'lumi.aircondition',
'lumi.camera.gwpagl01', 'lumi.camera.agl001',
'lumi.camera.acn003']):
raw = shell.read_file(
'/data/zigbee/coordinator.info', with_newline=False)
did = shell.get_prop("persist.sys.did")
model = shell.get_prop("ro.sys.model")
data = re.search(r"\[persist\.sys\.did\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
did = data.group(1) if data else shell.get_prop("persist.sys.did")
data = re.search(r"\[ro\.sys\.model\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
model = data.group(1) if data else shell.get_prop("ro.sys.model")
else:
raw = str(shell.read_file('/mnt/config/miio/device.conf'))
if len(raw) <= 1:
Expand All @@ -291,7 +298,8 @@ def _get_devices(self, shell):
self._model = model

# zigbee devices
zb_device = shell.get_prop("sys.zb_device")
data = re.search(r"\[sys\.zb_device\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
zb_device = data.group(1) if data else shell.get_prop("sys.zb_device")
if len(zb_device) >= 1:
raw = shell.read_file(zb_device, with_newline=False)
else:
Expand Down Expand Up @@ -429,25 +437,25 @@ def process_gateway_stats(self, payload: dict = None):
device_name = Utils.get_device_name(self._model).lower()
if "g2h pro" in device_name:
shell = TelnetShellG2HPro(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g2h" in device_name:
shell = TelnetShellG2H(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "e1" in device_name:
shell = TelnetShellE1(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g3" in device_name:
shell = TelnetShellG3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m2 2022" in device_name:
shell = TelnetShellM2POE(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m1s 2022" in device_name:
shell = TelnetShellM1S22(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m3" in device_name:
shell = TelnetShellM3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
else:
shell = TelnetShell(self.host,
self.options.get(CONF_PASSWORD, ''))
Expand Down Expand Up @@ -531,25 +539,25 @@ def _process_devices_info(self, prop, value):
device_name = Utils.get_device_name(self._model).lower()
if "g2h pro" in device_name:
shell = TelnetShellG2HPro(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g2h" in device_name:
shell = TelnetShellG2H(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "e1" in device_name:
shell = TelnetShellE1(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "g3" in device_name:
shell = TelnetShellG3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m2 2022" in device_name:
shell = TelnetShellM2POE(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m1s 2022" in device_name:
shell = TelnetShellM1S22(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
elif "m3" in device_name:
shell = TelnetShellM3(self.host,
self.options.get(CONF_PASSWORD, ''))
self.options.get(CONF_PASSWORD, ''))
else:
shell = TelnetShell(self.host,
self.options.get(CONF_PASSWORD, ''))
Expand Down Expand Up @@ -895,9 +903,13 @@ def is_aqaragateway(host: str,
if device_name and 'g2h pro' in device_name:
shell = TelnetShellG2HPro(host, password)
shell.login()
model = shell.get_prop("ro.sys.model")
name = shell.get_prop("ro.sys.name")
mac = shell.get_prop("persist.sys.miio_mac")
prop_raw = shell.get_prop("")
data = re.search(r"\[ro\.sys\.model\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
model = data.group(1) if data else shell.get_prop("ro.sys.model")
data = re.search(r"\[ro\.sys\.name\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
name = data.group(1) if data else shell.get_prop("ro.sys.name")
data = re.search(r"\[persist\.sys\.miio_mac\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
mac = data.group(1) if data else shell.get_prop("persist.sys.miio_mac")
token = shell.get_token()
elif device_name and 'g2h' in device_name:
shell = TelnetShellG2H(host, password)
Expand All @@ -924,9 +936,13 @@ def is_aqaragateway(host: str,
else:
shell = TelnetShell(host, password)
shell.login()
model = shell.get_prop("persist.sys.model")
name = shell.get_prop("ro.sys.name")
mac = shell.get_prop("persist.sys.miio_mac")
prop_raw = shell.get_prop("")
data = re.search(r"\[persist\.sys\.model\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
model = data.group(1) if data else shell.get_prop("persist.sys.model")
data = re.search(r"\[ro\.sys\.name\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
name = data.group(1) if data else shell.get_prop("ro.sys.name")
data = re.search(r"\[persist\.sys\.miio_mac\]: \[([a-zA-Z0-9.-]+)\]", prop_raw)
mac = data.group(1) if data else shell.get_prop("persist.sys.miio_mac")
token = shell.get_token()

except (ConnectionError, EOFError, socket.error):
Expand Down
12 changes: 6 additions & 6 deletions custom_components/aqara_gateway/core/lock_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@
"someone detected": {"default": "Someone is lingering at the door"},
"li battery notify":
{"default": "Li Battery notify",
"0": "Li Battery is abnormal",
"1": "Li Battery is normal"},
"0": "Li Battery is abnormal",
"1": "Li Battery is normal"},
"battery notify":
{"default": "Battery notify",
"0": "Battery is die",
"1": "Battery level is low",
"2": "Battery level is middle",
"3": "Battery level is full"},
"0": "Battery is die",
"1": "Battery level is low",
"2": "Battery level is middle",
"3": "Battery level is full"},
"camera connected": {"default": "Camera is connected"},
"open in away mode": {
"default":
Expand Down
21 changes: 13 additions & 8 deletions custom_components/aqara_gateway/core/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


WGET = "(wget http://master.dl.sourceforge.net/project/aqarahub/{0}?viasf=1 " \
"-O /data/bin/{1} && chmod +x /data/bin/{1})"
"-O /data/bin/{1} && chmod +x /data/bin/{1})"

CHECK_SOCAT = "(md5sum /data/socat | grep 92b77e1a93c4f4377b4b751a5390d979)"
DOWNLOAD_SOCAT = "(wget -O /data/socat http://pkg.simple-ha.ru/mipsel/socat && chmod +x /data/socat)"
Expand Down Expand Up @@ -41,7 +41,8 @@ def login(self):
self.read_until(b"Password: ", timeout=1)
self.write(self._password.encode() + b"\n")
self.run_command("stty -echo")
self.read_until(b"/ # ", timeout=10)
self.write(b"\n")
self.read_until(b" # ", timeout=2)

# self.run_command("export PS1='# '")

Expand All @@ -50,8 +51,8 @@ def run_command(self, command: str, as_bytes=False) -> Union[str, bytes]:
# pylint: disable=broad-except
try:
self.write(command.encode() + b"\n")
suffix = "\r\n{}".format(self._suffix)
raw = self.read_until(suffix.encode(), timeout=30)
suffix = "\n{}".format(self._suffix)
raw = self.read_until(suffix.encode(), timeout=15)
except Exception:
raw = b''
return raw if as_bytes else raw.decode()
Expand Down Expand Up @@ -92,12 +93,16 @@ def run_public_mosquitto(self):
def check_public_mosquitto(self) -> bool:
""" get processes list """
raw = self.run_command("mosquitto")
if "Binding listener to interface" in raw:
return False
return True
if 'Binding listener to interface ""' in raw:
return True
if 'Binding listener to interface ' not in raw:
return True
return False

def get_running_ps(self) -> str:
def get_running_ps(self, ps=None) -> str:
""" get processes list """
if isinstance(ps, str):
return self.run_command(f"ps | grep {ps}")
return self.run_command("ps")

def redirect_ha_master2mqtt(self, pattern: str):
Expand Down
7 changes: 4 additions & 3 deletions custom_components/aqara_gateway/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from aiohttp import web
from miio import Device, DeviceException

from homeassistant.components import persistent_notification
from homeassistant.components.http import HomeAssistantView
from homeassistant.helpers.device_registry import DeviceRegistry
from homeassistant.helpers.typing import HomeAssistantType
Expand Down Expand Up @@ -1908,8 +1909,8 @@ def gateway_alarm_mode_supported(model: str) -> Optional[bool]:
def gateway_infrared_supported(model: str) -> Optional[bool]:
""" return the gateway infrared supported """
if model in ('lumi.aircondition.acn05', 'lumi.gateway.iragl5',
'lumi.gateway.iragl7', 'lumi.gateway.iragl01',
'lumi.gateway.iragl8', 'lumi.gateway.agl001'):
'lumi.gateway.iragl7', 'lumi.gateway.iragl01',
'lumi.gateway.iragl8', 'lumi.gateway.agl001'):
return True
return False

Expand Down Expand Up @@ -2000,7 +2001,7 @@ def __init__(self, hass: HomeAssistantType):
self.url = "/{}".format(uuid.uuid4())

hass.http.register_view(self)
hass.components.persistent_notification.async_create(
persistent_notification.async_create(
NOTIFY_TEXT % self.url, title=TITLE)

def handle(self, rec: logging.LogRecord) -> None:
Expand Down
8 changes: 0 additions & 8 deletions custom_components/aqara_gateway/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,6 @@
DEVICE_MAPPINGS,
)

GATEWAY_PLATFORMS = ["binary_sensor",
"sensor",
"switch",
"light",
"cover",
"lock"]
GATEWAY_PLATFORMS_NO_KEY = ["binary_sensor", "sensor"]


async def async_setup_entry(hass, entry, async_add_entities):
""" setup config entry """
Expand Down

0 comments on commit 0014f31

Please sign in to comment.