Exemple #1
0
    def _connect(self):

        if not self._conn_attemts_timeout == None:
            # включен таймаут переподключения
            self._conn_attemts_timeout -= 1
            if self._conn_attemts_timeout >= 0:
                # если время не вышло то выходим
                return

        try:
            self._ser_thread = SerialReaderThread(self._com_port,
                                                  self._com_baudrate,
                                                  SerialLineReader)
            self._ser_thread.start()
            _, self._ser_reader = self._ser_thread.connect()

            self._connected = True
            self._conn_attemts_timeout = None

        except Exception as e:
            log.exception("can't connect to serial device")
            log.info("retrying after {} ticks.".format(СONN_ATTEMTS_TIMEOUT))
            self._connected = False
            self._conn_attemts_timeout = СONN_ATTEMTS_TIMEOUT
            self._callBack(ON_PROTOCOL_ERROR)
Exemple #2
0
    def storeData(self, accounts):
        start_time = clock()

        try:
            now_d = datetime.now()
            for acc in accounts:
                # цикл по ЛС
                for meter in accounts[acc]:
                    # цикл по счетчикам
                    data_s = "stored data: meter_id={}, count={}, updated={}".format(
                        meter["meter_id"], meter[DB_MTR_COUNT_NEW], now_d)
                    log.debug(data_s)
                    need_commit = True

            if need_commit:
                pass

        except Exception as e:
            self._db_error = True
            log.exception("can't update data into database")

        finally:
            pass

        log.debug("completed in {:g} sec.".format(clock() - start_time))
Exemple #3
0
 def _speak_error(self):
     # произносит стандратное сообщение об ошибке.
     self._set_state(State.READY_FOR_HANGOFF)
     try:
         #self._speaker.speakAndWait([self._error_message])
         self._begin_speaking([self._error_message])
     except Exception as e:
         log.exception("can't speak error sound sequence")
Exemple #4
0
    def storeData(self, accounts):
        start_time = clock()

        conn = self._db_connect()
        need_commit = False

        if not conn:
            self._db_error = True
            return

        cursor = conn.cursor(dictionary=True)

        # request_text = """UPDATE `meters`
        # SET `updated` = %(date)s,
        # `count` = %(count)s
        # WHERE `meters`.`id` = %(meter_id)s"""

        request_text = """INSERT INTO `meters_readings` 
        (`id`, `meter_id`, `count`, `updated`)
        VALUES (NULL, '%(meter_id)s', '%(count)s', %(date)s)"""

        try:
            now_d = datetime.now()
            for acc in accounts:
                # цикл по ЛС
                for meter in accounts[acc]:
                    # цикл по счетчикам
                    #if meter["__data_confirmed__"]:
                    cursor.execute(
                        request_text, {
                            'meter_id': meter["meter_id"],
                            'count': meter[DB_MTR_COUNT_NEW],
                            'date': now_d
                        })
                    log.debug("update row in 'meters' with id '{}'".format(
                        meter["meter_id"]))
                    need_commit = True

            if need_commit:
                conn.commit()

        except SQLError as e:
            self._db_error = True
            log.exception("can't update data into database")

        finally:
            cursor.close()
            conn.close()

        log.debug("completed in {:g} sec.".format(clock() - start_time))
Exemple #5
0
    def _sendCmd(self, cmd):
        try:
            # формирование команды устройству
            cmd_line = COMMANDS[cmd]["CMD"] + END_LINE
            # сброс таймаута и служебных полей
            self._set_cmd_timeout(CMD_TIMEOUT)
            self._set_last_cmd(cmd)
            # отправка команды
            self._ser_thread.write(cmd_line.encode())

        except Exception as e:
            log.exception("can't send command '{}' to device".format(cmd))
            self._callBack(ON_PROTOCOL_ERROR)

        # вызов события
        self._callBack(ON_CMD_SENT, cmd=cmd)
Exemple #6
0
    def fetchCallerInfo(self, caller_number):
        start_time = clock()

        accounts = {}
        pers_gr = ""

        try:

            for item in self._data:
                if not item["phone_number"] == caller_number:
                    continue
                acc = item["account"]

                if not acc in accounts:
                    accounts[acc] = []

                mtr = item.copy()
                # поле для новых показаний
                mtr[DB_MTR_COUNT_NEW] = mtr[DB_MTR_COUNT]
                accounts[acc].append(mtr)
                pers_gr = mtr[DB_PERSONAL_GREATING]

        except Exception as e:
            self._db_error = True
            log.exception("can't fetch data from database")

        finally:
            pass

        # определение функции для извлечения ключа сортировки
        def sf(item):
            return item[DB_MTR_INDEX]

        # сортировка по номеру в УС
        for acc in accounts:
            accounts[acc].sort(key=sf)

        log.debug("completed in {:g} sec.".format(clock() - start_time))
        log.debug("collected accounts : {}".format(list(accounts.keys())))

        return (accounts, pers_gr)
Exemple #7
0
 def _begin_speaking(self, sound, critical = True):
     if not isinstance(sound, list) and not isinstance(sound, tuple):
         snd = [sound]
     else:
         snd = []
         for item in sound:
             if item:
                 if isinstance(item, list) or isinstance(item, tuple):
                     snd += list(item)
                 else:
                     snd.append(item)
         
     try:
         self._speaker.speak(snd)
         self._speaking = True
     except Exception as e:
         log.exception("can't speak sound sequence '{}'.".format(snd))
         if critical:
             log.error("end the call due to an exception while speaking critical sound sequence")
             self._set_state(State.READY_FOR_HANGOFF)
         return False
     return True
Exemple #8
0
    def _db_connect(self):
        conn = None

        if not sql.paramstyle == 'pyformat':
            log.error('sql paramstyle = "{}" not supported.'.format(
                sql.paramstyle))
            return conn

        tryes = 3
        while tryes > 0:
            try:
                conn = sql.connect(host=self._db_host,
                                   port=self._db_port,
                                   database=self._db_database,
                                   user=self._db_user,
                                   password=self._db_password)

                tryes = 0

            except SQLError as e:
                tryes -= 1
                log.exception("can't connect to database server")

        return conn
Exemple #9
0
    def fetchCallerInfo(self, caller_number):
        start_time = clock()

        conn = self._db_connect()

        accounts = {}
        pers_gr = ""

        if not conn:
            self._db_error = True
            return (accounts, pers_gr)

        cursor = conn.cursor(dictionary=True)
        request_text = """SELECT 
            `clients`.`id` AS `client_id`,
            `clients`.`account`,
            `clients`.`phone_number`,
            `clients`.`registration_date`,
            `meters`.`id` AS `meter_id`,
            `meters`.`index_num`,
            `meters`.`updated`,
            `meters`.`count`,
            `pers_set`.`greeting_f`
            FROM `clients` 
            INNER JOIN `meters` ON `meters`.`owner_id` = `clients`.`id` AND `clients`.`phone_number`=%(phone)s
            LEFT JOIN `pers_set` ON `pers_set`.`phone_number`=%(phone)s"""

        try:
            cursor.execute(request_text, {'phone': caller_number})

            for item in cursor.fetchall():
                acc = item["account"]

                if not acc in accounts:
                    accounts[acc] = []

                mtr = item.copy()
                # поле для новых показаний
                mtr[DB_MTR_COUNT_NEW] = mtr[DB_MTR_COUNT]
                accounts[acc].append(mtr)
                pers_gr = item[DB_PERSONAL_GREATING]

        except SQLError as e:
            self._db_error = True
            log.exception("can't fetch data from database")

        finally:
            cursor.close()
            conn.close()

        # определение функции для извлечения ключа сортировки
        def sf(item):
            return item[DB_MTR_INDEX]

        # сортировка по номеру в УС
        for acc in accounts:
            accounts[acc].sort(key=sf)

        log.debug("completed in {:g} sec.".format(clock() - start_time))
        log.debug("collected accounts : {}".format(list(accounts.keys())))
        return (accounts, pers_gr)
Exemple #10
0
    def _process_message(self, msg):
        head, args = self._parse_msg(msg)
        # получаем имя последней отправленной команды
        lc = self._get_last_cmd()
        if lc:
            # была отправлена команда - ожидаемо что это результат ее выполнения
            if COMMANDS[lc]["CMD"] == msg:
                # включен режим эхо. устройство отправляет полученную команду обратно перед отправкой ответа
                pass

            elif head in COMMANDS[lc]["RESULT"].values():
                # результат выполнения команды
                is_ok = (head == COMMANDS[lc]["RESULT"]["SUCCESS"])
                # обработка последовательностей команд
                self._add_cmd_seq_result(is_ok)
                # вызываем событие при этом забываем последнюю команду
                self._callBack(ON_CMD_RESULT,
                               cmd=self._get_last_cmd(True),
                               result=is_ok,
                               test_result=self._get_last_test_result(True))

            elif "RESPONSE" in COMMANDS[lc] and head == COMMANDS[lc][
                    "RESPONSE"]["HEAD"]:
                # команда возращает ответ
                try:
                    self._set_last_test_result(
                        args[COMMANDS[lc]["RESPONSE"]["PARAMS"].index(
                            COMMANDS[lc]["TEST"]["PARAM"])] in COMMANDS[lc]
                        ["TEST"]["VALUE"])
                except IndexError as e:
                    #raise Exception("unexpected params count returned by command {}".format(lc))
                    log.exception(
                        "unexpected params count returned by command {}".
                        format(lc))
                    self._callBack(ON_PROTOCOL_ERROR)

            else:
                # вернулась какая то дичь
                # обработка последовательностей команд
                if self._is_cmd_seq():
                    self._cmd_seq_end(False)
                #raise Exception("unexpected result of command {}".format(lc))
                log.error("unexpected result '{}' of command {}".format(
                    msg, lc))
                self._callBack(ON_PROTOCOL_ERROR)
        else:
            # не было команды устройству - незатребованный результат
            if head == MSG_END_CALL:
                # завершение вызова на той стороне
                self._callBack(ON_END_CALL)
            elif head == MSG_INCOMING_CALL:
                # входящий вызов
                self._callBack(ON_INCOMING_CALL)
            elif head == MSG_CLIP_INFO:
                # входящий вызов
                self._callBack(ON_CALLER_NUMBER_RECIEVED, number=args[0])
            elif head == MSG_DTMF_RECIEVED:
                # получен символ
                self._callBack(ON_DTMF_RECIEVED, symbol=args[0])
            else:
                self._callBack(ON_UNKNOWN_MSG, message=msg)