APsystems ECU-C - Domoticz

Forum pour tous les autres objets : sondes météo, capteurs, actionneurs ...
Vous avez un besoin mais vous ne savez pas quel matériel choisir ? C'est ici.
kaka83136
Messages : 19
Inscription : 20 juil. 2020, 14:57

APsystems ECU-C - Domoticz

Message par kaka83136 »

Bonjour,

J'ai recemment acquerit des panneaux Solaires avec comme passerelle une APSystems ECU-C relié en RJ45.

Je voulais savoir si il exister un plugin pour intégrer la production et consomation à Domoticz et d'autre données si possible?

Merci
Jeff
Messages : 1007
Inscription : 17 nov. 2016, 20:54
Localisation : Rennes (35)

Re: APsystems ECU-C - Domoticz

Message par Jeff »

En essayant sur google... ca ferait pas ton bonheur ceci https://www.bjorn-meijer.nl/en/2021/05/ ... -domoticz/
Version: 2023.1 sur VM Synology, docker Zwave Js UI (Z-stick GEN5, Fibaro...), Zigbeefordomoticz. Nextion RGB Led Screen
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Re: APsystems ECU-C - Domoticz

Message par Keros »

Sujet déplacé dans la section dédiée aux objets.
EMqA
Messages : 38
Inscription : 14 déc. 2019, 14:27

Re: APsystems ECU-C - Domoticz

Message par EMqA »

Je profite du sujet pour me renseigner.
Je viens tout juste d'installer une paire de panneaux avec un micro-onduleur DS3_L et une passerelle ECU-B. Le système est opérationnel mais j'ai fini trop tard ce soir pour voir si cela produit.
J'avais préparé le terrain pour remonter les infos dans Domoticz en suivant cette procédure : https://github.com/Doudou14/Domoticz-apsystems_ecu
Je n'ai aucune notion de python, je me contente de savoir suivre les tutos.
J'ai pu positionné les 2 fichiers correctement renseignés dans le répertoire scripts indiqué, créé les devices, créer un script DZvent pour relever les infos toutes les 5min.
au moment de tester le script, j'obtiens un message que je ne sais pas identifier comme étant un problème ou pas. Sauriez vous me guider ?

Code : Tout sélectionner

pi@raspberrypi-domoticz:~/domoticz/scripts/python/ECU $ sudo python3 ECU-B.py
Traceback (most recent call last):
  File "ECU-B.py", line 45, in <module>
    data = loop.run_until_complete(ecu.async_query_ecu())
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "/home/pi/domoticz/scripts/python/ECU/APSystemsECU.py", line 131, in async_query_ecu
    raise APSystemsInvalidData(error)
APSystemsECU.APSystemsInvalidData: ECU returned 0 for lifetime energy, raw data=b'APS110094000121630005500601\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xd0\xd0\xd0\xd0\xd0\xd0\x00\x01\x00\x0010012ECU_B_1.2.26009Etc/GMT-8\x80\x97\x1b\x06\x1d6\x00\x00\x00\x00\x00\x00END\n'
pi@raspberrypi-domoticz:~/domoticz/scripts/python/ECU $ 
syl2222_fr
Messages : 47
Inscription : 14 janv. 2022, 20:02

Re: APsystems ECU-C - Domoticz

Message par syl2222_fr »

Salut,

J'avais utilisé la méthode de bjorn pour surveiller mes (oui, j'en ai 2) ecu-b .
Ca marchait parfaitement . C'est cool que maintenant il y ai une intégration ! (depuis, je suis passé sur HA pour surveiller cela).
Edit: Lol , l'intégration domoticz est un fork de l'intégration HA . Pour info, le workaround #142 dans Ha, c'est moi :)

Par contre, j'avais remarqué que, dés la nuit tombée, j'avais des trucs bizarre. Vu que tu as fait tes essais tard, peut-être que cela a un rapport ?

1°) Sur le site de APsysteme , t'as toutes les data ?
Si non => faut commencer à regarder pourquoi car, c'est peut-être ça le soucis (intégration des panneaux dans l'Ecu, parametrage de l'ecu, etc).
Si oui =>Recommence tranquillement en suivant l'ancienne procédure qui a marché du premier coup pour moi : https://www.bjorn-meijer.nl/en/2021/05/ ... -domoticz/
EMqA
Messages : 38
Inscription : 14 déc. 2019, 14:27

Re: APsystems ECU-C - Domoticz

Message par EMqA »

C’est ok du côté du site APsystems et sur l’app iOS EMA app.
Le lancement du script via dzvent aussi.

Code : Tout sélectionner

 2023-03-03 08:55:00.341 Status: dzVents: Info: DZvent_ECU-B: ------ Start internal script: DZvent_ECU-B:, trigger: "at daytime every 5 minutes"
2023-03-03 08:55:00.341 Status: dzVents: Info: DZvent_ECU-B: Timer event was triggered by at daytime every 5 minutes
2023-03-03 08:55:00.940 Status: dzVents: Info: DZvent_ECU-B: ------ Finished DZvent_ECU-B
Mais comme je le craignais, quelque chose coince dans le script python en lui même car rien ne remonte dans les différents devices créés.
syl2222_fr
Messages : 47
Inscription : 14 janv. 2022, 20:02

Re: APsystems ECU-C - Domoticz

Message par syl2222_fr »

Tu as installé combien de panneaux / onduleurs ds3l ?
Je suis nul en python , mais, à ta place , je modifierai le script :
https://github.com/Doudou14/Domoticz-ap ... U/ECU_B.py
pour isoler les onduleurs.

T'as l'onduleur 1 des lignes 84 à 112 et l'onduleur 2 des lignes 114 à 136

En isolant 1 des deux onduleurs , tu peux circoncire le soucis qui serait lié à un onduleur ou un panneau ?
EMqA
Messages : 38
Inscription : 14 déc. 2019, 14:27

Re: APsystems ECU-C - Domoticz

Message par EMqA »

J’ai un seul onduleur installé.
J’avais eu l’idée de me passer de ce qui concerne un second onduleur. Si je n’ai pas fait d’erreur, j’ai passé tous les éléments concernés en commentaire.
Je posterai le code des 2 scripts ce soir.
EMqA
Messages : 38
Inscription : 14 déc. 2019, 14:27

Re: APsystems ECU-C - Domoticz

Message par EMqA »

Mes 2 fichiers sont placés dans un dossier home\pi\domoticz\scripts\python\ ECU

Le premier est le fichier APSystemsECU.py que j'ai laissé tel quel

Code : Tout sélectionner

#!/usr/bin/env python3

import asyncio
import socket
import binascii
import datetime
import json
import logging

_LOGGER = logging.getLogger(__name__)

from pprint import pprint

class APSystemsInvalidData(Exception):
    pass

class APSystemsInvalidInverter(Exception):
    pass


class APSystemsECU:

    def __init__(self, ipaddr, port=8899, raw_ecu=None, raw_inverter=None):
        self.ipaddr = ipaddr
        self.port = port

        # what do we expect socket data to end in
        self.recv_suffix = b'END\n'

        # how long to wait on socket commands until we get our recv_suffix
        self.timeout = 5

        # how many times do we try the same command in a single update before failing
        self.cmd_attempts = 3

        # how big of a buffer to read at a time from the socket
        self.recv_size = 1024

        # how long to wait between socket open/closes
        self.socket_sleep_time = 2.0
        self.cmd_suffix = "END\n"
        self.ecu_query = "APS1100160001" + self.cmd_suffix
        self.inverter_query_prefix = "APS1100280002"
        self.inverter_query_suffix = self.cmd_suffix

        self.inverter_signal_prefix = "APS1100280030"
        self.inverter_signal_suffix = self.cmd_suffix

        self.inverter_byte_start = 26

        self.ecu_id = None
        self.ecu_firmware = None
        self.qty_of_inverters = 0
        self.qty_of_online_inverters = 0
        self.lifetime_energy = 0
        self.current_power = 0
        self.today_energy = 0
        self.inverters = {}
        self.firmware = None
        self.timezone = None
        self.last_update = None
        self.vsl = 0
        self.tsl = 0

        self.ecu_raw_data = raw_ecu
        self.inverter_raw_data = raw_inverter
        self.inverter_raw_signal = None

        self.read_buffer = b''

        self.reader = None
        self.writer = None

        self.socket_open = False

        self.errors = []

    async def async_read_from_socket(self):
        self.read_buffer = b''
        end_data = None

        self.read_buffer = await self.reader.readline()
        if self.read_buffer == b'':
            error = f"Got empty string from socket"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        size = len(self.read_buffer)
        end_data = self.read_buffer[size-4:]
        if end_data != self.recv_suffix:
            error = f"End suffix ({self.recv_suffix}) missing from ECU response end_data={end_data} data={self.read_buffer}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        return self.read_buffer

    async def async_send_read_from_socket(self, cmd):
        self.writer.write(cmd.encode('utf-8'))
        await self.writer.drain()
        try:
            return await asyncio.wait_for(self.async_read_from_socket(), timeout=self.timeout)
        except asyncio.TimeoutError as err:
            await self.async_close_socket()
            msg = "Timeout after {self.timeout}s waiting or ECU data cmd={cmd.rstrip()}. Closing socket."
            self.add_error(msg)
            raise APSystemsInvalidData(error)

    async def async_close_socket(self):
        if self.socket_open:
            self.writer.close()
            await self.writer.wait_closed()
            self.socket_open = False

    async def async_open_socket(self):
        _LOGGER.debug(f"Connecting to ECU on {self.ipaddr} {self.port}")
        self.reader, self.writer = await asyncio.open_connection(self.ipaddr, self.port)
        _LOGGER.debug(f"Connected to ECU {self.ipaddr} {self.port}")
        self.socket_open = True


    async def async_query_ecu(self):
        await self.async_open_socket()
        cmd = self.ecu_query
        self.ecu_raw_data = await self.async_send_read_from_socket(cmd)
        await self.async_close_socket()
        self.process_ecu_data()
        if self.lifetime_energy == 0:
            await self.async_close_socket()
            error = f"ECU returned 0 for lifetime energy, raw data={self.ecu_raw_data}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        # the ECU likes the socket to be closed and re-opened between commands
        await asyncio.sleep(self.socket_sleep_time) 
        await self.async_open_socket()
        cmd = self.inverter_query_prefix + self.ecu_id + self.inverter_query_suffix
        self.inverter_raw_data = await self.async_send_read_from_socket(cmd)
        await self.async_close_socket()

        # the ECU likes the socket to be closed and re-opened between commands
        await asyncio.sleep(self.socket_sleep_time)  
        await self.async_open_socket()
        cmd = self.inverter_signal_prefix + self.ecu_id + self.inverter_signal_suffix
        self.inverter_raw_signal = await self.async_send_read_from_socket(cmd)

        await self.async_close_socket()
        data = self.process_inverter_data()
        data["ecu_id"] = self.ecu_id
        data["ecu_firmware"] = self.firmware
        data["today_energy"] = self.today_energy
        data["lifetime_energy"] = self.lifetime_energy
        data["current_power"] = self.current_power
        data["qty_of_inverters"] = self.qty_of_inverters
        data["qty_of_online_inverters"] = self.qty_of_online_inverters
        return(data)
 
    def aps_int(self, codec, start):
        try:
            return int(binascii.b2a_hex(codec[(start):(start+2)]), 16)
        except ValueError as err:
            debugdata = binascii.b2a_hex(codec)
            error = f"Unable to convert binary to int location={start} data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)
 
    def aps_short(self, codec, start):
        try:
            return int(binascii.b2a_hex(codec[(start):(start+1)]), 8)
        except ValueError as err:
            debugdata = binascii.b2a_hex(codec)
            error = f"Unable to convert binary to short int location={start} data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

    def aps_double(self, codec, start):
        try:
            return int (binascii.b2a_hex(codec[(start):(start+4)]), 16)
        except ValueError as err:
            debugdata = binascii.b2a_hex(codec)
            error = f"Unable to convert binary to double location={start} data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)
    
    def aps_bool(self, codec, start):
        return bool(binascii.b2a_hex(codec[(start):(start+2)]))
    
    def aps_uid(self, codec, start):
        return str(binascii.b2a_hex(codec[(start):(start+12)]))[2:14]
    
    def aps_str(self, codec, start, amount):
        return str(codec[start:(start+amount)])[2:(amount+2)]
    
    def aps_timestamp(self, codec, start, amount):
        timestr=str(binascii.b2a_hex(codec[start:(start+amount)]))[2:(amount+2)]
        return timestr[0:4]+"-"+timestr[4:6]+"-"+timestr[6:8]+" "+timestr[8:10]+":"+timestr[10:12]+":"+timestr[12:14]

    def check_ecu_checksum(self, data, cmd):
        datalen = len(data) - 1
        try:
            checksum = int(data[5:9])
        except ValueError as err:
            debugdata = binascii.b2a_hex(data)
            error = f"Error getting checksum int from '{cmd}' data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        if datalen != checksum:
            debugdata = binascii.b2a_hex(data)
            error = f"Checksum on '{cmd}' failed checksum={checksum} datalen={datalen} data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        start_str = self.aps_str(data, 0, 3)
        end_str = self.aps_str(data, len(data) - 4, 3)

        if start_str != 'APS':
            debugdata = binascii.b2a_hex(data)
            error = f"Result on '{cmd}' incorrect start signature '{start_str}' != APS data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        if end_str != 'END':
            debugdata = binascii.b2a_hex(data)
            error = f"Result on '{cmd}' incorrect end signature '{end_str}' != END data={debugdata}"
            self.add_error(error)
            raise APSystemsInvalidData(error)

        return True

    def process_ecu_data(self, data=None):
        if not data:
            data = self.ecu_raw_data

        self.check_ecu_checksum(data, "ECU Query")
        self.ecu_id = self.aps_str(data, 13, 12)
        self.lifetime_energy = self.aps_double(data, 27) / 10
        self.current_power = self.aps_double(data, 31)
        self.today_energy = self.aps_double(data, 35) / 100
        if self.aps_str(data,25,2) == "01":
            self.qty_of_inverters = self.aps_int(data, 46)
            self.qty_of_online_inverters = self.aps_int(data, 48)
            self.vsl = int(self.aps_str(data, 52, 3))
            self.firmware = self.aps_str(data, 55, self.vsl)
            self.tsl = int(self.aps_str(data, 55 + self.vsl, 3))
            self.timezone = self.aps_str(data, 58 + self.vsl, self.tsl)
        elif self.aps_str(data,25,2) == "02":
            self.qty_of_inverters = self.aps_int(data, 39)
            self.qty_of_online_inverters = self.aps_int(data, 41)
            self.vsl = int(self.aps_str(data, 49, 3))
            self.firmware = self.aps_str(data, 52, self.vsl)

    def process_signal_data(self, data=None):
        signal_data = {}
        if self.inverter_raw_signal != '' and (self.aps_str(self.inverter_raw_signal,9,4)) == '0030':
            data = self.inverter_raw_signal
            _LOGGER.debug(binascii.b2a_hex(data))
            self.check_ecu_checksum(data, "Signal Query")
            if not self.qty_of_inverters:
                return signal_data
            location = 15
            for i in range(0, self.qty_of_inverters):
                uid = self.aps_uid(data, location)
                location += 6
                strength = data[location]
                location += 1
                strength = int((strength / 255) * 100)
                signal_data[uid] = strength
            return signal_data

    def process_inverter_data(self, data=None):
        if not data:
            data = self.inverter_raw_data

        self.check_ecu_checksum(data, "Inverter data")

        output = {}

        timestamp = self.aps_timestamp(data, 19, 14)
        inverter_qty = self.aps_int(data, 17)

        self.last_update = timestamp
        output["timestamp"] = timestamp
        output["inverter_qty"] = inverter_qty
        output["inverters"] = {}

        # this is the start of the loop of inverters
        istr = ''
        cnt2 = self.inverter_byte_start
        signal = self.process_signal_data()
        inverters = {}
        
        for i in range(0, inverter_qty):
            inv={}
            inverter_uid = self.aps_uid(data, cnt2)
            inv["uid"] = inverter_uid
            inv["online"] = bool(self.aps_short(data, cnt2 + 6))
            istr = self.aps_str(data, cnt2 + 7, 2)
            inv["signal"] = signal.get(inverter_uid, 0)
            inv["frequency"] = self.aps_int(data, cnt2 + 9) / 10
            inv["temperature"] = self.aps_int(data, cnt2 + 11) - 100
            if istr == '01' or istr == '04':
                (channel_data, cnt2) = self.process_yc600_ds3(data, cnt2)
                inv.update(channel_data)    
            elif istr == '02':
                (channel_data, cnt2) = self.process_yc1000(data, cnt2)
                inv.update(channel_data)
            elif istr == '03':
                (channel_data, cnt2) = self.process_qs1(data, cnt2)
                inv.update(channel_data)
            else:
                error = f"Unsupported inverter type {inverter_type} please create GitHub issue."
                self.add_error(error)
                raise APSystemsInvalidData(error)
            inverters[inverter_uid] = inv
        self.inverters = inverters
        output["inverters"] = inverters
        return (output)
    
    def process_yc1000(self, data, cnt2):
        power = []
        voltages = []
        power.append(self.aps_int(data, cnt2 + 13))
        voltages.append(self.aps_int(data, cnt2 + 15))
        power.append(self.aps_int(data, cnt2 + 17))
        voltages.append(self.aps_int(data, cnt2 + 19))
        power.append(self.aps_int(data, cnt2 + 21))
        voltages.append(self.aps_int(data, cnt2 + 23))
        power.append(self.aps_int(data, cnt2 + 25))
        output = {
            "model" : "YC1000",
            "channel_qty" : 4,
            "power" : power,
            "voltage" : voltages
        }
        return (output, cnt2)

    def process_qs1(self, data, cnt2):
        power = []
        voltages = []
        power.append(self.aps_int(data, cnt2 + 13))
        voltages.append(self.aps_int(data, cnt2 + 15))
        power.append(self.aps_int(data, cnt2 + 17))
        power.append(self.aps_int(data, cnt2 + 19))
        power.append(self.aps_int(data, cnt2 + 21))
        output = {
            "model" : "QS1",
            "channel_qty" : 4,
            "power" : power,
            "voltage" : voltages
        }
        return (output, cnt2)

    def process_yc600_ds3(self, data, cnt2):
        power = []
        voltages = []
        power.append(self.aps_int(data, cnt2 + 13))
        voltages.append(self.aps_int(data, cnt2 + 15))
        power.append(self.aps_int(data, cnt2 + 17))
        voltages.append(self.aps_int(data, cnt2 + 19))
        output = {
            "model" : "YC60/DS3-D-L",
            "channel_qty" : 2,
            "power" : power,
            "voltage" : voltages,
        }
        return (output, cnt2)

    def add_error(self, error):
        timestamp = datetime.datetime.now()

        self.errors.append("[{timestamp}] {error}")
Le second est le fichier ECU-B.py, que j'ai modifié selon mes besoins

Code : Tout sélectionner

#!/usr/bin/env python3
 
from APSystemsECU import APSystemsECU
import time
import asyncio
import urllib.request
import urllib.parse
import urllib
from pprint import pprint
 
#////////// START USER CONFIGURATION \\\\\\\\\\

#Change your ECU IP
ecu_ip = "192.168.1.44"

#Change your Domoticz IP
url = 'http://192.168.1.24:8080/json.htm?'

#Change your idx
Timestamp = 545
SolarGeneration = 540
SwitchInverter1 = 541
#SwitchInverter2 = 0
ConsumptionPannel1 = 542  #Inverter 1
ConsumptionPannel2 = 543  #Inverter 1
#ConsumptionPannel3 = 0  #Inverter 1 or 2
#ConsumptionPannel4 = 0  #Inverter 1 or 2
TemperatureInverter1 = 544
#TemperatureInverter2 = 0
SignalInverter1 = 546
#SignalInverter2 = 0
VoltageInverter1 = 547
#VoltageInverter2 = 0
FrequencyInverter1 = 548
#FrequencyInverter2 = 0

#\\\\\\\\\\ END USER CONFIGURATION //////////

#Communication delay to ECU (sec)

