コード例 #1
0
ファイル: __init__.py プロジェクト: b10m/nefit-client-python
class NefitCore(object):
    _accesskey_prefix = 'Ct7ZR03b_'
    _rrc_contact_prefix = 'rrccontact_'
    _rrc_gateway_prefix = 'rrcgateway_'
    _magic = bytearray.fromhex("58f18d70f667c9c79ef7de435bf0f9b1553bbb6e61816212ab80e5b0d351fbb1")

    serial_number = None
    access_key = None
    password = None

    jid = None
    _from = None
    _to = None
    client = None
    encryption = None

    event = None
    container = {}

    def __init__(self, serial_number, access_key, password, host="wa2-mz36-qrmzh6.bosch.de", sasl_mech="DIGEST-MD5"):
        """

        :param serial_number:
        :param access_key:
        :param password:
        :param host:
        :param sasl_mech:
        """
        serial_number = str(serial_number)
        self.serial_number = serial_number
        self.access_key = access_key
        self.password = password

        self.encryption = AESCipher(self._magic, access_key, password)

        identifier = serial_number + "@" + host
        self.jid = jid = self._from = self._rrc_contact_prefix + identifier
        self._to = self._rrc_gateway_prefix + identifier

        self.client = ClientXMPP(jid=jid, password=self._accesskey_prefix + access_key, sasl_mech=sasl_mech)
        self.client.add_event_handler("session_start", self.session_start)
        self.client.register_plugin('xep_0199')

    @staticmethod
    def set_verbose():
        import logging
        logging.basicConfig(filename="debug.log", level=logging.DEBUG)

    def message(self, msg):
        if msg['type'] in ('chat', 'normal'):
            headers = msg['body'].split("\n")[:-1]
            body = msg['body'].split("\n")[-1:][0]
            if 'HTTP/1.0 400 Bad Request' in headers:
                return
            response = self.decrypt(body)
            if 'Content-Type: application/json' in headers:
                _LOGGER.debug("response='{}'".format(response))
                response = response.strip()
                if len(response) > 1:
                    response = json.loads(response.strip())
            self.container[id(self.event)] = response
        self.event.set()

    def connect(self, block=False):
        self.client.connect()
        self.client.process(block=block)

    def session_start(self, event):
        self.client.send_presence()
        self.client.get_roster()

    def disconnect(self):
        self.client.disconnect()

    def get(self, uri, timeout=10):
        self.event = Event()
        self.client.add_event_handler("message", self.message)
        self.send("GET %s HTTP/1.1\rUser-Agent: NefitEasy\r\r" % uri)
        self.event.wait(timeout=timeout)
        self.client.del_event_handler("message", self.message)
        return self.container[id(self.event)] if id(self.event) in self.container.keys() else None

    def put(self, uri, data, timeout=10):
        data = data if isinstance(data, str) else json.dumps(data, separators=(',', ':'))
        encrypted_data = self.encrypt(data).decode("utf8")
        body = "\r".join([
            'PUT %s HTTP/1.1' % uri,
            'Content-Type: application/json',
            'Content-Length: %i' % len(encrypted_data),
            'User-Agent: NefitEasy\r',
            encrypted_data
        ])
        self.event = Event()
        self.client.add_event_handler("message", self.message)
        self.send(body)
        self.event.wait(timeout=timeout)
        self.client.del_event_handler("message", self.message)

    def send(self, body):
        # this horrible piece of code breaks xml syntax but does actually work...
        body = body.replace("\r", "
\n")
        message = self.client.make_message(mto=self._to, mfrom=self._from, mbody=body)
        message['lang'] = None
        str_data = tostring(message.xml, xmlns=message.stream.default_ns,
                            stream=message.stream,
                            top_level=True)
        str_data = str_data.replace("
", "
")
        return message.stream.send_raw(str_data)

    def encrypt(self, data):
        return self.encryption.encrypt(data)

    def decrypt(self, data):
        return self.encryption.decrypt(data)

    def get_display_code(self):
        return self.get('/system/appliance/displaycode')

    def get_status(self):
        return self.get('/ecus/rrc/uiStatus')

    def get_location(self):
        return self.get('/system/location/latitude'), self.get('/system/location/longitude')

    def get_outdoor(self):
        return self.get('/system/sensors/temperatures/outdoor_t1')

    def get_pressure(self):
        return self.get('/system/appliance/systemPressure')

    def get_program(self):
        return (
            self.get('/ecus/rrc/userprogram/activeprogram'),
            self.get('/ecus/rrc/userprogram/program1'),
            self.get('/ecus/rrc/userprogram/program2'),
        )

    def get_year_total(self):
        return self.get('/ecus/rrc/recordings/yearTotal')

    def set_temperature(self, temperature):
        self.put('/heatingCircuits/hc1/temperatureRoomManual', {'value': float(temperature)})
        self.put('/heatingCircuits/hc1/manualTempOverride/status', {'value': 'on'})
        self.put('/heatingCircuits/hc1/manualTempOverride/temperature', {'value': float(temperature)})

    def get_actualSupplyTemperature(self):
        return self.get('/heatingCircuits/hc1/actualSupplyTemperature')
コード例 #2
0
ファイル: xmpp.py プロジェクト: consometers/sen1-poc-proxies
class XmppFederationProtocol(FederationProtocol):
    """
    Gestion des échanges sur le réseau fédéré avec le protocole XMPP
    
    Implémentation XMPP du FederationProtocol 
    """
    def __init__(self):
        """
        PostConstruct
        """
        self.configService = None
        self.appService = None
        self.xmpp = None
        self.messageHandler = None
        MonkeyPatch().patch_fromisoformat()

    def start(self):
        """
        Démarre le service
        """
        xmppDomain = self.configService.value("XMPP_DOMAIN_NAME")
        xmppUser = self.configService.value("XMPP_USERNAME")
        self.xmpp = ClientXMPP(xmppUser,
                               self.configService.value("XMPP_PASSWORD"))

        # ajout des listeners et plugins
        self.xmpp.add_event_handler("session_start", self.session_start)
        self.xmpp.register_plugin('XmppMessagePlugin', module=xmpp)
        self.xmpp.register_handler(
            Callback(
                'SEN1 Message',
                MatchXPath('{%s}message/{http://xmpp.rocks}Sen1Message' %
                           self.xmpp.default_ns), self.receiveMessage))
        register_stanza_plugin(Message, XmppMessageStanza)

        if (not self.xmpp.connect(address=(xmppDomain, 5222))):
            raise Exception("Cannot bind XMPP session to {}".format(xmppUser))

        self.logger.info(
            "Start XMPP protocol : bind session {}...".format(xmppUser))

        self.xmpp.process()

    def stop(self):
        """
        Stoppe le service
        """
        self.logger.info("Stop XMPP protocol...")
        self.xmpp.disconnect()

    def session_start(self, event):
        """
        
        """
        self.logger.info("XMPP session is started")
        self.xmpp.send_presence()
        self.xmpp.get_roster()

    def receiveMessage(self, stanza):
        """
        Réception d'un message XMPP
        
        :param stanza: xmpp message
        """
        self.logger.info("Receive SEN1 message from {}...".format(
            stanza['from']))

        try:
            message = XmppMessageStanza.parse_xmpp_message(stanza)
            self.messageHandler.handle(message)
        except Exception as ex:
            self.logger.error("Receive SEN1 message : {}".format(ex))

    def sendMessage(self, message):
        """
        Envoi d'un message
        
        :param message: Message
        """

        # vérifie la conformité du message avant envoi
        message.asserts()

        # recherche du JID de l'application destinataire
        app = self.appService.findByName(message.applicationDst)
        self.logger.info("Sending SEN1 message to {}...".format(app.jid))

        # construction d'un message
        xmppMessage = self.xmpp.make_message(app.jid)
        XmppMessageStanza.build_xmpp_message(xmppMessage, message).send()