class SerialManager: serial = None settings = Settings.singleton() def __init__(self): self.serial = Serial(port=self.settings.serial_dev, baudrate=1200, parity=PARITY_NONE, stopbits=STOPBITS_ONE, bytesize=SEVENBITS, timeout=1) Logging.info("Teleinfo is reading on " + self.settings.serial_dev + "...") Logging.info("Search the beginning of the trame") self.search_beginning_trame() def search_beginning_trame(self): line = self.serial.readline() while b'\x02' not in line: # search the beginning trame character line = self.serial.readline() def read_line(self): return self.serial.readline().decode("utf-8") def close(self): self.serial.close() self.serial = None
from common.database.databasetype import DatabaseType from models.settings import Settings, Logging import sys if __name__ == '__main__': settings = Settings.singleton() if settings.service_already_running(): Logging.error("Service teleinfo is already running") sys.exit() open(settings.pidfile, 'w').write(settings.pid) try: Logging.info("Start Teleinfo application") settings.init_db(DatabaseType.SQLITE) # Creation of models import models from serial_teleinfo import teleinfo Logging.info("Check creation of tables") settings.database.init_tables() teleinfo.Teleinfo().run() finally: settings.dispose()
from models.settings import Settings from config.config import * global db """ Synchronize the local database (sqlite) with the remote database (mysql). """ if __name__ == '__main__': sqlite_db = SQLiteDatabaseManager() mysql_db = MySQLDatabaseManager() try: sqlite_db.init_db() mysql_db.init_db() Settings.singleton().database = mysql_db from models import models from models.settings import Logging max_id = mysql_db.db.session.query( mysql_db.db.func.max(models.Consumption.id)).scalar() Logging.info("max_id : " + str(max_id)) if max_id is None: max_id = 0 Settings.singleton().database = sqlite_db from models import models data_to_insert_query = sqlite_db.db.session.query( models.Consumption).filter(models.Consumption.id > max_id) nb_entry = data_to_insert_query.count() Logging.info("Synchronize " + str(nb_entry) + " values")
class Teleinfo: serial_manager = None settings = Settings.singleton() database = settings.database def run(self): try: nb_error = 0 self.serial_manager = SerialManager() # lecture de la première ligne de la première trame line = self.serial_manager.read_line() Logging.info("Reading data from teleinfo") consumption = None last_consumption = None while True: ar = line.split(" ") try: key = Keyword.value_of(ar[0]) if key is None: line = self.serial_manager.read_line() continue if key == Keyword.ADCO: # Begining of block if consumption is not None: if last_consumption is None or not last_consumption.has_same_indexes( consumption) or (consumption.datetime - last_consumption.datetime ).seconds > 30: self.database.commit_model(consumption) self.settings.remove_error_file() nb_error = 0 last_consumption = consumption consumption = models.Consumption() elif consumption is None: Logging.warning( "We search the beginning of first trame") line = self.serial_manager.read_line() continue if key.is_int_value(): value = int(ar[1]) else: value = ar[1] if key == Keyword.HCHP: consumption.index_hp = value elif key == Keyword.HCHC: consumption.index_hc = value elif key == Keyword.IINST: consumption.intensite_inst = value elif key == Keyword.PAPP: consumption.puissance_apparente = value elif key == Keyword.PTEC: if value == "HC..": consumption.periode = 2 except Exception as e: nb_error = nb_error + 1 if nb_error > 20: Logging.error("Too many error. Stop the service.") sys.exit() try: Logging.error("Exception no " + str(nb_error) + ": %s" % e) self.settings.create_error_file() self.settings.init_db() except Exception as e2: Logging.error("Exception : %s" % e2) line = self.serial_manager.read_line() finally: if self.serial_manager is not None: self.serial_manager.close()
import datetime from models.settings import Settings db = Settings.singleton().database.db class Consumption(db.Model): id = db.Column(db.Integer, primary_key=True) datetime = db.Column(db.DateTime) periode = db.Column(db.Integer, default=1) # 1 => HP, 2 => HC index_hp = db.Column(db.Integer) index_hc = db.Column(db.Integer) intensite_inst = db.Column(db.Integer) puissance_apparente = db.Column(db.Integer) def __init__(self, consumption=None): if consumption is None: self.datetime = datetime.datetime.utcnow() + datetime.timedelta( hours=2) else: # Copy constructor self.id = consumption.id self.datetime = consumption.datetime self.periode = consumption.periode self.index_hp = consumption.index_hp self.index_hc = consumption.index_hc self.intensite_inst = consumption.intensite_inst self.puissance_apparente = consumption.puissance_apparente def has_same_characteristics_as(self, other): return self.has_same_indexes(