puntcomma = '\u003B'
loop = asyncio.get_event_loop()
ecu = APSystemsECU(ecu_ip)

data = loop.run_until_complete(ecu.async_query_ecu())
#pprint(data)
lifetime_energy = str(data.get('lifetime_energy')*1000)
today_energy = str(data.get('today_energy')*1000)
print('Today energy : ' + today_energy + ' Wh')
current_power = str(data.get('current_power'))
print('Current power: ' + current_power + ' W')
generated_energy = (current_power + puntcomma + lifetime_energy)
print('Total energy : ' + lifetime_energy + ' Wh')
if (float(today_energy) >= 0 or float(current_power) >= 0):
   getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': SolarGeneration, 'svalue': (generated_energy)}
   webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
   print(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': Timestamp, 'svalue': data.get('timestamp') + ' / ' + data.get('ecu_firmware')}
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#print(url + urllib.parse.urlencode(getVars))
#inverter values
inverters = data.get('inverters')
#count number of inverters
Inverter_qty = len(data.get('inverters'))
print('Number inverter: ' + str(Inverter_qty))
# loop trough all inverters and get the data
for i in range(Inverter_qty):
   Inverter = list(inverters.keys())[i]
   print('Inverter Id: ' + Inverter)
   InverterFrequency = data['inverters'][Inverter]['frequency']
   print('Frequency: ' + str(InverterFrequency) + ' Hz')
   InverterSignal = data['inverters'][Inverter]['signal']
   print('Signal: ' + str(InverterSignal) + ' %')
   InverterTemperature = data['inverters'][Inverter]['temperature']
   print('Temperature: ' + str(InverterTemperature) + ' °C')
   nPower = len(data['inverters'][Inverter]['power'])
   nVoltage = len(data['inverters'][Inverter]['voltage'])
   voltage = data['inverters'][Inverter]['voltage'][0]
   print('Voltage inverter ' + str(i + 1) + ' panel ' + str(1) + ': ' + str(voltage) + ' V')
   for x in range(nPower):
      power = data['inverters'][Inverter]['power'][x]
      print('Power inverter ' + str(i + 1) + ' panel ' + str(x + 1) + ': ' + str(power) + ' W')

     #upload values to Domoticz for inverter 1
      if (i == 0) and (x == 0) :
         if (float(InverterTemperature) > 0):
            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': TemperatureInverter1, 'svalue': InverterTemperature}
            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
         if (float(InverterFrequency) > 0):
            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': FrequencyInverter1, 'svalue': InverterFrequency}
            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': SignalInverter1, 'svalue': InverterSignal}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
         if (float(voltage) > 0):
            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': VoltageInverter1, 'svalue': (voltage)}
            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
         if InverterOnline == True :
            getVars = {'type' : 'command', 'param' : 'switchlight', 'idx': SwitchInverter1, 'switchcmd': 'On'}
         else :
            getVars = {'type' : 'command', 'param' : 'switchlight', 'idx': SwitchInverter1, 'switchcmd': 'Off'}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel1, 'svalue': (power)}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
      elif (i == 0) and (x == 1) :
         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel2, 'svalue': (power)}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
      elif (i == 0) and (x == 2) :
         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel3, 'svalue': (power)}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
      elif (i == 0) and (x == 3) :
         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel4, 'svalue': (power)}
         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')

     #upload values to Domoticz for inverter 2
