Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. KarlHeinz666

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    K
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 5
    • Best 1
    • Groups 1

    KarlHeinz666

    @KarlHeinz666

    Starter

    1
    Reputation
    6
    Profile views
    5
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    KarlHeinz666 Follow
    Starter

    Best posts made by KarlHeinz666

    • RE: MQTT Victron / venus.dbus-iobroker-smartmeter

      EDIT_30.08.2023: Habe endlich selber den Fehler gefunden und behoben. Da ich keine ausführliche Anleitung gefunden habe, baue ich diesen (meinen) Beitrag zu einer Anleitung um, damit andere es etwas einfacher haben.

      Anleitung: Iobroker als Smartmeter für Venus Os (Victron)

      Beschreibung:
      Ich habe mir einen DIY Akku mit dem Victron Multiplus II installiert. Zusätzlich verwende ich einen Raspberry PI 2B als Zentrale für das Venus OS.
      Das Problem an der Geschichte ist, dass man ein Smart Meter benötigt mit welchem das Venus OS kommunizieren kann. Da ich leider kein direkt unterstütztes Smart Meter besitze habe ich nach alternativen Lösung gesuch und bin auf das Projekt von "timostark" gestoßen.
      In diesem Projekt wird mit Hilfe des Iobroker ein Smart Meter emuliert. Die Anleitung ist leider nicht so ausführlich, und da ich mich mich linux kaum auskenne und viel Zeit benötigt habe, habe ich mich entschlossen eine eigene Anleitung zu erstellen.
      Es gibt einige Beiträge im www, die dieses Projekt erwähnen, es existiert leider keine "ausführliche" Installationsanleitung.

      Änderungen:
      Im Projekt von "timostark" werden die Spannungen für die Phasen 1 bis 3 mit ein und demselben Wert versorgt. Daraus wird auch für jede der 3 Phasen auch der Strom (Power_1/voltage; Power_2/voltage; Power_3/voltage), welcher dementsprechend einen Fehler aufweist. Es kann sein, dass einige Smart Meter es nicht hergeben, dass man alle drei Spannung der Phasen zur verfügung hat, bei mir ist dies der Fall. Deshalb habe ich veränderungen am Code durchgeführt, damit für jede Phase die zugehörige Spannung verwendet wird.

      IOBROKER:

      1. Die benötigten Objekte erstellen, falls diese noch nicht vorhanden sind. Ich habe mir extra unter dem Baum "alias" die folgenden Objekte erstellt:
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseA
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseB
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseC
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_1
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_2
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_3
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Sold
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Bought

      Screenshot 2023-08-30 172609.png
      Zusätzlich weitere statische Objekte, wie die ID und die Objekte "Bought" und "Sold", die ich nicht benötige.
      Screenshot 2023-08-30 172924.png

      1. Auf dem iobroker habe ich den Adaper „simple-API“ installiert. Die Konfiguration des Adapters so gelassen wie sie ist.
        Screenshot 2023-08-30 171312.png

      2. Den „simple-API“ Adapter getestet:

      • Habe hierfür ein Objekt angelegt und den Bespielwert „11“ gegeben:
        0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID = 11
      • Mit dem Befehl im Browser konnte ich erfolgreich das Objekt auslesen:
        http://192.168.178.194:8087/get/0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
        Die IP ist die IP vom iobroker mit dem Port des „simple-API“ Adapters „8087“
        Screenshot 2023-08-30 171630.png

      RPI2 (Venus OS V3.01)

      1. Superuser Passwort vergeben und SSH aktrivieren.
        Unter Einstellungen->Allgemein
        Screenshot 2023-08-30 171918.png
        Hier ca. 5 Sekunden lang den Pfeil nach rechts gedrückt halten. Dann wird das Setzen des Superuser Passworts und das Aktivieren des SSH freigeschaltet. Hier ein Passwort vergeben und SSH aktivieren.
        Screenshot 2023-08-30 173317.png
        Screenshot 2023-08-30 173655.png

      2. Auf der Seite von Github (https://github.com/timostark/venus.dbus-iobroker-smartmeter) das Projekt heruntergeladen. Und die config.ini folgend verändern.

      [DEFAULT]
      SignOfLifeLog = 1
      IOBrokerPathSmartMeterId = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
      IOBrokerPathOverallConsumption = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport
      IOBrokerPathPhase1 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseA
      IOBrokerPathPhase2 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseB
      IOBrokerPathPhase3 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseC
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage1
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage2
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage3
      IOBrokerPathGridSold = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Sold
      IOBrokerPathGridBought = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Bought
      IOBrokerHostPath = http://192.168.178.194:8087
      
      1. Die Datei "dbus-iobroker-smartmeter.py" um die Spannung_Phase_2 und Spannung_Phase_3 erweitern. Dies kann ausgelassen werden, falls man diese nicht benötigt.
      #!/usr/bin/env python
      
      # import normal packages
      from vedbus import VeDbusService
      import platform
      import logging
      import sys
      import os
      import sys
      if sys.version_info.major == 2:
          import gobject
      else:
          from gi.repository import GLib as gobject
      import sys
      import time
      import requests  # for http GET
      import configparser  # for config/ini file
      import struct
      
      # our own packages from victron
      sys.path.insert(1, os.path.join(os.path.dirname(__file__),
                      '/opt/victronenergy/dbus-systemcalc-py/ext/velib_python'))
      
      
      class DbusIobrokerSmartmeterService:
          def __init__(self, servicename, deviceinstance, paths, productname='Smartmeter Reader', connection='Smartmeter via IOBroker HTTP JSON service'):
              self._dbusservice = VeDbusService(
                  "{}.http_{:02d}".format(servicename, deviceinstance))
              self._paths = paths
      
              self._config = self._getConfig()
      
              # get data from Senec
              meter_data = self._getIOBrokerSmartmeterData()
      
              self.grid_sold_start = next((x for x in meter_data if x['id'] ==
                                           self._getSmartMeterGridSold()), None)['val']
              self.grid_bought_start = next((x for x in meter_data if x['id'] ==
                                             self._getSmartMeterGridBought()), None)['val']
      
              logging.debug("%s /DeviceInstance = %d" %
                            (servicename, deviceinstance))
      
              # debug:
              #logging.info("Senec serial: %s" % (self._getSenecSerial()))
      
              # Create the management objects, as specified in the ccgx dbus-api document
              self._dbusservice.add_path('/Mgmt/ProcessName', __file__)
              self._dbusservice.add_path(
                  '/Mgmt/ProcessVersion', 'Unkown version, and running on Python ' + platform.python_version())
              self._dbusservice.add_path('/Mgmt/Connection', connection)
      
              # Create the mandatory objects
              self._dbusservice.add_path('/DeviceInstance', deviceinstance)
              # self._dbusservice.add_path('/ProductId', 16) # value used in ac_sensor_bridge.cpp of dbus-cgwacs
              # self._dbusservice.add_path('/ProductId', 0xFFFF) # id assigned by Victron Support from SDM630v2.py
              # found on https://www.sascha-curth.de/projekte/005_Color_Control_GX.html#experiment - should be an ET340 Engerie Meter
              self._dbusservice.add_path('/ProductId', 45069)
              # found on https://www.sascha-curth.de/projekte/005_Color_Control_GX.html#experiment - should be an ET340 Engerie Meter
              self._dbusservice.add_path('/DeviceType', 345)
              self._dbusservice.add_path('/ProductName', productname)
              self._dbusservice.add_path('/CustomName', productname)
              self._dbusservice.add_path('/Latency', None)
              self._dbusservice.add_path('/FirmwareVersion', 0.1)
              self._dbusservice.add_path('/HardwareVersion', 0)
              self._dbusservice.add_path('/Connected', 1)
              self._dbusservice.add_path('/Role', 'grid')
              # normaly only needed for pvinverter
              self._dbusservice.add_path('/Position', 0)
              self._dbusservice.add_path('/Serial', self._getSmartMeterSerial())
              self._dbusservice.add_path('/UpdateIndex', 0)
      
              # add path values to dbus
              for path, settings in self._paths.items():
                  self._dbusservice.add_path(
                      path, settings['initial'], gettextcallback=settings['textformat'], writeable=True, onchangecallback=self._handlechangedvalue)
      
              # last update
              self._lastUpdate = 0
      
              # add _update function 'timer'
              # pause 1000ms before the next request
              gobject.timeout_add(500, self._update)
      
              # add _signOfLife 'timer' to get feedback in log every 5minutes
              gobject.timeout_add(self._getSignOfLifeInterval()
                                  * 60*1000, self._signOfLife)
      
          def _getSmartMeterSerial(self):
              meter_data = self._getIOBrokerSmartmeterData()
      
              device_id = next(
                  (x for x in meter_data if x['id'] == self._getSmartMeterDeviceId()), None)
      
              if not device_id['val']:
                  raise ValueError(
                      "Response does not contain 'DEVICE_ID' attribute")
      
              serial = device_id['val']
              return serial
      
          def _getConfig(self):
              config = configparser.ConfigParser()
              config.read("%s/config.ini" %
                          (os.path.dirname(os.path.realpath(__file__))))
              return config
      
          def _getSignOfLifeInterval(self):
              value = self._config['DEFAULT']['SignOfLifeLog']
      
              if not value:
                  value = 0
      
              return int(value)
      
          def _getSmartMeterDeviceId(self):
              value = self._config['DEFAULT']['IOBrokerPathSmartMeterId']
              return value
      
          def _getSmartMeterOverallConsumption(self):
              value = self._config['DEFAULT']['IOBrokerPathOverallConsumption']
              return value
      
          def _getSmartMeterPhase1Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase1']
              return value
      
          def _getSmartMeterPhase2Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase2']
              return value
      
          def _getSmartMeterPhase3Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase3']
              return value
      
          def _getSmartMeterGridSold(self):
              value = self._config['DEFAULT']['IOBrokerPathGridSold']
              return value
      
          def _getSmartMeterGridBought(self):
              value = self._config['DEFAULT']['IOBrokerPathGridBought']
              return value
      
          def _getSmartMeterVoltage1(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage1']
              return value
          
          def _getSmartMeterVoltage2(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage2']
              return value
          
          def _getSmartMeterVoltage3(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage3']
              return value
      
          def _getIOBrokerPath(self):
              value = self._config['DEFAULT']['IOBrokerHostPath']
              return value
      
          def _getIOBrokerSmartmeterData(self):
              URL = self._getIOBrokerPath() + "/getBulk/" + self._getSmartMeterDeviceId() + "," + self._getSmartMeterOverallConsumption() + "," + \
                  self._getSmartMeterPhase1Consumption() + "," + self._getSmartMeterPhase2Consumption() + \
                  "," + self._getSmartMeterPhase3Consumption() + "," + self._getSmartMeterGridBought() + \
                  "," + self._getSmartMeterGridSold() + "," + self._getSmartMeterVoltage1() + \
                  "," + self._getSmartMeterVoltage2() + "," + self._getSmartMeterVoltage3()
      
              headers = {}
      
              meter_r = requests.request("GET", URL, headers=headers)
      
              # check for response
              if not meter_r:
                  raise ConnectionError("No response from IOBroker - %s" % (URL))
      
              meter_data = meter_r.json()
      
              # check for Json
              if not meter_data:
                  raise ValueError("Converting response to JSON failed")
      
              return meter_data
      
          def _floatFromHex(self, val):
      
              return struct.unpack('!f', bytes.fromhex(val[3:]))[0]
              #struct.unpack('!f', (val[3:]).decode('hex'))[0]
      
          def _signOfLife(self):
              logging.info("--- Start: sign of life ---")
              logging.info("Last _update() call: %s" % (self._lastUpdate))
              ##logging.info("Last '/Ac/Power': %s" % (self._dbusservice['/Ac/Power']))
              logging.info("--- End: sign of life ---")
              return True
      
          def _update(self):
              try:
                  # get data from Senec
                  meter_data = self._getIOBrokerSmartmeterData()
      
                  # send data to DBus
                  total_value = next(
                      (x for x in meter_data if x['id'] == self._getSmartMeterOverallConsumption()), None)['val']
                  phase_1 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase1Consumption()), None)['val']
                  phase_2 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase2Consumption()), None)['val']
                  phase_3 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase3Consumption()), None)['val']
                  grid_sold = next((x for x in meter_data if x['id'] ==
                                    self._getSmartMeterGridSold()), None)['val'] - self.grid_sold_start
                  grid_bought = next((x for x in meter_data if x['id'] ==
                                      self._getSmartMeterGridBought()), None)['val'] - self.grid_bought_start
                  voltage1 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage1()), None)['val']
                  voltage2 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage2()), None)['val']
                  voltage3 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage3()), None)['val']
      
                  # positive: consumption, negative: feed into grid
                  self._dbusservice['/Ac/Power'] = total_value
                  self._dbusservice['/Ac/L1/Voltage'] = voltage1
                  self._dbusservice['/Ac/L2/Voltage'] = voltage2
                  self._dbusservice['/Ac/L3/Voltage'] = voltage3
                  self._dbusservice['/Ac/L1/Current'] = phase_1 / voltage1
                  self._dbusservice['/Ac/L2/Current'] = phase_2 / voltage2
                  self._dbusservice['/Ac/L3/Current'] = phase_3 / voltage3
                  self._dbusservice['/Ac/L1/Power'] = phase_1
                  self._dbusservice['/Ac/L2/Power'] = phase_2
                  self._dbusservice['/Ac/L3/Power'] = phase_3
      
                  self._dbusservice['/Ac/Current'] = phase_1 / voltage1 + phase_2 / voltage2 + phase_3 / voltage3
                  self._dbusservice['/Ac/Voltage'] = phase_3
      
                  ##self._dbusservice['/Ac/L1/Energy/Forward'] = (meter_data['emeters'][0]['total']/1000)
                  self._dbusservice['/Ac/Energy/Forward'] = grid_bought
                  self._dbusservice['/Ac/Energy/Reverse'] = grid_sold
      
                  # logging
                  ##logging.info("House Consumption (/Ac/Power): %s" % (self._dbusservice['/Ac/Power']))
                  #logging.info("L1: %s L2: %s L3: %s" % (self._dbusservice['/Ac/L1/Power'],self._dbusservice['/Ac/L2/Power'],self._dbusservice['/Ac/L3/Power']))
                  ##logging.debug("House Forward (/Ac/Energy/Forward): %s" % (self._dbusservice['/Ac/Energy/Forward']))
                  ##logging.debug("House Reverse (/Ac/Energy/Revers): %s" % (self._dbusservice['/Ac/Energy/Reverse']))
                  # logging.debug("---");
      
                  # increment UpdateIndex - to show that new data is available
                  index = self._dbusservice['/UpdateIndex'] + 1  # increment index
                  if index > 255:   # maximum value of the index
                      index = 0       # overflow from 255 to 0
                  self._dbusservice['/UpdateIndex'] = index
      
                  # update lastupdate vars
                  self._lastUpdate = time.time()
              except Exception as e:
                  logging.critical('Error at %s', '_update', exc_info=e)
      
              # return true, otherwise add_timeout will be removed from GObject - see docs http://library.isr.ist.utl.pt/docs/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
              return True
      
          def _handlechangedvalue(self, path, value):
              logging.debug("someone else updated %s to %s" % (path, value))
              return True  # accept the change
      
      
      def main():
          # configure logging
          logging.basicConfig(format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                              datefmt='%Y-%m-%d %H:%M:%S',
                              level=logging.INFO,
                              handlers=[
                                  logging.FileHandler(
                                      "%s/current.log" % (os.path.dirname(os.path.realpath(__file__)))),
                                  logging.StreamHandler()
                              ])
      
          try:
              logging.info("Start")
      
              from dbus.mainloop.glib import DBusGMainLoop
              # Have a mainloop, so we can send/receive asynchronous calls to and from dbus
              DBusGMainLoop(set_as_default=True)
      
              # formatting
              def _kwh(p, v): return (str(round(v, 2)) + ' KWh')
              def _a(p, v): return (str(round(v, 1)) + ' A')
              def _w(p, v): return (str(round(v, 1)) + ' W')
              def _v(p, v): return (str(round(v, 1)) + ' V')
      
              # start our main-service
              pvac_output = DbusIobrokerSmartmeterService(
                  servicename='com.victronenergy.grid',
                  deviceinstance=40,
                  paths={
                      # energy bought from the grid
                      '/Ac/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      # energy sold to the grid
                      '/Ac/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/Power': {'initial': 0, 'textformat': _w},
      
                      '/Ac/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/Voltage': {'initial': 0, 'textformat': _v},
      
                      '/Ac/L1/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L2/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L3/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L1/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L2/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L3/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L1/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L2/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L3/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L1/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L2/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L3/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L1/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L2/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L3/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                  })
      
              logging.info(
                  'Connected to dbus, and switching over to gobject.MainLoop() (= event based)')
              mainloop = gobject.MainLoop()
              mainloop.run()
          except Exception as e:
              logging.critical('Error at %s', 'main', exc_info=e)
      
      
      if __name__ == "__main__":
          main()
      
      
      1. Dateien auf den RPI2 kopieren (Ordnernamen nicht verändern!).
        Mit „filezilla“ auf den Raspberry, mit dem vergebenen Passwort, eingeloggen und das modifizierte Projekt von „timostark“ in das Verzeichnis
        "data/dbus-iobroker-smartmeter" kopieren.
        Screenshot 2023-08-30 175449.png

      2. Mit dem Tool „Putty“ sich auf dem RPi2 einloggen.

      3. In das hinzugefügte Verzeichnis wechseln:

      cd data/dbus-iobroker-smartmeeter
      

      Screenshot 2023-08-30 175733.png

      1. Der „install.sh“ Ausführungsrechte vergeben.
      chmod +x install.sh
      
      1. Instllation des Smartmeter.
      ./install.sh
      

      Screenshot 2023-08-30 180113.png

      Nun sollte der "Smartmeter Reader" Venus OS auftauchen.
      Screenshot 2023-08-30 180226.png

      Screenshot 2023-08-30 180300.png

      Ich hoffe, dass ich den einen oder anderen damit helfen kann.

      Gruß
      KarlHeinz

      posted in ioBroker Allgemein
      K
      KarlHeinz666

    Latest posts made by KarlHeinz666

    • RE: MQTT Victron / venus.dbus-iobroker-smartmeter

      EDIT_30.08.2023: Habe endlich selber den Fehler gefunden und behoben. Da ich keine ausführliche Anleitung gefunden habe, baue ich diesen (meinen) Beitrag zu einer Anleitung um, damit andere es etwas einfacher haben.

      Anleitung: Iobroker als Smartmeter für Venus Os (Victron)

      Beschreibung:
      Ich habe mir einen DIY Akku mit dem Victron Multiplus II installiert. Zusätzlich verwende ich einen Raspberry PI 2B als Zentrale für das Venus OS.
      Das Problem an der Geschichte ist, dass man ein Smart Meter benötigt mit welchem das Venus OS kommunizieren kann. Da ich leider kein direkt unterstütztes Smart Meter besitze habe ich nach alternativen Lösung gesuch und bin auf das Projekt von "timostark" gestoßen.
      In diesem Projekt wird mit Hilfe des Iobroker ein Smart Meter emuliert. Die Anleitung ist leider nicht so ausführlich, und da ich mich mich linux kaum auskenne und viel Zeit benötigt habe, habe ich mich entschlossen eine eigene Anleitung zu erstellen.
      Es gibt einige Beiträge im www, die dieses Projekt erwähnen, es existiert leider keine "ausführliche" Installationsanleitung.

      Änderungen:
      Im Projekt von "timostark" werden die Spannungen für die Phasen 1 bis 3 mit ein und demselben Wert versorgt. Daraus wird auch für jede der 3 Phasen auch der Strom (Power_1/voltage; Power_2/voltage; Power_3/voltage), welcher dementsprechend einen Fehler aufweist. Es kann sein, dass einige Smart Meter es nicht hergeben, dass man alle drei Spannung der Phasen zur verfügung hat, bei mir ist dies der Fall. Deshalb habe ich veränderungen am Code durchgeführt, damit für jede Phase die zugehörige Spannung verwendet wird.

      IOBROKER:

      1. Die benötigten Objekte erstellen, falls diese noch nicht vorhanden sind. Ich habe mir extra unter dem Baum "alias" die folgenden Objekte erstellt:
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseA
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseB
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseC
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_1
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_2
      • alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.InOutVoltage_3
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Sold
      • 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Bought

      Screenshot 2023-08-30 172609.png
      Zusätzlich weitere statische Objekte, wie die ID und die Objekte "Bought" und "Sold", die ich nicht benötige.
      Screenshot 2023-08-30 172924.png

      1. Auf dem iobroker habe ich den Adaper „simple-API“ installiert. Die Konfiguration des Adapters so gelassen wie sie ist.
        Screenshot 2023-08-30 171312.png

      2. Den „simple-API“ Adapter getestet:

      • Habe hierfür ein Objekt angelegt und den Bespielwert „11“ gegeben:
        0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID = 11
      • Mit dem Befehl im Browser konnte ich erfolgreich das Objekt auslesen:
        http://192.168.178.194:8087/get/0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
        Die IP ist die IP vom iobroker mit dem Port des „simple-API“ Adapters „8087“
        Screenshot 2023-08-30 171630.png

      RPI2 (Venus OS V3.01)

      1. Superuser Passwort vergeben und SSH aktrivieren.
        Unter Einstellungen->Allgemein
        Screenshot 2023-08-30 171918.png
        Hier ca. 5 Sekunden lang den Pfeil nach rechts gedrückt halten. Dann wird das Setzen des Superuser Passworts und das Aktivieren des SSH freigeschaltet. Hier ein Passwort vergeben und SSH aktivieren.
        Screenshot 2023-08-30 173317.png
        Screenshot 2023-08-30 173655.png

      2. Auf der Seite von Github (https://github.com/timostark/venus.dbus-iobroker-smartmeter) das Projekt heruntergeladen. Und die config.ini folgend verändern.

      [DEFAULT]
      SignOfLifeLog = 1
      IOBrokerPathSmartMeterId = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.ID
      IOBrokerPathOverallConsumption = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport
      IOBrokerPathPhase1 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseA
      IOBrokerPathPhase2 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseB
      IOBrokerPathPhase3 = alias.0.Haus.Strom.Leistungsfluss.SmartMeeter.NetzExport_PhaseC
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage1
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage2
      IOBrokerPathVoltage = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Inout_Voltage3
      IOBrokerPathGridSold = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Sold
      IOBrokerPathGridBought = 0_userdata.0.Haus.Strom.Leistungsfluss.SmartMeeter.Bought
      IOBrokerHostPath = http://192.168.178.194:8087
      
      1. Die Datei "dbus-iobroker-smartmeter.py" um die Spannung_Phase_2 und Spannung_Phase_3 erweitern. Dies kann ausgelassen werden, falls man diese nicht benötigt.
      #!/usr/bin/env python
      
      # import normal packages
      from vedbus import VeDbusService
      import platform
      import logging
      import sys
      import os
      import sys
      if sys.version_info.major == 2:
          import gobject
      else:
          from gi.repository import GLib as gobject
      import sys
      import time
      import requests  # for http GET
      import configparser  # for config/ini file
      import struct
      
      # our own packages from victron
      sys.path.insert(1, os.path.join(os.path.dirname(__file__),
                      '/opt/victronenergy/dbus-systemcalc-py/ext/velib_python'))
      
      
      class DbusIobrokerSmartmeterService:
          def __init__(self, servicename, deviceinstance, paths, productname='Smartmeter Reader', connection='Smartmeter via IOBroker HTTP JSON service'):
              self._dbusservice = VeDbusService(
                  "{}.http_{:02d}".format(servicename, deviceinstance))
              self._paths = paths
      
              self._config = self._getConfig()
      
              # get data from Senec
              meter_data = self._getIOBrokerSmartmeterData()
      
              self.grid_sold_start = next((x for x in meter_data if x['id'] ==
                                           self._getSmartMeterGridSold()), None)['val']
              self.grid_bought_start = next((x for x in meter_data if x['id'] ==
                                             self._getSmartMeterGridBought()), None)['val']
      
              logging.debug("%s /DeviceInstance = %d" %
                            (servicename, deviceinstance))
      
              # debug:
              #logging.info("Senec serial: %s" % (self._getSenecSerial()))
      
              # Create the management objects, as specified in the ccgx dbus-api document
              self._dbusservice.add_path('/Mgmt/ProcessName', __file__)
              self._dbusservice.add_path(
                  '/Mgmt/ProcessVersion', 'Unkown version, and running on Python ' + platform.python_version())
              self._dbusservice.add_path('/Mgmt/Connection', connection)
      
              # Create the mandatory objects
              self._dbusservice.add_path('/DeviceInstance', deviceinstance)
              # self._dbusservice.add_path('/ProductId', 16) # value used in ac_sensor_bridge.cpp of dbus-cgwacs
              # self._dbusservice.add_path('/ProductId', 0xFFFF) # id assigned by Victron Support from SDM630v2.py
              # found on https://www.sascha-curth.de/projekte/005_Color_Control_GX.html#experiment - should be an ET340 Engerie Meter
              self._dbusservice.add_path('/ProductId', 45069)
              # found on https://www.sascha-curth.de/projekte/005_Color_Control_GX.html#experiment - should be an ET340 Engerie Meter
              self._dbusservice.add_path('/DeviceType', 345)
              self._dbusservice.add_path('/ProductName', productname)
              self._dbusservice.add_path('/CustomName', productname)
              self._dbusservice.add_path('/Latency', None)
              self._dbusservice.add_path('/FirmwareVersion', 0.1)
              self._dbusservice.add_path('/HardwareVersion', 0)
              self._dbusservice.add_path('/Connected', 1)
              self._dbusservice.add_path('/Role', 'grid')
              # normaly only needed for pvinverter
              self._dbusservice.add_path('/Position', 0)
              self._dbusservice.add_path('/Serial', self._getSmartMeterSerial())
              self._dbusservice.add_path('/UpdateIndex', 0)
      
              # add path values to dbus
              for path, settings in self._paths.items():
                  self._dbusservice.add_path(
                      path, settings['initial'], gettextcallback=settings['textformat'], writeable=True, onchangecallback=self._handlechangedvalue)
      
              # last update
              self._lastUpdate = 0
      
              # add _update function 'timer'
              # pause 1000ms before the next request
              gobject.timeout_add(500, self._update)
      
              # add _signOfLife 'timer' to get feedback in log every 5minutes
              gobject.timeout_add(self._getSignOfLifeInterval()
                                  * 60*1000, self._signOfLife)
      
          def _getSmartMeterSerial(self):
              meter_data = self._getIOBrokerSmartmeterData()
      
              device_id = next(
                  (x for x in meter_data if x['id'] == self._getSmartMeterDeviceId()), None)
      
              if not device_id['val']:
                  raise ValueError(
                      "Response does not contain 'DEVICE_ID' attribute")
      
              serial = device_id['val']
              return serial
      
          def _getConfig(self):
              config = configparser.ConfigParser()
              config.read("%s/config.ini" %
                          (os.path.dirname(os.path.realpath(__file__))))
              return config
      
          def _getSignOfLifeInterval(self):
              value = self._config['DEFAULT']['SignOfLifeLog']
      
              if not value:
                  value = 0
      
              return int(value)
      
          def _getSmartMeterDeviceId(self):
              value = self._config['DEFAULT']['IOBrokerPathSmartMeterId']
              return value
      
          def _getSmartMeterOverallConsumption(self):
              value = self._config['DEFAULT']['IOBrokerPathOverallConsumption']
              return value
      
          def _getSmartMeterPhase1Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase1']
              return value
      
          def _getSmartMeterPhase2Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase2']
              return value
      
          def _getSmartMeterPhase3Consumption(self):
              value = self._config['DEFAULT']['IOBrokerPathPhase3']
              return value
      
          def _getSmartMeterGridSold(self):
              value = self._config['DEFAULT']['IOBrokerPathGridSold']
              return value
      
          def _getSmartMeterGridBought(self):
              value = self._config['DEFAULT']['IOBrokerPathGridBought']
              return value
      
          def _getSmartMeterVoltage1(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage1']
              return value
          
          def _getSmartMeterVoltage2(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage2']
              return value
          
          def _getSmartMeterVoltage3(self):
              value = self._config['DEFAULT']['IOBrokerPathVoltage3']
              return value
      
          def _getIOBrokerPath(self):
              value = self._config['DEFAULT']['IOBrokerHostPath']
              return value
      
          def _getIOBrokerSmartmeterData(self):
              URL = self._getIOBrokerPath() + "/getBulk/" + self._getSmartMeterDeviceId() + "," + self._getSmartMeterOverallConsumption() + "," + \
                  self._getSmartMeterPhase1Consumption() + "," + self._getSmartMeterPhase2Consumption() + \
                  "," + self._getSmartMeterPhase3Consumption() + "," + self._getSmartMeterGridBought() + \
                  "," + self._getSmartMeterGridSold() + "," + self._getSmartMeterVoltage1() + \
                  "," + self._getSmartMeterVoltage2() + "," + self._getSmartMeterVoltage3()
      
              headers = {}
      
              meter_r = requests.request("GET", URL, headers=headers)
      
              # check for response
              if not meter_r:
                  raise ConnectionError("No response from IOBroker - %s" % (URL))
      
              meter_data = meter_r.json()
      
              # check for Json
              if not meter_data:
                  raise ValueError("Converting response to JSON failed")
      
              return meter_data
      
          def _floatFromHex(self, val):
      
              return struct.unpack('!f', bytes.fromhex(val[3:]))[0]
              #struct.unpack('!f', (val[3:]).decode('hex'))[0]
      
          def _signOfLife(self):
              logging.info("--- Start: sign of life ---")
              logging.info("Last _update() call: %s" % (self._lastUpdate))
              ##logging.info("Last '/Ac/Power': %s" % (self._dbusservice['/Ac/Power']))
              logging.info("--- End: sign of life ---")
              return True
      
          def _update(self):
              try:
                  # get data from Senec
                  meter_data = self._getIOBrokerSmartmeterData()
      
                  # send data to DBus
                  total_value = next(
                      (x for x in meter_data if x['id'] == self._getSmartMeterOverallConsumption()), None)['val']
                  phase_1 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase1Consumption()), None)['val']
                  phase_2 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase2Consumption()), None)['val']
                  phase_3 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterPhase3Consumption()), None)['val']
                  grid_sold = next((x for x in meter_data if x['id'] ==
                                    self._getSmartMeterGridSold()), None)['val'] - self.grid_sold_start
                  grid_bought = next((x for x in meter_data if x['id'] ==
                                      self._getSmartMeterGridBought()), None)['val'] - self.grid_bought_start
                  voltage1 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage1()), None)['val']
                  voltage2 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage2()), None)['val']
                  voltage3 = next((x for x in meter_data if x['id'] ==
                                  self._getSmartMeterVoltage3()), None)['val']
      
                  # positive: consumption, negative: feed into grid
                  self._dbusservice['/Ac/Power'] = total_value
                  self._dbusservice['/Ac/L1/Voltage'] = voltage1
                  self._dbusservice['/Ac/L2/Voltage'] = voltage2
                  self._dbusservice['/Ac/L3/Voltage'] = voltage3
                  self._dbusservice['/Ac/L1/Current'] = phase_1 / voltage1
                  self._dbusservice['/Ac/L2/Current'] = phase_2 / voltage2
                  self._dbusservice['/Ac/L3/Current'] = phase_3 / voltage3
                  self._dbusservice['/Ac/L1/Power'] = phase_1
                  self._dbusservice['/Ac/L2/Power'] = phase_2
                  self._dbusservice['/Ac/L3/Power'] = phase_3
      
                  self._dbusservice['/Ac/Current'] = phase_1 / voltage1 + phase_2 / voltage2 + phase_3 / voltage3
                  self._dbusservice['/Ac/Voltage'] = phase_3
      
                  ##self._dbusservice['/Ac/L1/Energy/Forward'] = (meter_data['emeters'][0]['total']/1000)
                  self._dbusservice['/Ac/Energy/Forward'] = grid_bought
                  self._dbusservice['/Ac/Energy/Reverse'] = grid_sold
      
                  # logging
                  ##logging.info("House Consumption (/Ac/Power): %s" % (self._dbusservice['/Ac/Power']))
                  #logging.info("L1: %s L2: %s L3: %s" % (self._dbusservice['/Ac/L1/Power'],self._dbusservice['/Ac/L2/Power'],self._dbusservice['/Ac/L3/Power']))
                  ##logging.debug("House Forward (/Ac/Energy/Forward): %s" % (self._dbusservice['/Ac/Energy/Forward']))
                  ##logging.debug("House Reverse (/Ac/Energy/Revers): %s" % (self._dbusservice['/Ac/Energy/Reverse']))
                  # logging.debug("---");
      
                  # increment UpdateIndex - to show that new data is available
                  index = self._dbusservice['/UpdateIndex'] + 1  # increment index
                  if index > 255:   # maximum value of the index
                      index = 0       # overflow from 255 to 0
                  self._dbusservice['/UpdateIndex'] = index
      
                  # update lastupdate vars
                  self._lastUpdate = time.time()
              except Exception as e:
                  logging.critical('Error at %s', '_update', exc_info=e)
      
              # return true, otherwise add_timeout will be removed from GObject - see docs http://library.isr.ist.utl.pt/docs/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
              return True
      
          def _handlechangedvalue(self, path, value):
              logging.debug("someone else updated %s to %s" % (path, value))
              return True  # accept the change
      
      
      def main():
          # configure logging
          logging.basicConfig(format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                              datefmt='%Y-%m-%d %H:%M:%S',
                              level=logging.INFO,
                              handlers=[
                                  logging.FileHandler(
                                      "%s/current.log" % (os.path.dirname(os.path.realpath(__file__)))),
                                  logging.StreamHandler()
                              ])
      
          try:
              logging.info("Start")
      
              from dbus.mainloop.glib import DBusGMainLoop
              # Have a mainloop, so we can send/receive asynchronous calls to and from dbus
              DBusGMainLoop(set_as_default=True)
      
              # formatting
              def _kwh(p, v): return (str(round(v, 2)) + ' KWh')
              def _a(p, v): return (str(round(v, 1)) + ' A')
              def _w(p, v): return (str(round(v, 1)) + ' W')
              def _v(p, v): return (str(round(v, 1)) + ' V')
      
              # start our main-service
              pvac_output = DbusIobrokerSmartmeterService(
                  servicename='com.victronenergy.grid',
                  deviceinstance=40,
                  paths={
                      # energy bought from the grid
                      '/Ac/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      # energy sold to the grid
                      '/Ac/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/Power': {'initial': 0, 'textformat': _w},
      
                      '/Ac/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/Voltage': {'initial': 0, 'textformat': _v},
      
                      '/Ac/L1/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L2/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L3/Voltage': {'initial': 0, 'textformat': _v},
                      '/Ac/L1/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L2/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L3/Current': {'initial': 0, 'textformat': _a},
                      '/Ac/L1/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L2/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L3/Power': {'initial': 0, 'textformat': _w},
                      '/Ac/L1/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L2/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L3/Energy/Forward': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L1/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L2/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                      '/Ac/L3/Energy/Reverse': {'initial': 0, 'textformat': _kwh},
                  })
      
              logging.info(
                  'Connected to dbus, and switching over to gobject.MainLoop() (= event based)')
              mainloop = gobject.MainLoop()
              mainloop.run()
          except Exception as e:
              logging.critical('Error at %s', 'main', exc_info=e)
      
      
      if __name__ == "__main__":
          main()
      
      
      1. Dateien auf den RPI2 kopieren (Ordnernamen nicht verändern!).
        Mit „filezilla“ auf den Raspberry, mit dem vergebenen Passwort, eingeloggen und das modifizierte Projekt von „timostark“ in das Verzeichnis
        "data/dbus-iobroker-smartmeter" kopieren.
        Screenshot 2023-08-30 175449.png

      2. Mit dem Tool „Putty“ sich auf dem RPi2 einloggen.

      3. In das hinzugefügte Verzeichnis wechseln:

      cd data/dbus-iobroker-smartmeeter
      

      Screenshot 2023-08-30 175733.png

      1. Der „install.sh“ Ausführungsrechte vergeben.
      chmod +x install.sh
      
      1. Instllation des Smartmeter.
      ./install.sh
      

      Screenshot 2023-08-30 180113.png

      Nun sollte der "Smartmeter Reader" Venus OS auftauchen.
      Screenshot 2023-08-30 180226.png

      Screenshot 2023-08-30 180300.png

      Ich hoffe, dass ich den einen oder anderen damit helfen kann.

      Gruß
      KarlHeinz

      posted in ioBroker Allgemein
      K
      KarlHeinz666
    • RE: [gelöst] Iobroker erkennt nur 4GB statt 8GB RPI4

      @djmarc75 said in Iobroker erkennt nur 4GB RAM statt 8GB auf RPI4 nach update:

      Das auch nicht... aber setze bitte im Titel ein [gelöst] davor

      Der Titel ist dann zu lang, oder gibt es hierfür eine zusätzliche Funktion, die ich nicht kenne?

      posted in Error/Bug
      K
      KarlHeinz666
    • RE: [gelöst] Iobroker erkennt nur 4GB statt 8GB RPI4

      @djmarc75

      Ach verdammt... Asche auf mein Haupt!!!! Habe den falschen RPi4 dran und habe vor lauter Bäume nicht mal gesehen.
      Jetzt kann man mich steinigen! 😨

      Edit: Am besten den Post löschen, damit andere nicht verwirrt werden.

      posted in Error/Bug
      K
      KarlHeinz666
    • RE: [gelöst] Iobroker erkennt nur 4GB statt 8GB RPI4

      @thomas-braun

      "iob diag" sagt:

      Skript v.2023-01-02
      
      *** BASE SYSTEM ***
      Model           : Raspberry Pi 4 Model B Rev 1.2
      Architecture:   armv7l
      Docker:         false
      Virtualization: none
      Distributor ID: Raspbian
      Description:    Raspbian GNU/Linux 10 (buster)
      Release:        10
      Codename:       buster
      
      PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
      NAME="Raspbian GNU/Linux"
      VERSION_ID="10"
      VERSION="10 (buster)"
      VERSION_CODENAME=buster
      ID=raspbian
      ID_LIKE=debian
      HOME_URL="http://www.raspbian.org/"
      SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
      BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
      
      Systemuptime and Load:
       20:28:55 up  1:34,  1 user,  load average: 1.21, 1.25, 1.12
      CPU threads: 4
      
      *** Time and Time Zones ***
      Sun Mar  5 19:28:55 UTC 2023
      Sun Mar  5 20:28:55 CET 2023
      CET +0100
      Europe/Berlin
      
      *** User and Groups ***
      pi
      /home/pi
      pi adm dialout cdrom sudo audio video plugdev games users input netdev gpio i2c spi iobroker
      
      *** X-Server-Setup ***
      X-Server:       false
      Desktop:
      Terminal:       tty
      Boot Target:    graphical.target
      
      *** MEMORY ***
                    total        used        free      shared  buff/cache   available
      Mem:           3.8G        1.0G        1.6G        8.0M        1.2G        3.0G
      Swap:           99M          0B         99M
      Total:         3.9G        1.0G        1.7G
      
               3826 M total memory
               1017 M used memory
               1054 M active memory
               1033 M inactive memory
               1566 M free memory
                149 M buffer memory
               1093 M swap cache
                 99 M total swap
                  0 M used swap
                 99 M free swap
      
      
      
      posted in Error/Bug
      K
      KarlHeinz666
    • [gelöst] Iobroker erkennt nur 4GB statt 8GB RPI4

      Guten Abend,

      bis jetzt war ich mit meinem iobroker auf einem RPI4 8G sehr zufrieden und hatte keine Proble, jedenfalls konnte ich das meiste selbt lösen, auch wenn ich keine Linux-Kenntnisse habe.
      Jetzt habe ich aber das Problem, dass nach einem Update von 4.X.xx auf 4.0.24 und dem Update von Node.js 12 auf 16 nur 4GB RAM erkannt werden.

      Screenshot 2023-03-05 201622.jpg

      Ich habe nach meinem Problem gesucht, jedoch nichts passendes gefunden. Bitte steinigt mich nicht, wenn das Problem hier schon behandelt worden ist.

      Ich hoffe, dass vielleicht jemand das Problem kennt und mir helfen kann.

      Grüsse
      KarlHeinz666

      Systemdata Bitte Ausfüllen
      Hardwaresystem: Pi4
      Arbeitsspeicher: 8GB
      Festplattenart: SSD
      Betriebssystem: Rasbian
      Node-Version: 10.x.x
      Nodejs-Version: v16.19.1
      NPM-Version: v8.19.3
      Installationsart: Skript/Manuell
      Image genutzt: Ja
      Ort/Name der Imagedatei: Offizielle Homepage
      posted in Error/Bug
      K
      KarlHeinz666
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo