from pyheatpump.db import DB, RowClass from datetime import datetime from .variable_type import VariableType from pyheatpump.logger import logger_init from pyheatpump.modbus import write_coil, write_holding_register logger = logger_init() class VariableValue(RowClass): type: VariableType = None address: int = None time: datetime = None value: int = None def __init__(self, **kwargs): if 'type' in kwargs.keys() and not isinstance(kwargs['type'], VariableType): kwargs['type'] = VariableType.get(kwargs['type']) super().__init__(**kwargs) def insert(self): try: old_value = VariableValue.get( self.type, self.address) if old_value.value == self.value: # last variable value is equal to current value # so do not insert return False except StopIteration: # variable value was never inserted pass try: params = self.__dict__.copy() params.update({'type': str(params['type'])}) DB.sql( """INSERT INTO var_value (type, address, value) VALUES (:type, :address, :value)""", params ) return True except Exception as e: logger.error('VariableValue.insert: %s', e) return False def get_value(self): return self.type.cast()(self.value) def equals(self, var_value): return self.get_value() == var_value.get_value() def set(self): if self.type == 'D': write_coil(self) else: write_holding_register(self) return self.insert() @staticmethod def get(var_type, address, time=datetime.now()): try: row = next(DB.sql( """SELECT * FROM var_value WHERE type = :type AND address = :address AND time <= :time ORDER BY time DESC LIMIT 1""", { 'type':str(var_type), 'address':address, 'time':int(time.strftime('%s'))+1 })) return VariableValue(**{ **dict(row), **{ 'type': var_type } }) except StopIteration as e: raise e