sprint1 refactor

This commit is contained in:
2024-01-14 15:59:35 +03:00
parent fe4ec551b5
commit 19da29b9b7
9 changed files with 99 additions and 51 deletions

View File

@@ -1,9 +1,10 @@
from src.config import test_config
from src.device import FakeInverter
from src.monitor import Monitor
def run_test_monitor(config: dict):
monitor = Monitor(session_config=config)
def demo_test():
monitor = Monitor(session_config=test_config)
device_conf = {
"name": "myinv",
"model": "12345",
@@ -12,8 +13,4 @@ def run_test_monitor(config: dict):
}
device = FakeInverter(**device_conf)
monitor.init_device(device)
monitor.demo_get_device_data_from_file()
if __name__ == "__main__":
pass
monitor.mainloop()

View File

@@ -2,4 +2,4 @@ from dotenv import dotenv_values
prod_config = dotenv_values("src/.env_prod")
test_config = dotenv_values("nts_ntu/.env_test")
test_config = dotenv_values("src/.env_test")

View File

@@ -24,13 +24,14 @@ class Device(ABC):
"""
@abstractmethod
def connect(self):
"""Реализуется физическое подключение к прибору, для сбора данных"""
def _connect_and_read(self) -> Any:
"""Реализуется физическое подключение к прибору, и считывание данных"""
raise NotImplementedError
@abstractmethod
def get_data(self) -> dict:
"""Реализует получение данных от прибора возвращает словарь.
"""Реализует получение данных "Монитором" от прибора.
Возвращает словарь.
Считанные данные привести к dict описанной ниже структуры:
dict_structure = {
"measurement": "<name>",
@@ -45,25 +46,30 @@ class Device(ABC):
<field_name>: str
<field_value>: str | int | float | bool
<measurement_time>: datetime
Функция должна вернуть созданный словарь
"""
raise NotImplementedError
class Inverter(Device):
def __init__(self, **kwargs) -> None:
self.name: str = kwargs.get("name", "fakeinvertor")
self.model: str = kwargs.get("model", "fakemodel")
self.location: str = kwargs.get("name", "fakelocation")
self.name: str = "Invertor"
self.model: str = "model"
self.location: str = "location"
self._raw_data: str
self.port: str = kwargs.get("name", "fakeCOMport")
self.port: str = "COM_port"
self.__dict__.update(kwargs)
def connect(self):
pass
def _connect_and_read(self) -> str:
"""Подключение к прибору
Реализует подключение к прибору и считывает поток данных
в виде строки.
Считанную строку сохранить в self._raw_data и вернуть
"""
return self._raw_data
def get_data(self, current_time: datetime = datetime.now()) -> dict:
def get_data(self, **kwargs) -> dict:
""""""
current_time = kwargs.get('current_time', datetime.now())
val_template = namedtuple(
"InvertorData",
[
@@ -71,7 +77,7 @@ class Inverter(Device):
"QQQ", # O/P load percent (Digital) 0, - 0%
"SS_S", # Battery voltage 12,24,48
"BBB", # Battery capacity (as O/P load percent)
"TT_T", # Heat Sink Temperature (0-99.9)
"TT_T", # Heat Sink Temperature (0-99.9)оо
"MMM", # Utility Power Voltage (0-250VACоооо)
"RR_R", # Output Power Frequency (40.0-70.0) Hz
"DDD", # DC BUS Voltage (0V)
@@ -80,8 +86,8 @@ class Inverter(Device):
],
)
raw = self._raw_data.strip().lstrip("(").rstrip(")").split()
print(raw)
if len(raw) != 10:
raise TypeError("неверный формат ответа")
values = val_template(*map(float, raw[:-1]), raw[-1])
answer: dict = {
"measurement": self.name,
@@ -89,6 +95,7 @@ class Inverter(Device):
"fields": values._asdict(),
"time": current_time,
}
print(answer)
return answer
@@ -97,14 +104,21 @@ class FakeInverter(Inverter):
super().__init__(**kwargs)
self.cur_datetime: datetime = datetime.now() - timedelta(hours=23)
self.delta: timedelta = timedelta(minutes=10)
self.line_counter = 0
def __getattribute__(self, __name: str) -> Any:
if __name == "cur_datetime":
self.__dict__["cur_datetime"] += self.delta
if __name == "_raw_data":
with open("telemetry.txt", mode="r") as f:
for _ in range(self.line_counter):
f.readline()
line = f.readline().strip()
self.__dict__["_raw_data"] = line
self.line_counter += 2
return super().__getattribute__(__name)
def set_fake_answer(self, line: str) -> None:
self._raw_data = line
def get_data(self, current_time: datetime = datetime.now()) -> dict:
return super().get_data(self.cur_datetime)
def get_data(self, **kwargs) -> dict:
return super().get_data(current_time=self.cur_datetime)

View File

@@ -11,36 +11,38 @@ class Monitor:
session_config: dict,
pooling_delay: int | float = 0.1,
) -> None:
"""
description
"""
self.device_list: List[Device] = []
self.session_config: dict = session_config
self.pooling_delay: int | float = pooling_delay
def init_device(self, device: Device) -> None:
self.device_list.append(device)
"""Инициализация конечного устройства для наблюдения"""
if isinstance(device, Device):
self.device_list.append(device)
else:
raise TypeError(
'Не могу инициализировать конечное устройство,\n' \
'init_device притимает только объекты-наследники класса Device'
)
def _get_device_data(self, device: Device) -> dict:
def __get_device_data(self, device: Device) -> dict:
"""Запрос данных от класса устройства
Нужно сделать валидацию структуры и параметры данных
"""
answer = device.get_data()
return answer
def __send_devices_data_to_db(self) -> None:
"""Сбор данных от всех устройств и отправка на сохранение"""
session = InfDBSession(config=self.session_config)
for device in self.device_list:
data: dict = self._get_device_data(device)
data: dict = self.__get_device_data(device)
session.add(data)
session.commit()
def mainloop(self) -> None:
"""Главный цикл монитора"""
while True:
self.__send_devices_data_to_db()
time.sleep(self.pooling_delay)
def demo_get_device_data_from_file(self):
with open("telemetry.txt", mode="r") as f:
for line in f.readlines():
line = line.strip()
if line:
self.device_list[0].set_fake_answer(line)
self.__send_devices_data_to_db()

View File

@@ -20,9 +20,7 @@ class InfDBSession:
self.__write_api = self.__client.write_api(write_options=SYNCHRONOUS)
def add(self, point: dict) -> None:
print(point)
self.__points_queue.append(Point.from_dict(point))
print(len(self.__points_queue))
def commit(self) -> None:
while self.__points_queue: