Hinzufügen eines SDM-220-Zählers zu OpenHab

Fast ein Jahr ist seit meiner ersten Veröffentlichung über einen Stromzähler mit RS485 / ModBus-Schnittstelle SDM-220 vergangen . Dann gab es einen zweiten Artikel darüber, wie man Daten daraus sammelt und Statistiken verarbeitet. Dies ist der dritte, hoffentlich letzte. Sie befasst sich mit der Integration des Zählers in OpenHab . Das Ergebnis ist für mich endlich ganz in Ordnung.



Der erste Versuch, Statistiken vom Zähler zu sammeln, wurde mit einem externen Cloud-Dienst ThingSpeak durchgeführt . Als lokaler Server, der den Zähler abfragt, haben wir einen Thin Client (Mini-Computer) verwendet, auf dem Ubuntu Server auf dem USB-Stick installiert ist. Dies war der erste Fehler - das Flash-Laufwerk "starb" nach 3 Monaten (ein Unfall, dachte ich). Nachdem ich keine Schlussfolgerungen gezogen hatte, tötete ich das zweite Flash-Laufwerk in 2 Monaten (Regelmäßigkeit). In der dritten Version wurde bereits eine USB-Tasche mit einer 2,5-Zoll-Schraube als Speicher verwendet.

Der ThingSpeak-Dienst selbst ermöglicht eine gewisse Verarbeitung, bietet jedoch keine ausreichende Flexibilität bei der Datenmanipulation. Daten pro Tag wurden beispielsweise als Summe von Daten pro Stunde gesammelt. Wenn ein Datenpaket nicht auf dem Server eingetroffen ist oder ich während des Tests einige Daten gesendet habe, ist ein Fehler aufgetreten. Gedanken, dass es notwendig wäre, eine Zwei-Raten-Buchhaltung in Bezug auf die Tageszeit zu führen, wurden nicht optimistisch aufgenommen.

Im Allgemeinen habe ich beschlossen, OpenHab zu lernen.

Die erste Aufgabe: Rohdaten vom Zähler abrufen.


Die Installation von OpenHab selbst ist in der Anleitung beschrieben . Nach der Installation müssen Sie die ModBus-Bindung - binding-modbus1 - 1.9.0 über das Bedienfeld Papier-Benutzeroberfläche → Bindungen installieren

Der Modus-Bus wird über den USB-RS485-Adapter abgefragt. Stellen Sie daher sicher, dass sich der Adapter im System befindet, und fügen Sie dem Port die Openhab-Benutzerzugriffsrechte hinzu:

lsusb Bus 002 Device 002: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC ls /dev/ttyUSB* /dev/ttyUSB0 sudo adduser openhab dialout sudo adduser openhab tty 

Anschließend wird empfohlen, Berechtigungen für Java zu konfigurieren (dies wird auch in den OpenHab-Installationsanweisungen ausführlich beschrieben):

 sudo vi /etc/default/openhab2 EXTRA_JAVA_OPTS="-Dgnu.io.rxtx.SerialPorts=/dev/ttyUSB0" 

Nach diesen Manipulationen müssen Sie die Konfigurationsdatei services / modbus.cfg konfigurieren:

  sudo vi /etc/openhab2/services/modbus.cfg #   poll=30000 #        ,        .  start -  .   connection      (9600,8,n,1),        . # - 0x00 serial.slave1.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave1.type=input serial.slave1.start=0 serial.slave1.length=2 serial.slave1.valuetype=float32 # - 0x06 serial.slave2.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave2.type=input serial.slave2.start=6 serial.slave2.length=2 serial.slave2.valuetype=float32 #  - 0x0C serial.slave3.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave3.type=input serial.slave3.start=12 serial.slave3.length=2 serial.slave3.valuetype=float32 #  ( ) - 0x156 serial.slave4.connection=/dev/ttyUSB0:9600:8:none:1:rtu:2000:1000:none:none serial.slave4.type=input serial.slave4.start=342 serial.slave4.length=2 serial.slave4.valuetype=float32 

Anschließend müssen Sie die Datenelemente in der Datei items / sdm220.items erstellen :

 sudo vi /etc/openhab2/items/sdm220.items #    Group gSDM220 # ,      , energy -       Number sdm220_voltage " [%.1f ]" <energy> (gSDM220) {modbus="slave1:0"} Number sdm220_current " [%.2f ]" <energy> (gSDM220) {modbus="slave2:0"} Number sdm220_actpower " [%.1f ]" <energy> (gSDM220) {modbus="slave3:0"} Number sdm220_actcounter "  [%.1f *]" <energy> (gSDM220) {modbus="slave4:0"} 

Es bleiben die aktuellen Messwerte im Dashboard hinzuzufügen. Bearbeiten Sie dazu die Datei sitemaps / default.sitemap :

 sudo vi /etc/openhab2/sitemaps/default.sitemap sitemap default label="alk0v SmartHome (default sitemap)" { Frame label="" { Text item=sdm220_voltage Text item=sdm220_current Text item=sdm220_actpower Text item=sdm220_actcounter } } 

Im Prinzip reicht dies aus, um den aktuellen Zählerstand zu sehen:



Aufgabe 2: HabPanel konfigurieren und Messwerte visualisieren


OpenHab unterstützt mehrere Control Panels. Äußerlich mochte ich HabPanel am meisten . Installieren Sie HabPanel - ui-habpanel - 2.0.0 über Paper UI → User Interfaces .

Um Diagramme zu zeichnen, müssen Sie auch Daten irgendwo speichern. OpenHab verwendet den Begriff Persistenz für Datenbanken. Ich wollte die MySQL-Datenbank verwenden, die Community diskutierte viele Probleme mit dieser Datenbank, am Ende fand ich eine Anweisung , die auch für mich funktionierte.

Installieren Sie also MySQL Persistence (persistence-mysql - 1.9.0).

Installieren Sie MySQL:

 sudo apt-get install mysql-server sudo mysql -u root -p 

Richten Sie die Basis ein:

 CREATE DATABASE OpenHAB; CREATE USER 'openhab'@'localhost' IDENTIFIED BY 'YOURPASSWORD'; GRANT ALL PRIVILEGES ON OpenHAB.* TO 'openhab'@'localhost'; quit 

Openhab neu starten:

 sudo service openhab2 stop sudo service openhab2 start 

Dienste bearbeiten / mysql.cfg :

 # the database url like 'jdbc:mysql://<host>:<port>/<database>' (without quotes) url=jdbc:mysql://localhost:3306/openhab # the database user user=openhab # the database password password=YOURPASSWORD 

Bearbeiten Sie die Persistenz / mysql.persist . Standardmäßig werden die Werte aller Elemente bei jeder Änderung in die Datenbank eingegeben:

 Strategies { // if no strategy is specified for an item entry below, the default list will be used everyMinute : "0 * * * * ?" every5Minutes : "0 */5 * * * ?" everyHour : "0 0 * * * ?" everyDay : "0 0 0 * * ?" default = everyChange } Items { // persist all items once a day and on every change and restore them from the db at startup * : strategy = default, restoreOnStartup } 

Wenn alles richtig konfiguriert ist, sollten die Items-Tabelle und die ItemXX-Tabellen für jedes Item in der Datenbank angezeigt werden.

 mysql> use openhab; Database changed mysql> show tables; +-------------------+ | Tables_in_openhab | +-------------------+ | Item1 | | Item2 | | Item3 | | Item4 | | Items | +-------------------+ 5 rows in set (0.00 sec) mysql> select * from Items; +--------+--------------------------+ | ItemId | ItemName | +--------+--------------------------+ | 1 | sdm220_voltage | | 2 | sdm220_actpower | | 3 | sdm220_actcounter | | 4 | sdm220_current | +--------+--------------------------+ 4 rows in set (0.00 sec) 

Jetzt können Sie dem HabPanel Schönheit verleihen.

Fügen Sie ein Dashboard hinzu und fügen Sie neue Widgets hinzu. Verwenden Sie zum Anzeigen von Werten das Dummy- Widget, um Diagramme anzuzeigen - Diagramm . Hier ist alles intuitiv. Ich habe die Leistungs- und Spannungsparameter in einem Diagramm mit zwei verschiedenen Y-Skalen abgeleitet.

Geben Sie MySQL als Datenquelle an:



Schwellenwerte für die Spannungsachse einstellen:



Elemente hinzufügen, Farbe und Typ der Linie angeben, für die Spannung die Sekundärachse angeben:



Wir bekommen das Ergebnis :)



Die dritte Aufgabe: stündliche und tägliche Messung des Stromverbrauchs


Es ist gut, eine Zustandsänderung im Laufe der Zeit anzuzeigen, aber ich wollte auch Statistiken über den Verbrauch für eine Stunde, einen Tag und einen Monat erhalten. Das heißt, die Aufgabe besteht darin, regelmäßig einige Berechnungen durchzuführen. Hier kommt die Regel-Engine in OpenHab ins Spiel.

Also konfigurieren wir Regeln .

Zuerst müssen Sie den Elementen / sdm220.items neue Elemente hinzufügen :

 Number sdm220_hourcounter (gSDM220) Number sdm220_daycounter (gSDM220) 

Erstellen Sie dann die Datei rules / energy.rules , in der Sie zwei Regeln angeben müssen: eine wird einmal pro Stunde ausgeführt, die zweite einmal am Tag.

 rule "Energy by hour" when Time cron "0 0 * * * ?" then // .            var hour = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1), "mysql":).state as DecimalType //      logInfo("TEST","sdm220_hourcounter = "+hour) //  Item postUpdate(sdm220_hourcounter, hour) end rule "Energy by day" when Time cron "0 0 0 * * ?" then var day = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType postUpdate(sdm220_daycounter, day) 

Sie können die OpenHab-Konsole zum Debuggen verwenden. Standardbenutzername und Passwort: openhab / habopen. Sie können mit dem folgenden Befehl eine Verbindung herstellen:

 ssh -p 8101 openhab@localhost openhab> log:tail 19:22:00.012 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.526123046875 19:22:00.014 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.861083984375 19:22:09.462 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_current changed from 16.0433025360107421875 to 5.69449329376220703125 19:22:11.500 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_actcounter changed from 2387.51904296875 to 2387.5458984375 19:22:13.532 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_voltage changed from 192.7679595947265625 to 200.4195098876953125 19:22:15.568 [INFO ] [marthome.event.ItemStateChangedEvent] - sdm220_actpower changed from 2271.8486328125 to 1132.8717041015625 19:23:00.014 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.515869140625 19:23:00.015 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.8769531250 

Oder Sie können die Protokolldatei anzeigen:

 tail -f /var/log/openhab2/openhab.log 2017-04-18 19:17:45.587 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'energy.rules' 2017-04-18 19:18:00.259 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.571044921875 2017-04-18 19:18:00.272 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.8330078125 2017-04-18 19:19:00.015 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.83789062500 2017-04-18 19:19:00.025 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.557861328125 2017-04-18 19:20:00.013 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_hourcounter_day = 0.55517578125 2017-04-18 19:20:00.024 [INFO ] [.eclipse.smarthome.model.script.TEST] - sdm220_daycounter = 10.859130859375 

Ich habe vor, den Hauptstromzähler auf einen Zwei-Tarif-Zähler umzustellen, nach dem der im Bereich von 23:00 bis 07:00 Uhr verbrauchte Strom mit einem Koeffizienten von 0,5 bezahlt wird. Daher möchte ich den erwarteten Effekt sehen und eine Zwei-Tarif-Messung beibehalten. Zuerst habe ich einfach zusätzliche Zeitbedingungen zu Elementen und Regeln hinzugefügt und die Tag- und Nachtablesungen in zwei verschiedene Tabellen eingefügt. In der Datenbank war alles schön, aber auf dem Diagramm sah es ungeschickt aus, da das Diagramm die letzten beiden Werte mit einer geraden Linie verband:



Um meinen Sinn für Schönheit zu amüsieren, musste ich mich ein bisschen darum kümmern.

Das endgültige Regel-Skript für die Zwei-Tarif-Buchhaltung sieht also folgendermaßen aus:

 rule "Energy by hour" when Time cron "0 0 * * * ?" then var hour = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1), "mysql":).state as DecimalType //   if(now.getHourOfDay > 7 && now.getHourOfDay < 23) { logInfo("TEST","sdm220_hourcounter_day = "+hour) postUpdate(sdm220_hourcounter_day, hour) } else { //        //      primary key  timestamp,               if(now.getHourOfDay==7) { postUpdate(sdm220_hourcounter_night, hour) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day, hour) } else if(now.getHourOfDay==23) { postUpdate(sdm220_hourcounter_day, hour) Thread::sleep(1000) postUpdate(sdm220_hourcounter_day,0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, 0) Thread::sleep(1000) postUpdate(sdm220_hourcounter_night, hour) } else { postUpdate(sdm220_hourcounter_night, hour) } } postUpdate(sdm220_hourcounter, hour) end rule "Energy by day" when Time cron "0 0 0 * * ?" then var day = sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType //night counter, 00:00..07:00 + 23:00..00:00 var day2 = sdm220_actcounter.historicState(now.minusHours(17),"mysql":).state as DecimalType - sdm220_actcounter.historicState(now.minusDays(1), "mysql":).state as DecimalType + sdm220_actcounter.state as DecimalType - sdm220_actcounter.historicState(now.minusHours(1),"mysql":).state as DecimalType //day counter, 07:00..23:00 var day1 = sdm220_actcounter.historicState(now.minusHours(1),"mysql":).state as DecimalType - sdm220_actcounter.historicState(now.minusHours(17),"mysql":).state as DecimalType logInfo("TEST","sdm220_daycounter_day = "+day1) logInfo("TEST","sdm220_daycounter_night = "+day2) logInfo("TEST","sdm220_daycounter = "+day) postUpdate(sdm220_daycounter, day) postUpdate(sdm220_daycounter_day, day1) postUpdate(sdm220_daycounter_night, day2) end 

Fügen Sie vor dem Bearbeiten des Skripts die erforderlichen Elemente hinzu:

 Number sdm220_hourcounter_day (gSDM220) Number sdm220_hourcounter_night (gSDM220) Number sdm220_daycounter_day (gSDM220) Number sdm220_daycounter_night (gSDM220) 

Das stündliche und tägliche Flussdiagramm sieht nun folgendermaßen aus:



Das ist wahrscheinlich alles. Es ist auch geplant, eine Berechnung des Strom- und Geldverbrauchs pro Monat für einen Tages- und Nachttarif und eine Berichterstellung mit Postversand hinzuzufügen.

Source: https://habr.com/ru/post/de403237/


All Articles