This commit is contained in:
Evgeny Zinoviev 2023-05-22 07:11:21 +03:00
parent 893e21cc83
commit 2f1c00bed4
11 changed files with 126 additions and 49 deletions

View File

@ -3,6 +3,17 @@ from datetime import datetime
from typing import Tuple, List from typing import Tuple, List
from .clickhouse import ClickhouseDatabase from .clickhouse import ClickhouseDatabase
from ..api.types import TemperatureSensorLocation from ..api.types import TemperatureSensorLocation
from ..temphum import TempHumNodes
migration_tables_map = {
'temp_diana': TempHumNodes.KBN_SH_HALL.hash(),
'temp_street': TempHumNodes.KBN_BH_2FL_STREET.hash(),
'temp_roof': TempHumNodes.KBN_BH_2FL.hash(),
'temp_room': TempHumNodes.KBN_BH_1FL_BEDROOM.hash(),
'temp_spb1': TempHumNodes.SPB_FLAT120_CABINET.hash(),
'temp': TempHumNodes.KBN_BH_1FL_LIVINGROOM.hash()
}
def get_temperature_table(sensor: TemperatureSensorLocation) -> str: def get_temperature_table(sensor: TemperatureSensorLocation) -> str:
@ -28,6 +39,37 @@ def get_temperature_table(sensor: TemperatureSensorLocation) -> str:
class SensorsDatabase(ClickhouseDatabase): class SensorsDatabase(ClickhouseDatabase):
def __init__(self): def __init__(self):
super().__init__('home') super().__init__('home')
self.db.execute("""
CREATE TABLE IF NOT EXISTS temphum (
NodeID Uint32,
ClientTime DateTime,
ReceivedTime DateTime,
Temperature Int16,
RelativeHumidity UInt16,
SensorType Enum8('Si7021' = 0, 'DHT12' = 1, 'BME280' = 2),
) ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(ReceivedTime)
ORDER BY (NodeID, ReceivedTime);
""")
def migrate(self):
for table_name, node_id in migration_tables_map.items():
if table_name in ('temp_room',):
sensor_type = 'DHT12'
else:
sensor_type = 'Si7021'
self.logger.info(f'starting copying table {table_name}')
self.db.execute(f"""
INSERT INTO temphum (NodeID, ClientTime, ReceivedTime, Temperature, RelativeHumidify, SensorType)
SELECT {node_id}, ClientTime, ReceivedTime, Temperature, RelativeHumidify, '{sensor_type}' FROM {table_name}
""")
self.logger.info(f'finished copying table {table_name}')
def migrate_del_old_tables(self):
for table_name in migration_tables_map.keys():
self.db.execute(f"DROP TABLE {table_name}")
self.logger.info(f'dropped table {table_name}')
def add_temperature(self, def add_temperature(self,
home_id: int, home_id: int,

View File

@ -1,25 +1,8 @@
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import re import re
from enum import auto
from .payload.temphum import TempHumDataPayload from .payload.temphum import TempHumDataPayload
from .esp import MqttEspBase from .esp import MqttEspBase
from ..util import HashableEnum
class MqttTempHumNodes(HashableEnum):
KBN_SH_HALL = auto()
KBN_SH_BATHROOM = auto()
KBN_SH_LIVINGROOM = auto()
KBN_SH_BEDROOM = auto()
KBN_BH_2FL = auto()
KBN_BH_2FL_STREET = auto()
KBN_BH_1FL_LIVINGROOM = auto()
KBN_BH_1FL_BEDROOM = auto()
KBN_BH_1FL_BATHROOM = auto()
SPB_FLAT120_CABINET = auto()
class MqttTempHum(MqttEspBase): class MqttTempHum(MqttEspBase):

View File

@ -1,18 +1,38 @@
from .base import SensorType, TempHumSensor from importlib import import_module
from .si7021 import Si7021
from .dht12 import DHT12
__all__ = [ __all__ = [
'SensorType', 'SensorType',
'TempHumSensor', 'TempHumSensor',
'TempHumNodes',
'create_sensor' 'create_sensor'
] ]
def create_sensor(type: SensorType, bus: int) -> TempHumSensor: def __import_sensor(name):
if type == SensorType.Si7021: if name == 'si7021':
return Si7021(bus) return import_module('.si7021', __name__).Si7021
elif type == SensorType.DHT12: elif name == 'dht12':
return DHT12(bus) return import_module('.dht12', __name__).DHT12
else: else:
raise ValueError('unexpected sensor type') raise ValueError(f'unexpected sensor type: {name}')
def __getattr__(name):
if name == 'create_sensor':
base = import_module('.base', __name__)
def create_sensor(type: base.SensorType, bus: int) -> base.TempHumSensor:
if type == base.SensorType.Si7021:
return __import_sensor('si7021')(bus)
elif type == base.SensorType.DHT12:
return __import_sensor('dht12')(bus)
else:
raise ValueError(f'unexpected sensor type: {type}')
return create_sensor
elif name in ('SensorType', 'TempHumSensor'):
return getattr(import_module('.base', __name__), name)
elif name == 'TempHumNodes':
return import_module('.nodes', __name__).TempHumNodes

View File

@ -0,0 +1,9 @@
from .base import (
SensorType as SensorType,
TempHumSensor as TempHumSensor
)
from .nodes import TempHumNodes as TempHumNodes
def create_sensor(type: SensorType, bus: int) -> TempHumSensor:
pass

23
src/home/temphum/nodes.py Normal file
View File

@ -0,0 +1,23 @@
from ..util import HashableEnum
from enum import auto
class TempHumNodes(HashableEnum):
KBN_SH_HALL = auto()
KBN_SH_BATHROOM = auto()
KBN_SH_LIVINGROOM = auto()
KBN_SH_BEDROOM = auto()
KBN_BH_2FL = auto()
KBN_BH_2FL_STREET = auto()
KBN_BH_1FL_LIVINGROOM = auto()
KBN_BH_1FL_BEDROOM = auto()
KBN_BH_1FL_BATHROOM = auto()
KBN_STR_EL_BOX = auto()
SPB_FLAT120_CABINET = auto()
SPB_FLAT120_LIVINGROOM = auto()
SPB_FLAT120_BEDROOM = auto()
SPB_FLAT120_LVR_BALCONY = auto()
SPB_FLAT120_BDR_BALCONY = auto()
SPB_FLAT120_BATHROOM = auto()

View File

@ -1,14 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from home.mqtt.temphum import MqttTempHumNodes from home.temphum import TempHumNodes
if __name__ == '__main__': if __name__ == '__main__':
max_name_len = 0 max_name_len = 0
for node in MqttTempHumNodes: for node in TempHumNodes:
if len(node.name) > max_name_len: if len(node.name) > max_name_len:
max_name_len = len(node.name) max_name_len = len(node.name)
values = [] values = []
for node in MqttTempHumNodes: for node in TempHumNodes:
hash = node.hash() hash = node.hash()
if hash in values: if hash in values:
raise ValueError(f'collision detected: {hash}') raise ValueError(f'collision detected: {hash}')

View File

@ -0,0 +1,10 @@
[Unit]
Description=temperature and humidity sensor node
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/home/user/homekit/src/temphum_native_node.py --config /etc/temphum_node.toml
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,10 @@
[Unit]
Description=temperature and humidity sensor node
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/home/user/homekit/src/temphum_native_node.py --config /etc/temphum-node-%i.toml
[Install]
WantedBy=multi-user.target

View File

@ -1,10 +0,0 @@
[Unit]
Description=temperature and humidity daemon
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/home/user/homekit/src/temphumd.py --config /etc/temphumd.toml
[Install]
WantedBy=multi-user.target

View File

@ -1,10 +0,0 @@
[Unit]
Description=temperature and humidity daemon
After=network-online.target
[Service]
Restart=on-failure
ExecStart=/home/user/homekit/src/temphumd.py --config /etc/temphumd-%i.toml
[Install]
WantedBy=multi-user.target