mirror of
https://github.com/andvikt/mega_hacs.git
synced 2025-12-11 00:54:28 +05:00
155 lines
4.6 KiB
Python
155 lines
4.6 KiB
Python
import typing
|
|
from dataclasses import dataclass, field, astuple
|
|
from urllib.parse import parse_qsl, urlparse
|
|
from bs4 import BeautifulSoup
|
|
from homeassistant.const import (
|
|
DEVICE_CLASS_HUMIDITY,
|
|
DEVICE_CLASS_TEMPERATURE,
|
|
DEVICE_CLASS_ILLUMINANCE,
|
|
DEVICE_CLASS_PRESSURE,
|
|
DEVICE_CLASS_CO2,
|
|
PERCENTAGE,
|
|
LIGHT_LUX,
|
|
TEMP_CELSIUS,
|
|
CONCENTRATION_PARTS_PER_MILLION,
|
|
PRESSURE_BAR,
|
|
)
|
|
from collections import namedtuple
|
|
|
|
# DeviceType = namedtuple('DeviceType', 'device_class,unit_of_measurement,suffix')
|
|
|
|
@dataclass
|
|
class DeviceType:
|
|
|
|
device_class: typing.Optional[str] = None
|
|
unit_of_measurement: typing.Optional[str] = None
|
|
suffix: typing.Optional[str] = None
|
|
delay: typing.Optional[float] = None
|
|
|
|
|
|
def parse_scan_page(page: str):
|
|
ret = []
|
|
req = []
|
|
page = BeautifulSoup(page, features="lxml")
|
|
for x in page.find_all('a'):
|
|
params = x.get('href')
|
|
if params is None:
|
|
continue
|
|
params = dict(parse_qsl(urlparse(params).query))
|
|
dev = params.get('i2c_dev')
|
|
if dev is None:
|
|
continue
|
|
classes = i2c_classes.get(dev, [])
|
|
for i, c in enumerate(classes):
|
|
_params = params.copy()
|
|
if c is Skip:
|
|
continue
|
|
elif c is Request:
|
|
req.append(_params)
|
|
continue
|
|
elif isinstance(c, Request):
|
|
if c.delay:
|
|
_params['delay'] = c.delay
|
|
req.append(_params)
|
|
continue
|
|
elif isinstance(c, DeviceType):
|
|
c, m, suffix, delay = astuple(c)
|
|
if delay is not None:
|
|
_params['delay'] = delay
|
|
else:
|
|
continue
|
|
suffix = suffix or c
|
|
if 'addr' in _params:
|
|
suffix += f"_{_params['addr']}" if suffix else str(_params['addr'])
|
|
if suffix:
|
|
_dev = f'{dev}_{suffix}'
|
|
else:
|
|
_dev = dev
|
|
if i > 0:
|
|
_params['i2c_par'] = i
|
|
|
|
ret.append({
|
|
'id_suffix': _dev,
|
|
'device_class': c,
|
|
'params': _params,
|
|
'unit_of_measurement': m,
|
|
})
|
|
req.append(_params)
|
|
return req, ret
|
|
|
|
|
|
class Skip:
|
|
pass
|
|
|
|
|
|
@dataclass
|
|
class Request:
|
|
delay: float = None
|
|
|
|
|
|
i2c_classes = {
|
|
'htu21d': [
|
|
DeviceType(DEVICE_CLASS_HUMIDITY, PERCENTAGE, None),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'sht31': [
|
|
DeviceType(DEVICE_CLASS_HUMIDITY, PERCENTAGE, None, delay=1.5),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'max44009': [
|
|
DeviceType(DEVICE_CLASS_ILLUMINANCE, LIGHT_LUX, None)
|
|
],
|
|
'bh1750': [
|
|
DeviceType(DEVICE_CLASS_ILLUMINANCE, LIGHT_LUX, None)
|
|
],
|
|
'tsl2591': [
|
|
DeviceType(DEVICE_CLASS_ILLUMINANCE, LIGHT_LUX, None)
|
|
],
|
|
'bmp180': [
|
|
DeviceType(DEVICE_CLASS_PRESSURE, PRESSURE_BAR, None),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'bmx280': [
|
|
DeviceType(DEVICE_CLASS_PRESSURE, PRESSURE_BAR, None),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
DeviceType(DEVICE_CLASS_HUMIDITY, PERCENTAGE, None)
|
|
],
|
|
'dps368': [
|
|
DeviceType(DEVICE_CLASS_PRESSURE, PRESSURE_BAR, None),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'mlx90614': [
|
|
Skip,
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 'temp'),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, 'object'),
|
|
],
|
|
'ptsensor': [
|
|
Skip,
|
|
Request(delay=3), # запрос на измерение
|
|
DeviceType(DEVICE_CLASS_PRESSURE, PRESSURE_BAR, None),
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'mcp9600': [
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), # термопара
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None), # сенсор встроенный в микросхему
|
|
],
|
|
't67xx': [
|
|
DeviceType(DEVICE_CLASS_CO2, CONCENTRATION_PARTS_PER_MILLION, None)
|
|
],
|
|
'tmp117': [
|
|
DeviceType(DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, None),
|
|
],
|
|
'ads1115': [
|
|
DeviceType(None, None, 'ch0'),
|
|
DeviceType(None, None, 'ch1'),
|
|
DeviceType(None, None, 'ch2'),
|
|
DeviceType(None, None, 'ch3'),
|
|
],
|
|
'ads1015': [
|
|
DeviceType(None, None, 'ch0'),
|
|
DeviceType(None, None, 'ch1'),
|
|
DeviceType(None, None, 'ch2'),
|
|
DeviceType(None, None, 'ch3'),
|
|
],
|
|
}
|