#      if (i == 1) and (x == 0) :
#         if (float(InverterTemperature) > 0):
#            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': TemperatureInverter2, 'svalue': InverterTemperature}
#            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#         if (float(InverterFrequency) > 0):
#            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': FrequencyInverter2, 'svalue': InverterFrequency}
#            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': SignalInverter2, 'svalue': InverterSignal}
#         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#         if (float(voltage) > 0):
#            getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': VoltageInverter2, 'svalue': (voltage)}
#            webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
#         if InverterOnline == True :
#            getVars = {'type' : 'command', 'param' : 'switchlight', 'idx': SwitchInverter2, 'switchcmd': 'On'}
#         else :
#            getVars = {'type' : 'command', 'param' : 'switchlight', 'idx': SwitchInverter2, 'switchcmd': 'Off'}
#         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
#         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel3, 'svalue': (power)}
#         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
#      elif (i == 1) and (x == 1) :
#         getVars = {'type' : 'command', 'param' : 'udevice', 'nvalue' : 0, 'idx': ConsumptionPannel4, 'svalue': (power)}
#         webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars) + (puntcomma) + '0')
j'ai retenté de tester le script tel qu'indiqué surGithub GitHub et le résultat est différent d'hier avec tout de même des infos sur la prod du jour mais rien ne remonte dans mes devices.

Code : Tout sélectionner

pi@raspberrypi-domoticz:~/domoticz/scripts/python/ECU $ sudo python3 ECU-B.py
Today energy : 3170.0 Wh
Current power: 0 W
Total energy : 3100.0 Wh
Traceback (most recent call last):
  File "ECU-B.py", line 56, in <module>
    webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))
  File "/usr/lib/python3.7/urllib/request.py", line 222, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.7/urllib/request.py", line 531, in open
    response = meth(req, response)
  File "/usr/lib/python3.7/urllib/request.py", line 641, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.7/urllib/request.py", line 569, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.7/urllib/request.py", line 503, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.7/urllib/request.py", line 649, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: Unauthorized
pi@raspberrypi-domoticz:~/domoticz/scripts/python/ECU $ 
Je suis largué.
syl2222_fr
Messages : 47
Inscription : 14 janv. 2022, 20:02

Re: APsystems ECU-C - Domoticz

Message par syl2222_fr »

Alors, sans trop m'avancer

Tu as une erreur 401 :
urllib.error.HTTPError: HTTP Error 401: Unauthorized
dans le fichier File "ECU-B.py", line 56
Qui correspond à:
webUrl = urllib.request.urlopen(url + urllib.parse.urlencode(getVars))

La variable url correspond à :
#Change your Domoticz IP
url = 'http://192.168.1.24:8080/json.htm?'

Donc, ton domoticz . Est-ce que dans les logs de domoticz , tu vois ce log d'erreur ou de soucis d'authent au même moment ? Ton domoticz est openbar ou nécessite une authentification ?
Répondre