Perl-Hilfe für Volkszaehler.pm erbeten

Begonnen von bgewehr, 23 Februar 2013, 23:07:12

Vorheriges Thema - Nächstes Thema

bgewehr

Hallo!

Ich habe mal damit begonnen, ein fhem-Modul für die Abfrage von Daten aus dem Projekt Volkszaehler.org zu entwickeln.

Der Volkszaehler läuft bei mir auf einem Raspberry Pi in der Nähe des Stromkastens und liest den Stromzähler per Infrarot-Lesekopf aus.

Um nun die Daten, die auf diese Weise gewonnen werden, auch in fhem verwenden und darstellen zu können, möchte ich dieses Modul fertigstellen.

Ich bin soweit gekommen, dass die Daten durch das Modul gelesen werden können und im Log bereits auftauchen. Die Zerlegung des Antwortstrings mit Perl macht mir aber noch Schwierigkeiten, daher hier meine Hilfeanfrage.

Zuerst der Stand des Moduls:

Siehe Anhang "23_Volkszaehler.pm" in den Ordner /fhem/fhem/

Dieser Code muss per Define durch ein device abgerufen werden, dazu muss ich einen Kanal aus meinem Volkszähler mit seiner UUID benennen:


define Stromverbrauch VOLKSZAEHLER 192.168.178.45 80 635481a0-6fcd-11e2-8587-eda25228f8bf 60


Daraufhin wird der folgende Text abgerufen:


{"version":"0.2","data":{"uuid":"635481a0-6fcd-11e2-8587-eda25228f8bf","from":"1361655894730","to":"1361655923499","min":[1361655922123,971.195],"max":[1361655923499,1056.5],"average":975.275,"consumption":7.794,"rows":20,"tuples":[[1361655922123,971.195,20],[1361655923499,1056.5,1]]}}


Nun würde ich gern die einzelnen Readings dem Device zuordnen. Das gelingt mir aber nicht so richtig, daher bitte ich hier um Hilfe.

Bisher hole ich mir nur das vorletze Reading, was aber immerhin schon mal den aktuellen Verbrauch und den Zählerstand im Device aufzeigt:


(siehe Anhang / see attachement)


Ein Graph aus dem Verbrauch ist auch schnell erstellt:

Neue gPlot-Definition "Volkszaehler.gplot" in den Ordner /fhem/www/gplot/, siehe Anhang.


define FileLog_Stromverbrauch FileLog ./log/Stromverbrauch-%Y-%m.log Stromverbrauch
attr FileLog_Stromverbrauch group Volkszaehler
attr FileLog_Stromverbrauch logtype text
attr FileLog_Stromverbrauch room Z_Log

define FilePlot_Stromverbrauch weblink fileplot FileLog_Stromverbrauch:Volkszaehler:CURRENT
attr FilePlot_Stromverbrauch label "Stromverbrauch: $data{currval1}"
attr FilePlot_Stromverbrauch room Volkszaehler


Sieht dann so aus:

(siehe Anhang / see attachement)
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Neuer Stand mit den fertigen Readings... :-)

Wer kann sowas einchecken?


(siehe Anhang / see attachement)
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Martin Fischer

Hallo Bernd,

> Wer kann sowas einchecken?

theoretisch jeder der einen SVN Zugang hat aber ich hoffe es checkt keiner ein... :-)

Nach dem ich Dich jetzt geschockt habe, die Auflösung:

Wenn es als "offizielles" Fhem Modul aufgenommen werden soll, dann solltest Du Dir als Maintainer des Moduls selber einen SVN Zugang zulegen. Jede Änderung müßte sonst von einem anderem Entwickler eingecheckt werden, was nicht zielführend ist. Darüber hinaus fehlt noch die komplette Dokumentation im Modul, also die Abschnitte für die commandref.html.

Wenn Du Dein Modul also offiziell in Fhem einfließen lassen möchtest, dann solltest Du bereit sein, das Modul hier im Forum zu supporten, eine Dokumentation dafür bereit zu stellen, sowie die Pflege des Quelltextes (inkl. SVN check-in) selber zu übernehmen.

Im Quelltext solltest Du noch die Zeile mit der Id abändern auf:# $Id:$ und Deinem svn client mitteilen, dass das keyword 'Id' gesetzt wird:svn propset svn:keywords 'Id' FHEM/23_VOLKSZAEHLER.pm

Gruß Martin
--
Admin, Developer, Gründungsmitglied des FHEM e.V.

macmattes

Hi

frage meinen Volkszaehler mit einem Bashscript ab.
Vielleicht kannst du die Regex bei Dir nutzen, hab da leider zu wenig Ahnung von und nur alles zusammenkopiert, aber es läuft.
Bei deinem Modul hab ich bei den Verbrauchswerten immer "null" stehen. Min Max Average funtkionieren.
Vielleicht wäre es sinnvoll nach den Bezeichnungen zu suchen und nicht abzuzählen.

summiere bei mir die 3 Phasen , daher mehrfache abfragen

bgewehr

Habe zwar nicht Deine regex genommen, aber die Anregung war gut, danke dafür!

Hier das neue Modul mit einer wichtigen Veränderung: Das Reading, welches als state genommen werden soll, kann im define gewählt werden, also:


define <name> VOLKSZAEHLER <ip-address> <port-nr> <channel> <state:last/min/max/average/consumption> <poll-delay>


Beispiele:


#Kanal im Volkszaehler, der den Momentanverbrauch per I/R-Lesekopf ermittelt, alle 60 Sekunden davon der Mittelwert
define Verbrauch_aktuell VOLKSZAEHLER 192.168.178.45 80 635481a0-6fcd-11e2-8587-eda25228f8bf average 60
attr Verbrauch_aktuell delay 60
attr Verbrauch_aktuell group Strom
attr Verbrauch_aktuell room Volkszaehler

#In fhem loggen, um einen Graphen daraus zu zeigen
define FileLog_Verbrauch_aktuell FileLog ./log/Verbrauch_aktuell-%Y-%m.log Verbrauch_aktuell
attr FileLog_Verbrauch_aktuell group Volkszaehler
attr FileLog_Verbrauch_aktuell logtype text
attr FileLog_Verbrauch_aktuell room Z_Log

#der Graph dazu
define FilePlot_Verbrauch_aktuell weblink fileplot FileLog_Verbrauch_aktuell:Volkszaehler:CURRENT
attr FilePlot_Verbrauch_aktuell label "Stromverbrauch: $data{currval1}"
attr FilePlot_Verbrauch_aktuell room Volkszaehler

#Kanal im Volkszaehler, der den Zählerstand per I/R-Lesekopf ermittelt, jede Stunde davon der letzte Wert
define Zaehlerstand VOLKSZAEHLER 192.168.178.45 80 ebb9c9b0-7058-11e2-b5ed-d12ec87a3a7f last 1800
attr Zaehlerstand delay 1800
attr Zaehlerstand group Strom
attr Zaehlerstand room Volkszaehler

#Kanal im Volkszaehler, der den Zählerstand per I/R-Lesekopf ermittelt, alle 24 Stunden davon der Verbrauch
define Verbrauch_24h VOLKSZAEHLER 192.168.178.45 80 635481a0-6fcd-11e2-8587-eda25228f8bf consumption 86400
attr Verbrauch_24h group Strom
attr Verbrauch_24h room Volkszaehler


Das sieht dann so aus:

(siehe Anhang / see attachement)

FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Martin Fischer

Hallo Bernd,

hier noch ein paar Anmerkungen zu Deinem Modul:

Du verwendest $hash->{CHANGED}, das ist "veraltet". Stattdessen solltest Du Dir mal readingsSingleUpdate bzw. readingsBulkUpdate anschauen. Das hat meines Wissens Boris im Wiki dokumentiert (ich selber arbeite nicht mit dem Wiki).

Des weiteren habe ich verstanden, das Du beim define festlegst welches reading als Status angezeigt werden soll. Hierzu wird empfohlen, das der Entwickler einen Standardwert vorgibt, der Nutzer dieses dann aber über das Attribut stateFormat selber definieren kann. Dann kannst Du Dir diesen Parameter im define sparen.

Die Rückgabe die Du von dem Volkszähler bekommst ist übrigens im JSON-Format. Wenn man sich den mal strukturiert aufbaut, dann sieht das so aus:
{
   "version":"0.2",
   "data":{
      "uuid":"635481a0-6fcd-11e2-8587-eda25228f8bf",
      "from":"1361655894730",
      "to":"1361655923499",
      "min":[
         1361655922123,
         971.195
      ],
      "max":[
         1361655923499,
         1056.5
      ],
      "average":975.275,
      "consumption":7.794,
      "rows":20,
      "tuples":[
         [
            1361655922123,
            971.195,
            20
         ],
         [
            1361655923499,
            1056.5,
            1
         ]
      ]
   }
}

Vereinfacht gesagt, stehen dabei die geschweiften Klammern {} für ein Hash und die eckigen Klammern [] für ein Array. Somit ist die Rückgabe ein Hash of Hashes, das auch Arrays enthält.

Diesen könnte man (wenn man denn wollte) in ein Hash of Hashes bzw. Arrays konvertieren:
$hash = (
  "version" => "0.2",
  "data"    => (
    "uuid"  => "635481a0-6fcd-11e2-8587-eda25228f8bf",
    "from"  => "1361655894730",
    "to"    => "1361655923499",
    "min"   => [
      1361655922123,
      971.195
    ],
    "max"   => [
      1361655923499,
      1056.5
    ],
    "average"     => 975.275,
    "consumption" => 7.794,

  usw.

  ),
);


Wenn Du Dich mit dem Aufbau einer JSON-Rückgabe befaßt, diese auch "sauber" in ein HoH wandelst, dann benötigst Du kein regexp, sondern kannst z.B. gezielt über $hash{data}{from} den Wert auslesen.

Zwar wird die Wandlung in eine Variable etwas aufwändiger sein, als Dein regexp, dafür hast Du dann eine (vermutlich) generelle Umwandlung der Rückgaben von Volkszähler in eine Perlvariable.

Dafür gibt es auch fertige Perlmodule (CPAN), die aber auf dem meisten "kleinen" Systemen wie z.B. FRITZ!Box vermutlich nicht vorhanden sind. Daher ist der "manuelle" Weg zu bevorzugen.

Das Modul 98_JsonList.pm, das ich mal vor einigen Jahren, genauer 2008 für FHEM geschrieben habe, macht genau den umgekehrten Weg. Es wandelt eine Perlvariable nach JSON.

Soviel mal als ein paar Tipps zur Umsetzung von mir....

Und wie eingangs bereits erwähnt, pflegt Boris ab und an im Wiki Develeopers Guidlines wo Du Dir ggf. auch die eine oder andere Info noch anlesen kannst.

Gruß Martin
--
Admin, Developer, Gründungsmitglied des FHEM e.V.

bgewehr

Hallo!

Ich habe inzwischen eine neue Version mit Hilfe des JSON.pm erstellt. Läuft bei mir seit 4 Wochen ohne Probleme.

Gruß, Bernd
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Dennis D.

Hi Bernd,

zunächst mal vielen Dank für Dein Modul. Habe es bei mir eingebaut. Und direkt ein paar Fragen hierzu ;) :

1. Besteht die Möglichkeit mittels "stateFormat" die Ausgabe der Werte anzupassen, ähnlich wie es bei 1Wire-Devices möglich ist?

2. Ich habe vier Zwischenzähler per S0-Schnittstelle angeschlossen und werte diese über Volkszähler aus. Da die Impulse der Zähler aber abhängig vom Verbrauch kommen, wird häufig auch der Wert "0" ins Log geschrieben. Dies führt dann zu einem Zick-Zack-Muster im Graph. Kann man was dagegen machen?


(siehe Anhang / see attachement)


Gruß,
Dennis

PS: und bei dem Delay-Attribut sagt fhem, dass es das nicht kennt?!
FHEM 5.5 auf RPi Rev. B 512 mit HMLAN (HM-CFG-LAN)

CUL_HM: HM-LC-Bl1PBU-FM,HM-LC-SW1-BA-PCB,HM-LC-SW4-SM,HM-LC-Sw1PBU-FM,HM-OU-LED16,HM-PB-2-WM55,HM-RC-KEY3-B,HM-SEC-KEY,HM-SEC-RHS,HM-SEC-SC,HM-SEC-SD,HM-WDS10-TH-O,HM-WDS40-TH-I

OWDevice: DS18B20,DS2438

bgewehr

Hallo, Dennis!

Super, dass Dir mein Modul hilft, freut mich!

Die Überschrift zu meinem Forumsbeitrag sagt aber auch schon was über mein Problem: Ich kann überhaupt kein Perl! Ich habe nur einen vorhandenen Code genommen und umgefrickelt.

Die Art und Weise, wie FHEM Attribute in Modulen definiert, habe ich noch nicht verstanden und bin daher auch nicht in der Lage, die richtigen nächsten Schritte zu machen!

Leider hat mir auf meinen Aufruf noch niemand wirklich geholfen.

Daher meine Antworten:

zu 1:
Geht sicher, kann ich aber noch nicht umsetzen!

zu 2:
Wenn Du den Abstand etwas größer wählst, dann müsste avg doch was sinnvolles ergeben, oder? So 5 Minuten sollten doch reichen, um einen akzeptablen Wert zu erhalten. Einen besseren Vorschlag habe ich aktuell leider auch nicht.

Wenn Du jemanden kennst, der besser in Perl ist, lass uns gemeinsam dran weiterarbeiten!

Gruß

Bernd
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Dennis D.

Hi Bernd,

dann haben wir was gemeinsam. Ich kann es nämlich auch nicht. ;)

Hmmm, vielleicht sehe ich das jetzt was naiv, aber eventuell könnte man aus dem 1Wire-Device-Modul den entsprechenden Code bzgl. des stateFormat finden und in Dein Modul "guttenbergen". Werde heute mal schauen ob ich da was finde.

Vergrößern des Abstandes sollte nicht viel bringen. Dein Modul ruft doch über das Frontend des VZ die Daten aus der Volkszähler SQL-Db ab, oder? In der Datenbank werden jedoch nur die S0 Impulse mit dem Wert "1" mit einem Zeitstempel versehen weggeschrieben. Je nachdem zu welcher Zeit dein Modul den Zähler (bzw. die Datenbank) abfragt, bekommt es daher meiner Meinung nach den Wert "0" zurück und daher der Zickzack.

Wäre gern mehr behilflich, aber dafür fehlt mir bisher das know-how.

Gruß,
Dennis
FHEM 5.5 auf RPi Rev. B 512 mit HMLAN (HM-CFG-LAN)

CUL_HM: HM-LC-Bl1PBU-FM,HM-LC-SW1-BA-PCB,HM-LC-SW4-SM,HM-LC-Sw1PBU-FM,HM-OU-LED16,HM-PB-2-WM55,HM-RC-KEY3-B,HM-SEC-KEY,HM-SEC-RHS,HM-SEC-SC,HM-SEC-SD,HM-WDS10-TH-O,HM-WDS40-TH-I

OWDevice: DS18B20,DS2438

bgewehr

Nur eben zwischendurch: mein Modul fragt NICHT die Datenbank ab, sondern die Vz-Middleware, die berechnet je nach Channel Typ die Werte für Verbrauch, min, max average aus den DB Daten, dieser Punkt ist SEHR wichtig für das Verständnis der VZ Architektur!
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Dennis D.

mein ich ja. die middleware und das frontend ist für mich ein teil ;). kämpfe eh noch mit der einrichtung des vzlogger um meinen EMH eHz auszulesen. bisher läuft nur der s0vz-deamon vernünftig.
FHEM 5.5 auf RPi Rev. B 512 mit HMLAN (HM-CFG-LAN)

CUL_HM: HM-LC-Bl1PBU-FM,HM-LC-SW1-BA-PCB,HM-LC-SW4-SM,HM-LC-Sw1PBU-FM,HM-OU-LED16,HM-PB-2-WM55,HM-RC-KEY3-B,HM-SEC-KEY,HM-SEC-RHS,HM-SEC-SC,HM-SEC-SD,HM-WDS10-TH-O,HM-WDS40-TH-I

OWDevice: DS18B20,DS2438

bgewehr

FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Dennis D.

Saugeil! Vielen Dank Bernd! Innerhalbvon 15 Minuten hatte ich den vzlogger am laufen. :) Hast mir jede Menge Arbeit erspart.
FHEM 5.5 auf RPi Rev. B 512 mit HMLAN (HM-CFG-LAN)

CUL_HM: HM-LC-Bl1PBU-FM,HM-LC-SW1-BA-PCB,HM-LC-SW4-SM,HM-LC-Sw1PBU-FM,HM-OU-LED16,HM-PB-2-WM55,HM-RC-KEY3-B,HM-SEC-KEY,HM-SEC-RHS,HM-SEC-SC,HM-SEC-SD,HM-WDS10-TH-O,HM-WDS40-TH-I

OWDevice: DS18B20,DS2438

Spiceweasel

bekomme leider Fehlermeldungen wg. der JSON.pm auf meiner FritzBox 7390

2013.05.05 00:44:16 1: reload: Error:Modul 23_VOLKSZAEHLER deactivated:
 Attempt to reload JSON2.pm aborted.
Compilation failed in require at ./FHEM/23_VOLKSZAEHLER.pm line 32, <$fh> line 223.
BEGIN failed--compilation aborted at ./FHEM/23_VOLKSZAEHLER.pm line 32, <$fh> line 223.

2013.05.05 00:44:16 0: Attempt to reload JSON2.pm aborted.
Compilation failed in require at ./FHEM/23_VOLKSZAEHLER.pm line 32, <$fh> line 223.
BEGIN failed--compilation aborted at ./FHEM/23_VOLKSZAEHLER.pm line 32, <$fh> line 223.