Teleinfo déporté debian 12

Bonsoir

Je viens de passer le RPI sur lequel est rattaché le modem cartelectronic 2cpt en Debian V12.
Lors de l installation du daemon comme indiqué dans la doc, j obtiens un « forbidden » en réponse aux wget, avec ou sans sudo. J ai donc installé ces 4 fichiers à la main des /root/teleinfo/ et /root/teleinfo/jeedom/.
Lors du lancement du daemon, le log me signale l absence du module « fdti1 ».
J ai donc essayé d installer ces dépendances inspiré du fichier « install_apt.sh » comme indiqué dans la doc.
C est là que ça se complique : il me demande la création d un environnement virtuel, ce que j ai fait, mais me refuse toutes les commandes de ce fichier d install.
Quelles sont les dépendances à installer , où et comment?

Pi3B+
Bookworm 32bits

Merci de votre aide

JMM

Salut, c’est une partie du plugin que je n’ai jamais explorée. Les dépendances à installer sont dans le fichier équipement.txt de la version bêta (désolé je n’arrive pas à copier sur mon téléphone, je t’ai fait une copie d’écran :

Bonjour

Merci pour cette réponse rapide.

Après install des dépendances ci dessus, j obtiens cette erreur :

Error: importing module from jeedom folder
No module named ‹ MySQLdb ›

qui à priori viens de la ligne 63 du fichier teleinfo_2_cpt.py, qui va le chercher dans le fichier jeedom.py.
Faut il charger cette dépendance ?

Merci d avance

JMM

Je n’ai pas trop la possibilité de regarder mais il me semble que pour teleinfo tu n’as pas besoin de MySQL. Si cela ne te crée pas d’erreur alors tu dois pouvoir supprimer l’import du module dans le fichier jeedom.py. Sinon tu peux aussi installer ce module

Re bonjour

La dévalidation de MySqlDb a suffit.
Maintenant, il démarre, mais jai cette erreur

[2024-11-01 12:52:45][INFO] : GLOBAL------Start teleinfod
[2024-11-01 12:52:45][INFO] : GLOBAL------Cycle Sommeil : 30.0
[2024-11-01 12:52:45][INFO] : GLOBAL------Socket port : 55062
[2024-11-01 12:52:45][INFO] : GLOBAL------Socket host : 192.168.20.173
[2024-11-01 12:52:45][INFO] : GLOBAL------Log level : debug
[2024-11-01 12:52:45][INFO] : GLOBAL------Callback : http://192.168.20.190/plugins/teleinfo/core/php/jeeTeleinfo.php
[2024-11-01 12:52:45][INFO] : GLOBAL------Vitesse : 1200
[2024-11-01 12:52:45][INFO] : GLOBAL------Apikey : VytD2R7hyraVeRsU5gStuYjwnOYa2sWX2340iUtv6CBphpwB8dhmTPlb7JAwLKfk
[2024-11-01 12:52:45][INFO] : GLOBAL------Cycle : 1.0
[2024-11-01 12:52:45][INFO] : GLOBAL------Port : /dev/ttyUSB0
[2024-11-01 12:52:45][INFO] : GLOBAL------Mode : historique
[2024-11-01 12:52:45][DEBUG] : Writing PID- 2454 to /tmp/teleinfo2cpt.pid
[2024-11-01 12:52:45][DEBUG] : Init request module v2.32.3
[2024-11-01 12:52:45][DEBUG] : Starting new HTTP connection (1): 192.168.20.190:80
[2024-11-01 12:52:45][DEBUG] : http://192.168.20.190:80 "GET /plugins/teleinfo/core/php/jeeTeleinfo.php?apikey=VytD2R7hyraVeRsU5gStuYjwnOYa2sWX2340iUtv6CBphpwB8dhmTPlb7JAwLKfk HTTP/11" 200 0
[2024-11-01 12:52:45][DEBUG] : Socket interface started
[2024-11-01 12:52:45][DEBUG] : LoopNetServer Thread started
[2024-11-01 12:52:45][INFO] : GLOBAL------Start listening...
[2024-11-01 12:52:45][DEBUG] : Listening on: [192.168.20.173:55062]
[2024-11-01 12:52:45][INFO] : GLOBAL------Preparing Teleinfo...
[2024-11-01 12:52:45][DEBUG] : GLOBAL------Read Socket Thread Launched
[2024-11-01 12:52:45][INFO] : TELEINFO------Initialisation de la teleinfo
[2024-11-01 12:52:45][INFO] : TELEINFO------FTDI TYPE : 1
[2024-11-01 12:52:45][DEBUG] : Lecture des donnees
[2024-11-01 12:52:45][DEBUG] : GLOBAL------Shutdown
[2024-11-01 12:52:45][DEBUG] : Shutdown
[2024-11-01 12:52:45][DEBUG] : Removing PID file /tmp/teleinfo2cpt.pid
[2024-11-01 12:52:46][DEBUG] : LoopNetServer Thread stopped
[2024-11-01 12:52:46][DEBUG] : Exit 0
Error:
argument 2: TypeError: wrong type

Est ce type FTDI TYPE : 1 qui est faux ?

JMM

Ça va être compliqué pour moi car je ne suis pas à la maison. Je vais tenter de regarder avec mon téléphone mais c’est pas gagné. Pour le type ftdi c’est juste une info pour dire quel est le module qui est utilisé

Tu as quelle version de python sur la machine où teleinfo.py tourne?

Tu lances teleinfo.py avec quelle commande ?

Version python : 3.11

cde: sudo /home/jmm/venvteleinfo/bin/python /root/teleinfo/teleinfo_2_cpt.py --port /dev/ttyUSB0 --apikey VytD2R7hyraVeRsU5gStuYjwnOYa2sWX2340iUtv6CBphpwB8dhmTPlb7JAwLKfk --callback http://192.168.20.190/plugins/teleinfo/core/php/jeeTeleinfo.php --loglevel debug --cyclesommeil 30 --sockethost 192.168.20.173 >> /tmp/teleinfo.log 2>&1

Ah c’est un modem 2 compteurs?

Ta teleinfo est historique ou standard ?

historique

C’est bien un modèle 2 compteurs ? Tu as pris le fichier python sur quelle version du plugin?

Désolé pour le retard

Plugin version 2024-08-27 08:04:00
core : 4.8.7
cest celui la

#!/usr/bin/python3
#coding: utf-8

""" Teleinfo reader

License
=======

teleinfo_2_cpt.py is Copyright:
- (C) 2010-2012 Samuel <samuel DOT buffet AT gmail DOT com>
- (C) 2012-2017 Frédéric <fma38 AT gbiloba DOT org>
- (C) 2017 Samuel <samuel DOT buffet AT gmail DOT com>
- (C) 2015-2018 Cédric Guiné <cedric DOT guine AT gmail DOT com>

This software is governed by the CeCILL license under French law and
abiding by the rules of distribution of free software.  You can  use,
modify and/or redistribute the software under the terms of the CeCILL
license as circulated by CEA, CNRS and INRIA at the following URL
http://www.cecill.info.

As a counterpart to the access to the source code and  rights to copy,
modify and redistribute granted by the license, users are provided only
with a limited warranty  and the software's author,  the holder of the
economic rights,  and the successive licensors  have only  limited
liability.

In this respect, the user's attention is drawn to the risks associated
with loading,  using,  modifying and/or developing or reproducing the
software by the user in light of its specific status of free software,
that may mean  that it is complicated to manipulate,  and  that  also
therefore means  that it is reserved for developers  and  experienced
professionals having in-depth computer knowledge. Users are therefore
encouraged to load and test the software's suitability as regards their
requirements in conditions enabling the security of their systems and/or
data to be ensured and,  more generally, to use and operate it in the
same conditions as regards security.

The fact that you are presently reading this means that you have had
knowledge of the CeCILL license and that you accept its terms.
"""

import time
import optparse
#import urllib2
import sys
import os
import traceback
import logging
import signal
import globals
import argparse
import _thread
import json
try:
    import ftdi
    ftdi_type = 0
except ImportError:
    import ftdi1 as ftdi
    ftdi_type = 1
    #raise ImportError('Erreur de librairie ftdi')
try:
    from jeedom.jeedom import *
except ImportError as ex:
    print("Error: importing module from jeedom folder")
    print(ex)
    sys.exit(1)
# USB settings
usb_vendor = 0x0403
usb_product = 0x6001
usb_port = [0x00, 0x11, 0x22]
baud_rate = 1200

# Misc
stx = 0x02  # start of text
etx = 0x03  # end of text
eot = 0x04  # end of transmission

# Datas
global_external_ip = ''
global_cle_api = ''
global_debug = ''
global_real_path = ''

class FtdiError(Exception):
    """ Ftdi related errors
    """


class Ftdi(object):
    """ Class for handling ftdi communication
    """
    def __init__(self):
        """
        """
        logging.info("Try to open Teleinfo modem")
        super(Ftdi, self).__init__()
        self.__ftdic = None

    def init(self):
        """ Init ftdi com.
        """
        # Create ftdi context
        logging.info("Try to Create ftdi context")
        self.__ftdic = ftdi.ftdi_context()
        if self.__ftdic is None:
            logging.error("Can't create ftdi context")
            raise FtdiError("Can't create ftdi context")

        # Init ftdi context
        err = ftdi.ftdi_init(self.__ftdic)
        if err < 0:
            logging.error("Can't init ftdi context (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't init ftdi context (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        # Open port
        logging.info("Try to open ftdi port")
        err = ftdi.ftdi_usb_open(self.__ftdic, usb_vendor, usb_product)
        if err < 0:
            logging.error("Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        err = ftdi.ftdi_set_baudrate(self.__ftdic, baud_rate)
        if err < 0:
            logging.error("Can't set baudrate (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't set baudrate (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        # Because of the usb interface, must use 8 bits transmission data, instead of 7 bits
        err = ftdi.ftdi_set_line_property(self.__ftdic, ftdi.BITS_8, ftdi.EVEN, ftdi.STOP_BIT_1)
        if err < 0:
            logging.error("Can't set line property (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't set line property (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

    def shutdown(self):
        """ Shutdown ftdi com.
        """
        logging.info("Try to close ftdi port")
        err = ftdi.ftdi_usb_close(self.__ftdic)
        if err < 0:
            logging.error("Can't close ftdi com. (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't close ftdi com. (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        ftdi.ftdi_deinit(self.__ftdic)

    def selectPort(self, port):
        """ Select the giver port
        """
        err = ftdi.ftdi_set_bitmode(self.__ftdic, port, ftdi.BITMODE_CBUS)
        if err < 0:
            logging.error("Can't set bitmode (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't set bitmode (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
        time.sleep(0.1)

    def purgeBuffers(self):
        """ Purge ftdi buffers
        """
        err = ftdi.ftdi_usb_purge_buffers(self.__ftdic)
        if err < 0:
            logging.error("Can't purge buffers (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            raise FtdiError("Can't purge buffers (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

    def readOne(self):
        """ read 1 char from usb
        """
        buf = ' '
        err = ftdi.ftdi_read_data(self.__ftdic, buf, 1)
        if err < 0:
            logging.error("Can't read data (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            self.shutdown()
            raise FtdiError("Can't read data (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
        if err:
            c_error = unichr(ord(buf) % 0x80)  # Clear bit 7
            return c_error
        else:
            return None

    def read(self, size):
        """ read several chars
        """

        # Purge buffers
        self.purgeBuffers()

        raw = u""
        while len(raw) < globals.frame_length:
            c = self.readOne()
            if c is not None and c != '\x00':
                raw += c

        return raw

class Teleinfo(object):
    import globals
    """ Class for handling teleinfo stuff
    """
    def __init__(self, ftdi_):
        """
        """
        logging.info("TELEINFO------Initialisation de la teleinfo")
        logging.info("TELEINFO------FTDI TYPE : " + str(ftdi_type))
        if ftdi_type == 0:
            globals.ftdi_context = ""
            super(Teleinfo, self).__init__()
            self.__ftdi = ftdi_
        else:
            globals.ftdi_context = ftdi.new()
            ret = ftdi.usb_open(globals.ftdi_context, 0x0403, 0x6001)
            if ret < 0:
                logging.error("Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))
            ftdi.set_baudrate(globals.ftdi_context, int(globals.vitesse))
        if globals.mode == "historique":
            globals.frame_length = 500
            #ftdi.set_line_property(globals.ftdi_context, ftdi.BITS_8, ftdi.EVEN, ftdi.STOP_BIT_1)

    def __selectMeter(self, num):
        """ Select giver meter
        """
        if ftdi_type == 0:
            self.__ftdi.selectPort(usb_port[num])
        else:
            err = ftdi.set_bitmode(globals.ftdi_context, usb_port[num], ftdi.BITMODE_CBUS)
            if err < 0:
                logging.error("Can't set bitmode (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
                raise FtdiError("Can't set bitmode (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
            time.sleep(0.1)

    def __readOne(self):
        """ read 1 char from usb
        """
        err, buf = ftdi.read_data(globals.ftdi_context, 0x1)
        if err < 0:
            logging.error("Can't read data (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
            self.close()
            raise FtdiError("Can't read data (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
        if err:
            #c = unichr(ord(buf) % 0x80)  # Clear bit 7
            c = chr(ord(buf) & 0x07f)
            return err, c
        else:
            return err, None

    def __readRawFrame(self):
        """ Read raw frame
        """
        # As the data are sent asynchronously by the USB interface, we probably don't start
        # to read at the start of a frame. So, we read enough chars to retreive a complete frame
        logging.debug("Lecture des donnees")
        if ftdi_type == 0:
            raw = self.__ftdi.read(globals.frame_length)
        else:
            err = ftdi.usb_purge_buffers(globals.ftdi_context)
            if err < 0:
                logging.error("Can't purge buffers (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
                raise FtdiError("Can't purge buffers (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))
            raw = u""
            while len(raw) < globals.frame_length:
                err, c = self.__readOne()
                if c is not None and c != '\x00':
                    raw += c
                    #logging.debug(c)
        return raw

    def __frameToDatas(self, frame):
        """ Split frame in datas
        """
        #essai indent
        Content = {}
        lines = frame.split('\r')
        for line in lines:
            try:
                checksum = line[-1]
                #logging.debug('chechsum : ' + checksum)
                header, value = line[:-2].split()
                #data = {'header': header.encode(), 'value': value.encode(), 'checksum': checksum}
                #logging.debug('TELEINFO------name : ' + header.encode() + ' value : ' + value.encode() + ' checksum : ' + checksum)
                logging.debug('TELEINFO------name : ' + header + ' value : ' + value + ' chechsum : ' + checksum)
                if self.__checkData(line):
                    #logging.debug('retour vrai du checksum')
                    #Content[header.encode()] = value.encode()
                    Content[header] = value
                    #logging.debug('retour 2 ')
            except:
                pass
                #datas.append(data)
        return Content

    def __checkData(self, data):
        """ Check if data is ok (checksum)
        """
        if globals.mode == "standard":
            #Gestion des champs horodates
            #logging.debug('calcul du checksum 1')
            if len(data.split('\x09')) == 4:
                datas = '\x09'.join(data.split('\x09')[0:3])
                #logging.debug('calcul du checksum 2' + datas)
            else:
                datas = '\x09'.join(data.split('\x09')[0:2])
                #logging.debug('calcul du checksum 3' + datas)
            my_sum = 0
            for cks in datas:
                my_sum = my_sum + ord(cks)
            #logging.debug('my_sum : ' + str(my_sum))
            computed_checksum = ((my_sum - 0x01) & int("111111", 2)) + 0x20
            #computed_checksum = ((my_sum + 0x09) & int("111111", 2)) + 0x20
            #logging.debug('computed checksum : ' + chr(computed_checksum) + ' compare a checksum : ' + data[-1])
        else:
            #print "Check checksum : f = %s, chk = %s" % (frame, checksum)
            datas = ' '.join(data.split()[0:2])
            my_sum = 0
            for cks in datas:
                my_sum = my_sum + ord(cks)
            computed_checksum = (my_sum & int("111111", 2)) + 0x20
            #print "computed_checksum = %s" % chr(computed_checksum)
        return chr(computed_checksum) == data[-1]

    def extractDatas(self, raw):
        """ Extract datas from raw frame
        """
        end = raw.rfind(chr(etx)) + 1
        start = raw[:end].rfind(chr(etx)+chr(stx))
        frame = raw[start+2:end-2]
        #logging.debug('end : ' + str(end) + ' start : ' + str(start) + ' frame : ' + frame)

        # Check if there is a eot, cancel frame
        if frame.find(chr(eot)) != -1:
            return {'Message':'eot'}
            #raise TeleinfoError("eot found")

        # Convert frame back to ERDF standard
        #frame = frame.replace('\n', '')     # Remove new line

        # Extract data
        datas = self.__frameToDatas(frame)

        return datas

    def readMeter(self):
        """ Read raw frame for giver meter
        """
        num_compteur = 1
        cpt1_data = {}
        cpt2_data = {}
        cpt1_data_temp = {}
        cpt2_data_temp = {}
        raz_time = 600
        separateur = " "
        send_data = {}
        #for cle, valeur in Donnees.items():
        #            Donnees.pop(cle)
        #            _Donnees.pop(cle)
        while(1):
            if raz_time > 1:
                raz_time = raz_time - 1
            else:
                logging.info("TELEINFO------HEARTBEAT")
                raz_time = 600
                for cle, valeur in list(cpt1_data.items()):
                    cpt1_data.pop(cle)
                    cpt1_data_temp.pop(cle)
                for cle, valeur in list(cpt2_data.items()):
                    cpt2_data.pop(cle)
                    cpt2_data_temp.pop(cle)
            send_data = {}
            self.__selectMeter(num_compteur)
            raw = self.__readRawFrame()
            self.__selectMeter(0)
            datas = self.extractDatas(raw)
            #logging.debug(raw)

            if num_compteur == 1:
                for cle, valeur in datas.items():
                    if cle == 'PTEC':
                        valeur = valeur.replace(".", "")
                        valeur = valeur.replace(")", "")
                        cpt1_data[cle] = valeur
                    else:
                        cpt1_data[cle] = valeur
                        logging.debug('cle : ' + cle + ' valeur : ' + valeur)
            elif num_compteur == 2:
                for cle, valeur in datas.items():
                    if cle == 'PTEC':
                        valeur = valeur.replace(".", "")
                        valeur = valeur.replace(")", "")
                        cpt2_data[cle] = valeur
                    else:
                        cpt2_data[cle] = valeur
            PENDING_CHANGES = False
            if num_compteur == 1:
                for cle, valeur in cpt1_data.items():
                    if cle in cpt1_data_temp:
                        if cpt1_data[cle] != cpt1_data_temp[cle]:
                            send_data[cle] = valeur
                            cpt1_data_temp[cle] = valeur
                            PENDING_CHANGES = True
                    else:
                        send_data[cle] = valeur
                        cpt1_data_temp[cle] = valeur
                        PENDING_CHANGES = True
            elif num_compteur == 2:
                for cle, valeur in cpt2_data.items():
                    if cle in cpt2_data_temp:
                        if cpt2_data[cle] != cpt2_data_temp[cle]:
                            send_data[cle] = valeur
                            cpt2_data_temp[cle] = valeur
                            PENDING_CHANGES = True
                    else:
                        send_data[cle] = valeur
                        cpt2_data_temp[cle] = valeur
                        PENDING_CHANGES = True
            try:
                if PENDING_CHANGES :
                    if num_compteur == 1:
                        globals.JEEDOM_COM.ecritmysql(cpt1_data)
                        logging.debug('Ecrit teleinfo')
                        globals.JEEDOM_COM.ecritteleinf(cpt1_data)
                        
                        if globals.mode == "standard": # Zone linky standard
                            if not cpt1_data_temp["ADSC"] == '':
                                send_data["device"] = cpt1_data_temp["ADSC"]
                                globals.JEEDOM_COM.add_changes('device::'+cpt1_data_temp["ADSC"],send_data)
                        else:
                            if not cpt1_data_temp["ADCO"] == '':
                                send_data["device"] = cpt1_data_temp["ADCO"]
                                globals.JEEDOM_COM.add_changes('device::'+cpt1_data_temp["ADCO"],send_data)
                    elif num_compteur == 2:
                        globals.JEEDOM_COM.ecritmysql(cpt2_data)
                        globals.JEEDOM_COM.ecritteleinf(cpt2_data)
                        if globals.mode == "standard": # Zone linky standard
                            if not cpt2_data_temp["ADSC"] == '':
                                send_data["device"] = cpt2_data_temp["ADSC"]
                                globals.JEEDOM_COM.add_changes('device::'+cpt2_data_temp["ADSC"],send_data)
                        else:
                            if not cpt2_data_temp["ADCO"] == '':
                                send_data["device"] = cpt2_data_temp["ADCO"]
                                globals.JEEDOM_COM.add_changes('device::'+cpt2_data_temp["ADCO"],send_data)
            except Exception as err:
                errorCom = "Connection error"
                logging.error(errorCom,f"Unexpected {err=}, {type(err)=}")
            #logging.debug("TELEINFO------START SLEEPING " + str(globals.cycle_sommeil) + " seconds")
            
            time.sleep(globals.cycle_sommeil)
            #logging.debug("TELEINFO------WAITING : " + str(globals.TELEINFO_SERIAL.inWaiting()) + " octets dans la file apres sleep ")
            #if globals.TELEINFO_SERIAL.inWaiting() > 1500:
            #    globals.TELEINFO_SERIAL.flushInput()
            #    logging.info("TELEINFO------BUFFER OVERFLOW => FLUSH")
            #    logging.debug(str(globals.TELEINFO_SERIAL.inWaiting()) + "octets dans la file apres flush ")
            if num_compteur == 1:
                num_compteur = 2
            else:
                num_compteur = 1
        self.terminate()

    def exit_handler(self, *args):
        self.terminate()
        logging.info("[exit_handler]")

    def close(self):
        if ftdi_type == 0:
            self.__ftdi.shutdown()
        else:
            ftdi.close()

    def terminate(self):
        print ("Terminating...")
        self.close()
        #sys.close(gOutput)
        #sys.exit()

def read_socket(cycle):
    while True :
        try:
            global JEEDOM_SOCKET_MESSAGE
            if not JEEDOM_SOCKET_MESSAGE.empty():
                logging.debug("SOCKET-READ------Message received in socket JEEDOM_SOCKET_MESSAGE")
                message = json.loads(JEEDOM_SOCKET_MESSAGE.get())
                if message['apikey'] != globals.apikey:
                    logging.error("SOCKET-READ------Invalid apikey from socket : " + str(message))
                    return
                logging.debug('SOCKET-READ------Received command from jeedom : '+str(message['cmd']))
                if message['cmd'] == 'action':
                    logging.debug('SOCKET-READ------Attempt an action on a device')
                    _thread.start_new_thread( action_handler, (message,))
                    logging.debug('SOCKET-READ------Action Thread Launched')
                elif message['cmd'] == 'logdebug':
                    logging.info('SOCKET-READ------Passage du demon en mode debug force')
                    log = logging.getLogger()
                    for hdlr in log.handlers[:]:
                        log.removeHandler(hdlr)
                    jeedom_utils.set_log_level('debug')
                    logging.debug('SOCKET-READ------<----- La preuve ;)')
                elif message['cmd'] == 'lognormal':
                    logging.info('SOCKET-READ------Passage du demon en mode de log normal')
                    log = logging.getLogger()
                    for hdlr in log.handlers[:]:
                        log.removeHandler(hdlr)
                    jeedom_utils.set_log_level('info')
        except Exception as e:
            logging.error("SOCKET-READ------Exception on socket : %s" % str(e))
            logging.debug(traceback.format_exc())
        time.sleep(cycle)

def listen():
    globals.PENDING_ACTION=False
    jeedom_socket.open()
    logging.info("GLOBAL------Start listening...")
    #globals.TELEINFO = Teleinfo()
    logging.info("GLOBAL------Preparing Teleinfo...")
    _thread.start_new_thread( read_socket, (globals.cycle,))
    logging.debug('GLOBAL------Read Socket Thread Launched')
    while 1:
        try:
            if ftdi_type == 0:
                ftdi_ = Ftdi()
                ftdi_.init()
                globals.TELEINFO = Teleinfo(ftdi_)
            else:
                globals.TELEINFO = Teleinfo("")
            _thread.start_new_thread( log_starting,(globals.cycle,))
            globals.TELEINFO.readMeter()
        except Exception as e:
            print("Error:")
            print(e)
            shutdown()

def log_starting(cycle):
	time.sleep(30)
	logging.info('GLOBAL------Passage des logs en normal')
	log = logging.getLogger()
	for hdlr in log.handlers[:]:
		log.removeHandler(hdlr)
	jeedom_utils.set_log_level('error')

def handler(signum=None, frame=None):
    logging.debug("Signal %i caught, exiting..." % int(signum))
    shutdown()

def shutdown():
    logging.debug("GLOBAL------Shutdown")
    #if ftdi_type == 0:
        #ftdi_.shutdown()
    #globals.TELEINFO.close()
    logging.debug("Shutdown")
    logging.debug("Removing PID file " + str(globals.pidfile))
    try:
        os.remove(globals.pidfile)
    except:
        pass
    try:
        jeedom_socket.close()
    except:
        pass
    logging.debug("Exit 0")
    sys.stdout.flush()
    os._exit(0)
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------

globals.log_level = "info"
globals.socketport = 55062
globals.sockethost = '127.0.0.1'
globals.apikey = ''
globals.callback = ''
globals.cycle = 1;

parser = argparse.ArgumentParser(description='Teleinfo Daemon for Jeedom plugin')
parser.add_argument("--apikey", help="Value to write", type=str)
parser.add_argument("--loglevel", help="Log Level for the daemon", type=str)
parser.add_argument("--callback", help="Value to write", type=str)
parser.add_argument("--socketport", help="Socket Port", type=str)
parser.add_argument("--sockethost", help="Socket Host", type=str)
parser.add_argument("--cycle", help="Cycle to send event", type=str)
parser.add_argument("--port", help="Port du modem", type=str)
parser.add_argument("--vitesse", help="Vitesse du modem", type=str)
parser.add_argument("--mode", help="Model mode", type=str)
parser.add_argument("--cyclesommeil", help="Wait time between 2 readline", type=str)
args = parser.parse_args()

if args.apikey:
    globals.apikey = args.apikey
if args.loglevel:
    globals.log_level = args.loglevel
if args.callback:
    globals.callback = args.callback
if args.socketport:
    globals.socketport = args.socketport
if args.sockethost:
    globals.sockethost = args.sockethost
if args.cycle:
    globals.cycle = float(args.cycle)
if args.port:
    globals.port = args.port
if args.vitesse:
    globals.vitesse = args.vitesse
if args.mode:
    globals.mode = args.mode
if args.cyclesommeil:
    globals.cycle_sommeil = float(args.cyclesommeil)

globals.socketport = int(globals.socketport)
globals.cycle = float(globals.cycle)

jeedom_utils.set_log_level(globals.log_level)
logging.info('GLOBAL------Start teleinfod')
logging.info('GLOBAL------Cycle Sommeil : '+str(globals.cycle_sommeil))
logging.info('GLOBAL------Socket port : '+str(globals.socketport))
logging.info('GLOBAL------Socket host : '+str(globals.sockethost))
logging.info('GLOBAL------Log level : '+str(globals.log_level))
logging.info('GLOBAL------Callback : '+str(globals.callback))
logging.info('GLOBAL------Vitesse : '+str(globals.vitesse))
logging.info('GLOBAL------Apikey : '+str(globals.apikey))
logging.info('GLOBAL------Cycle : '+str(globals.cycle))
logging.info('GLOBAL------Port : '+str(globals.port))
logging.info('GLOBAL------Mode : '+str(globals.mode))

signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
globals.pidfile = "/tmp/teleinfo2cpt.pid"
jeedom_utils.write_pid(str(globals.pidfile))
globals.JEEDOM_COM = jeedom_com(apikey = globals.apikey,url = globals.callback,cycle=globals.cycle)
if not globals.JEEDOM_COM.test():
    logging.error('GLOBAL------Network communication issues. Please fix your Jeedom network configuration.')
    shutdown()
jeedom_socket = jeedom_socket(port=globals.socketport,address=globals.sockethost)
listen()
sys.exit()

Excuse moi mais je te reposé pour la 3eme fois la même question : est ce que tu as bien un modem cartelectronic 2 compteurs ?

Bonjour

Oui c est bien un 2 compteurs

Tu as un pb de type de données mais je n’arrive pas à localiser le pb. C’est soit dans __readRawFrame soit dans extractDatas

Je vais t’envoyer un nouveau fichier avec plus de traces log mais je ne pourrais pas avant au moins demain soir, ça te va?

Une petite question : as tu modifié le fichier original car il y a qq log qui ne correspondent pas à la version que j’ai?

Bonsoir

Pas de pb pour le délai.
Le fichier n a pas été modifié.

Bonne soirée et encore merci

J’ai un peu cherché et il est issu de la version 4.8.3 pas de la 4.8.7

En effet
J ai recopié le fichier de l ancienne conf qui n a pas du être mis à jour lors des évolutions sur le
Pi jeedom
Je vais essayer le dernier fichier pris directement dans les plugins du Pi jeedom et te tiens au courant

J ai repris les fichiers Global.py, teleinfo.py, teleinfo_2_cpt.py et mis dans le rep /root/teleinfo/
les fichiers init.py , jeedom.py dans le rep /root/teleinfo/jeedom/

Maintenant j ai l erreur suivante :

saisissez ou [2024-11-02 20:19:02][INFO] : GLOBAL------Start teleinfod
[2024-11-02 20:19:02][INFO] : GLOBAL------Cycle Sommeil : 30.0
[2024-11-02 20:19:02][INFO] : GLOBAL------Socket port : 55062
[2024-11-02 20:19:02][INFO] : GLOBAL------Socket host : 192.168.20.173
[2024-11-02 20:19:02][INFO] : GLOBAL------Log level : debug
[2024-11-02 20:19:02][INFO] : GLOBAL------Callback : http://192.168.20.190/plugins/teleinfo/core/php/jeeTeleinfo.php
[2024-11-02 20:19:02][INFO] : GLOBAL------Vitesse : 1200
[2024-11-02 20:19:02][INFO] : GLOBAL------Apikey : VytD2R7hyraVeRsU5gStuYjwnOYa2sWX2340iUtv6CBphpwB8dhmTPlb7JAwLKfk
[2024-11-02 20:19:02][INFO] : GLOBAL------Cycle : 1.0
[2024-11-02 20:19:02][INFO] : GLOBAL------Port : /dev/ttyUSB0
[2024-11-02 20:19:02][INFO] : GLOBAL------Mode : historique
[2024-11-02 20:19:02][DEBUG] : Writing PID 2384 to /tmp/jeedom/teleinfo/teleinfo2cpt.pid
Traceback (most recent call last):
  File "/root/teleinfo/teleinfo_2_cpt.py", line 601, in <module>
    jeedom_utils.write_pid(str(globals.pidfile))
  File "/root/teleinfo/jeedom/jeedom.py", line 220, in write_pid
    open(path, 'w').write("%s\n" % pid)
    ^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/jeedom/teleinfo/teleinfo2cpt.pid'

En effet, il n y apas de fichier de ce nom dans le rep du pi jeedom, rep qui d ailleurs est vide

J ai oublié de préciser que ces fichier viennent du pi jeedom /var/www/html/plugins/teleinfo/ressources/

Ci joint le teleinfo_2_cpt.py correspondant:

#!/usr/bin/python3

# -*- coding: utf-8 -*-



""" Teleinfo reader



License

=======



teleinfo_2_cpt.py is Copyright:

- (C) 2010-2012 Samuel <samuel DOT buffet AT gmail DOT com>

- (C) 2012-2017 Frédéric <fma38 AT gbiloba DOT org>

- (C) 2017 Samuel <samuel DOT buffet AT gmail DOT com>

- (C) 2015-2018 Cédric Guiné <cedric DOT guine AT gmail DOT com>



This software is governed by the CeCILL license under French law and

abiding by the rules of distribution of free software.  You can  use,

modify and/or redistribute the software under the terms of the CeCILL

license as circulated by CEA, CNRS and INRIA at the following URL

http://www.cecill.info.



As a counterpart to the access to the source code and  rights to copy,

modify and redistribute granted by the license, users are provided only

with a limited warranty  and the software's author,  the holder of the

economic rights,  and the successive licensors  have only  limited

liability.



In this respect, the user's attention is drawn to the risks associated

with loading,  using,  modifying and/or developing or reproducing the

software by the user in light of its specific status of free software,

that may mean  that it is complicated to manipulate,  and  that  also

therefore means  that it is reserved for developers  and  experienced

professionals having in-depth computer knowledge. Users are therefore

encouraged to load and test the software's suitability as regards their

requirements in conditions enabling the security of their systems and/or

data to be ensured and,  more generally, to use and operate it in the

same conditions as regards security.



The fact that you are presently reading this means that you have had

knowledge of the CeCILL license and that you accept its terms.

"""



import time

import optparse

#import urllib2

import sys

import os

import traceback

import logging

import signal

import globals

import argparse

import _thread

import json

try:

    import ftdi

    ftdi_type = 0

except ImportError:

    import ftdi1 as ftdi

    ftdi_type = 1

    #raise ImportError('Erreur de librairie ftdi')

try:

    from jeedom.jeedom import *

except ImportError as ex:

    print("Error: importing module from jeedom folder")

    print(ex)

    sys.exit(1)

# USB settings

usb_vendor = 0x0403

usb_product = 0x6001

usb_port = [0x00, 0x11, 0x22]

baud_rate = 1200



# Misc

stx = 0x02  # start of text

etx = 0x03  # end of text

eot = 0x04  # end of transmission



# Datas

global_external_ip = ''

global_cle_api = ''

global_debug = ''

global_real_path = ''



class FtdiError(Exception):

    """ Ftdi related errors

    """





class Ftdi(object):

    """ Class for handling ftdi communication

    """

    def __init__(self):

        """

        """

        logging.info("Try to open Teleinfo modem")

        super(Ftdi, self).__init__()

        self.__ftdic = None



    def init(self):

        """ Init ftdi com.

        """

        # Create ftdi context

        logging.info("Try to Create ftdi context")

        self.__ftdic = ftdi.ftdi_context()

        if self.__ftdic is None:

            logging.error("MODEM_2cpt------Can't create ftdi context")

            raise FtdiError("Can't create ftdi context")



        # Init ftdi context

        err = ftdi.ftdi_init(self.__ftdic)

        if err < 0:

            logging.error("MODEM_2cpt------Can't init ftdi context (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't init ftdi context (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



        # Open port

        logging.info("Try to open ftdi port")

        err = ftdi.ftdi_usb_open(self.__ftdic, usb_vendor, usb_product)

        if err < 0:

            logging.error("MODEM_2cpt------Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



        err = ftdi.ftdi_set_baudrate(self.__ftdic, baud_rate)

        if err < 0:

            logging.error("MODEM_2cpt------Can't set baudrate (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't set baudrate (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



        # Because of the usb interface, must use 8 bits transmission data, instead of 7 bits

        err = ftdi.ftdi_set_line_property(self.__ftdic, ftdi.BITS_8, ftdi.EVEN, ftdi.STOP_BIT_1)

        if err < 0:

            logging.error("MODEM_2cpt------Can't set line property (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't set line property (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



    def shutdown(self):

        """ Shutdown ftdi com.

        """

        logging.info("Try to close ftdi port")

        err = ftdi.ftdi_usb_close(self.__ftdic)

        if err < 0:

            logging.error("MODEM_2cpt------Can't close ftdi com. (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't close ftdi com. (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



        ftdi.ftdi_deinit(self.__ftdic)



    def selectPort(self, port):

        """ Select the giver port

        """

        err = ftdi.ftdi_set_bitmode(self.__ftdic, port, ftdi.BITMODE_CBUS)

        if err < 0:

            logging.error("MODEM_2cpt------Can't set bitmode (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't set bitmode (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        time.sleep(0.1)



    def purgeBuffers(self):

        """ Purge ftdi buffers

        """

        err = ftdi.ftdi_usb_purge_buffers(self.__ftdic)

        if err < 0:

            logging.error("MODEM_2cpt------Can't purge buffers (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            raise FtdiError("Can't purge buffers (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))



    def readOne(self):

        """ read 1 char from usb

        """

        buf = ' '

        err = ftdi.ftdi_read_data(self.__ftdic, buf, 1)

        if err < 0:

            logging.error("MODEM_2cpt------Can't read data (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            self.shutdown()

            raise FtdiError("Can't read data (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

        if err:

            c_error = chr(ord(buf) % 0x80)  # Clear bit 7

            return c_error

        else:

            return None



    def read(self, size):

        """ read several chars

        """



        # Purge buffers

        self.purgeBuffers()



        raw = u""

        while len(raw) < globals.frame_length:

            c = self.readOne()

            if c is not None and c != '\x00':

                raw += c



        return raw



class Teleinfo(object):

    import globals

    """ Class for handling teleinfo stuff

    """

    def __init__(self, ftdi_):

        """

        """

        logging.info("MODEM_2cpt------Initialisation de la teleinfo")

        logging.info("MODEM_2cpt------MODEM_2cpt------FTDI TYPE : " + str(ftdi_type))

        if ftdi_type == 0:

            globals.ftdi_context = ""

            super(Teleinfo, self).__init__()

            self.__ftdi = ftdi_

        else:

            globals.ftdi_context = ftdi.new()

            ret = ftdi.usb_open(globals.ftdi_context, 0x0403, 0x6001)

            if ret < 0:

                logging.error("MODEM_2cpt------Can't open usb (%d, %s)" % (err, ftdi.ftdi_get_error_string(self.__ftdic)))

            ftdi.set_baudrate(globals.ftdi_context, int(globals.vitesse))

        if globals.mode == "historique":

            globals.frame_length = 500

            #ftdi.set_line_property(globals.ftdi_context, ftdi.BITS_8, ftdi.EVEN, ftdi.STOP_BIT_1)



    def __selectMeter(self, num):

        """ Select giver meter

        """

        if ftdi_type == 0:

            self.__ftdi.selectPort(usb_port[num])

        else:

            err = ftdi.set_bitmode(globals.ftdi_context, usb_port[num], ftdi.BITMODE_CBUS)

            if err < 0:

                logging.error("MODEM_2cpt------Can't set bitmode (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

                raise FtdiError("Can't set bitmode (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

            time.sleep(0.1)



    def __readOne(self):

        """ read 1 char from usb

        """

        err, buf = ftdi.read_data(globals.ftdi_context, 0x1)

        if err < 0:

            logging.error("MODEM_2cpt------Can't read data (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

            self.close()

            raise FtdiError("Can't read data (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

        if err:

            #c = unichr(ord(buf) % 0x80)  # Clear bit 7

            c = chr(ord(buf) & 0x07f)

            return err, c

        else:

            return err, None



    def __readRawFrame(self):

        """ Read raw frame

        """

        # As the data are sent asynchronously by the USB interface, we probably don't start

        # to read at the start of a frame. So, we read enough chars to retreive a complete frame

        logging.debug("Lecture des donnees")

        if ftdi_type == 0:

            raw = self.__ftdi.read(globals.frame_length)

        else:

            err = ftdi.usb_purge_buffers(globals.ftdi_context)

            if err < 0:

                logging.error("MODEM_2cpt------Can't purge buffers (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

                raise FtdiError("Can't purge buffers (%d, %s)" % (err, ftdi.get_error_string(globals.ftdi_context)))

            raw = u""

            while len(raw) < globals.frame_length:

                err, c = self.__readOne()

                if c is not None and c != '\x00':

                    raw += c

                    #logging.debug(c)

        return raw



    def __frameToDatas(self, frame):

        """ Split frame in datas

        """

        #essai indent

        Content = {}

        lines = frame.split('\r')

        for line in lines:

            try:

                checksum = line[-1]

                #logging.debug('chechsum : ' + checksum)

                header, value = line[:-2].split()

                #data = {'header': header.encode(), 'value': value.encode(), 'checksum': checksum}

                #logging.debug('TELEINFO------name : ' + header.encode() + ' value : ' + value.encode() + ' checksum : ' + checksum)

                logging.debug('TELEINFO------name : ' + header + ' value : ' + value + ' chechsum : ' + checksum)

                if self.__checkData(line):

                    #logging.debug('retour vrai du checksum')

                    #Content[header.encode()] = value.encode()

                    Content[header] = value

                    #logging.debug('retour 2 ')

            except:

                pass

                #datas.append(data)

        return Content



    def __checkData(self, data):

        """ Check if data is ok (checksum)

        """

        if globals.mode == "standard":

            #Gestion des champs horodates

            #logging.debug('calcul du checksum 1')

            if len(data.split('\x09')) == 4:

                datas = '\x09'.join(data.split('\x09')[0:3])

                #logging.debug('calcul du checksum 2' + datas)

            else:

                datas = '\x09'.join(data.split('\x09')[0:2])

                #logging.debug('calcul du checksum 3' + datas)

            my_sum = 0

            for cks in datas:

                my_sum = my_sum + ord(cks)

            #logging.debug('my_sum : ' + str(my_sum))

            computed_checksum = ((my_sum - 0x01) & int("111111", 2)) + 0x20

            #computed_checksum = ((my_sum + 0x09) & int("111111", 2)) + 0x20

            #logging.debug('computed checksum : ' + chr(computed_checksum) + ' compare a checksum : ' + data[-1])

        else:

            #print "Check checksum : f = %s, chk = %s" % (frame, checksum)

            datas = ' '.join(data.split()[0:2])

            my_sum = 0

            for cks in datas:

                my_sum = my_sum + ord(cks)

            computed_checksum = (my_sum & int("111111", 2)) + 0x20

            #print "computed_checksum = %s" % chr(computed_checksum)

        return chr(computed_checksum) == data[-1]



    def extractDatas(self, raw):

        """ Extract datas from raw frame

        """

        end = raw.rfind(chr(etx)) + 1

        start = raw[:end].rfind(chr(etx)+chr(stx))

        frame = raw[start+2:end-2]

        #logging.debug('end : ' + str(end) + ' start : ' + str(start) + ' frame : ' + frame)



        # Check if there is a eot, cancel frame

        if frame.find(chr(eot)) != -1:

            return {'Message':'eot'}

            #raise TeleinfoError("eot found")



        # Convert frame back to ERDF standard

        #frame = frame.replace('\n', '')     # Remove new line



        # Extract data

        datas = self.__frameToDatas(frame)



        return datas



    def readMeter(self):

        """ Read raw frame for giver meter

        """

        num_compteur = 1

        cpt1_data = {}

        cpt2_data = {}

        cpt1_data_temp = {}

        cpt2_data_temp = {}

        raz_time = 600

        separateur = " "

        send_data = {}

        #for cle, valeur in Donnees.items():

        #            Donnees.pop(cle)

        #            _Donnees.pop(cle)

        while(1):

            if raz_time > 1:

                raz_time = raz_time - 1

            else:

                logging.info("MODEM_2cpt------HEARTBEAT")

                raz_time = 600

                for cle, valeur in list(cpt1_data.items()):

                    cpt1_data.pop(cle)

                    cpt1_data_temp.pop(cle)

                for cle, valeur in list(cpt2_data.items()):

                    cpt2_data.pop(cle)

                    cpt2_data_temp.pop(cle)

            send_data = {}

            self.__selectMeter(num_compteur)

            raw = self.__readRawFrame()

            self.__selectMeter(0)

            datas = self.extractDatas(raw)

            #logging.debug(raw)



            if num_compteur == 1:

                for cle, valeur in datas.items():

                    if cle == 'PTEC':

                        valeur = valeur.replace(".", "")

                        valeur = valeur.replace(")", "")

                        cpt1_data[cle] = valeur

                    else:

                        cpt1_data[cle] = valeur

                        logging.debug('cle : ' + cle + ' valeur : ' + valeur)

            elif num_compteur == 2:

                for cle, valeur in datas.items():

                    if cle == 'PTEC':

                        valeur = valeur.replace(".", "")

                        valeur = valeur.replace(")", "")

                        cpt2_data[cle] = valeur

                    else:

                        cpt2_data[cle] = valeur

            PENDING_CHANGES = False

            if num_compteur == 1:

                for cle, valeur in cpt1_data.items():

                    if cle in cpt1_data_temp:

                        if cpt1_data[cle] != cpt1_data_temp[cle]:

                            send_data[cle] = valeur

                            cpt1_data_temp[cle] = valeur

                            PENDING_CHANGES = True

                    else:

                        send_data[cle] = valeur

                        cpt1_data_temp[cle] = valeur

                        PENDING_CHANGES = True

            elif num_compteur == 2:

                for cle, valeur in cpt2_data.items():

                    if cle in cpt2_data_temp:

                        if cpt2_data[cle] != cpt2_data_temp[cle]:

                            send_data[cle] = valeur

                            cpt2_data_temp[cle] = valeur

                            PENDING_CHANGES = True

                    else:

                        send_data[cle] = valeur

                        cpt2_data_temp[cle] = valeur

                        PENDING_CHANGES = True

            try:

                if PENDING_CHANGES :

                    if num_compteur == 1:

                        if globals.mode == "standard": # Zone linky standard

                            if not cpt1_data_temp["ADSC"] == '':

                                send_data["device"] = cpt1_data_temp["ADSC"]

                                globals.JEEDOM_COM.add_changes('device::'+cpt1_data_temp["ADSC"],send_data)

                        else:

                            if not cpt1_data_temp["ADCO"] == '':

                                send_data["device"] = cpt1_data_temp["ADCO"]

                                globals.JEEDOM_COM.add_changes('device::'+cpt1_data_temp["ADCO"],send_data)

                    elif num_compteur == 2:

                        if globals.mode == "standard": # Zone linky standard

                            if not cpt2_data_temp["ADSC"] == '':

                                send_data["device"] = cpt2_data_temp["ADSC"]

                                globals.JEEDOM_COM.add_changes('device::'+cpt2_data_temp["ADSC"],send_data)

                        else:

                            if not cpt2_data_temp["ADCO"] == '':

                                send_data["device"] = cpt2_data_temp["ADCO"]

                                globals.JEEDOM_COM.add_changes('device::'+cpt2_data_temp["ADCO"],send_data)

            except Exception:

                errorCom = "Connection error"

                logging.error(errorCom)

            #logging.debug("MODEM_2cpt------START SLEEPING " + str(globals.cycle_sommeil) + " seconds")

            time.sleep(globals.cycle_sommeil)

            #logging.debug("MODEM_2cpt------WAITING : " + str(globals.TELEINFO_SERIAL.inWaiting()) + " octets dans la file apres sleep ")

            #if globals.TELEINFO_SERIAL.inWaiting() > 1500:

            #    globals.TELEINFO_SERIAL.flushInput()

            #    logging.info("MODEM_2cpt------BUFFER OVERFLOW => FLUSH")

            #    logging.debug(str(globals.TELEINFO_SERIAL.inWaiting()) + "octets dans la file apres flush ")

            if num_compteur == 1:

                num_compteur = 2

            else:

                num_compteur = 1

        self.terminate()



    def exit_handler(self, *args):

        self.terminate()

        logging.info("[exit_handler]")



    def close(self):

        if ftdi_type == 0:

            self.__ftdi.shutdown()

        else:

            ftdi.close()



    def terminate(self):

        print ("Terminating...")

        self.close()

        #sys.close(gOutput)

        #sys.exit()



def read_socket(cycle):

    while True:

        try:

            global JEEDOM_SOCKET_MESSAGE

            if not JEEDOM_SOCKET_MESSAGE.empty():

                logging.debug("SOCKET-READ------Message received in socket JEEDOM_SOCKET_MESSAGE")

                message = json.loads(JEEDOM_SOCKET_MESSAGE.get())

                logging.debug("SOCKET-READ------Message received in socket JEEDOM_SOCKET_MESSAGE " + message['cmd'])

                if message['apikey'] != globals.apikey:

                    logging.error("SOCKET-READ------Invalid apikey from socket : " + str(message))

                    return

                logging.debug('SOCKET-READ------Received command from jeedom : ' + str(message['cmd']))

                if message['cmd'] == 'action':

                    logging.debug('SOCKET-READ------Attempt an action on a device')

                    _thread.start_new_thread(action_handler, (message,))

                    logging.debug('SOCKET-READ------Action Thread Launched')

                elif message['cmd'] == 'changelog':

                    jeedom_utils.set_log_level('info')

                    logging.info('SOCKET-READ------Passage du demon en mode ' + message['level'])

                    log = logging.getLogger()

                    for hdlr in log.handlers[:]:

                        log.removeHandler(hdlr)

                    logging.info("SOCKET-READ------------ C'est parti ;)")

                    jeedom_utils.set_log_level(message['level'])

        except Exception as e:

            logging.error("SOCKET-READ------Exception on socket : %s" % str(e))

            logging.debug(traceback.format_exc())

        time.sleep(cycle)



def listen():

    globals.PENDING_ACTION=False

    jeedom_socket.open()

    logging.info("MODEM_2cpt------Start listening...")

    #globals.TELEINFO = Teleinfo()

    logging.info("MODEM_2cpt------Preparing Teleinfo...")

    _thread.start_new_thread( read_socket, (globals.cycle,))

    logging.debug('GLOBAL------Read Socket Thread Launched')

    while 1:

        try:

            if ftdi_type == 0:

                ftdi_ = Ftdi()

                ftdi_.init()

                globals.TELEINFO = Teleinfo(ftdi_)

            else:

                globals.TELEINFO = Teleinfo("")

            globals.TELEINFO.readMeter()

        except Exception as e:

            print("Error:")

            print(e)

            shutdown()



def handler(signum=None, frame=None):

    logging.debug("Signal %i caught, exiting..." % int(signum))

    shutdown()



def shutdown():

    logging.debug("MODEM_2cpt------Shutdown")

    #if ftdi_type == 0:

        #ftdi_.shutdown()

    #globals.TELEINFO.close()

    logging.debug("Shutdown")

    logging.debug("Removing PID file " + str(globals.pidfile))

    try:

        os.remove(globals.pidfile)

    except:

        pass

    try:

        jeedom_socket.close()

    except:

        pass

    logging.debug("Exit 0")

    sys.stdout.flush()

    os._exit(0)

#------------------------------------------------------------------------------

# MAIN

#------------------------------------------------------------------------------



globals.log_level = "info"

globals.socketport = 55062

globals.sockethost = '127.0.0.1'

globals.apikey = ''

globals.callback = ''

globals.cycle = 1;



parser = argparse.ArgumentParser(description='Teleinfo Daemon for Jeedom plugin')

parser.add_argument("--apikey", help="Value to write", type=str)

parser.add_argument("--loglevel", help="Log Level for the daemon", type=str)

parser.add_argument("--callback", help="Value to write", type=str)

parser.add_argument("--socketport", help="Socket Port", type=str)

parser.add_argument("--sockethost", help="Socket Host", type=str)

parser.add_argument("--cycle", help="Cycle to send event", type=str)

parser.add_argument("--port", help="Port du modem", type=str)

parser.add_argument("--vitesse", help="Vitesse du modem", type=str)

parser.add_argument("--mode", help="Model mode", type=str)

parser.add_argument("--cyclesommeil", help="Wait time between 2 readline", type=str)

parser.add_argument("--pidfile", help="pidfile", type=str)

args = parser.parse_args()



if args.apikey:

    globals.apikey = args.apikey

if args.loglevel:

    globals.log_level = args.loglevel

if args.callback:

    globals.callback = args.callback

if args.socketport:

    globals.socketport = args.socketport

if args.sockethost:

    globals.sockethost = args.sockethost

if args.cycle:

    globals.cycle = float(args.cycle)

if args.port:

    globals.port = args.port

if args.vitesse:

    globals.vitesse = args.vitesse

if args.mode:

    globals.mode = args.mode

if args.cyclesommeil:

    globals.cycle_sommeil = float(args.cyclesommeil)

if args.pidfile:

    globals.pidfile = args.pidfile



globals.socketport = int(globals.socketport)

globals.cycle = float(globals.cycle)



jeedom_utils.set_log_level(globals.log_level)

logging.info('GLOBAL------Start teleinfod')

logging.info('GLOBAL------Cycle Sommeil : '+str(globals.cycle_sommeil))

logging.info('GLOBAL------Socket port : '+str(globals.socketport))

logging.info('GLOBAL------Socket host : '+str(globals.sockethost))

logging.info('GLOBAL------Log level : '+str(globals.log_level))

logging.info('GLOBAL------Callback : '+str(globals.callback))

logging.info('GLOBAL------Vitesse : '+str(globals.vitesse))

logging.info('GLOBAL------Apikey : '+str(globals.apikey))

logging.info('GLOBAL------Cycle : '+str(globals.cycle))

logging.info('GLOBAL------Port : '+str(globals.port))

logging.info('GLOBAL------Mode : '+str(globals.mode))



signal.signal(signal.SIGINT, handler)

signal.signal(signal.SIGTERM, handler)

globals.pidfile = globals.pidfile + "2cpt.pid"

jeedom_utils.write_pid(str(globals.pidfile))

globals.JEEDOM_COM = jeedom_com(apikey = globals.apikey,url = globals.callback,cycle=globals.cycle)

if not globals.JEEDOM_COM.test():

    logging.error('MODEM_2cpt------Network communication issues. Please fix your Jeedom network configuration.')

    shutdown()

jeedom_socket = jeedom_socket(port=globals.socketport,address=globals.sockethost)

listen()

sys.exit()