Sensordaten von USB in FHEM einlesen

Begonnen von Mathias, 20 März 2016, 21:48:16

Vorheriges Thema - Nächstes Thema

Mathias

Hallo,

ich bin neu hier und habe gleich eine ganze reihe Probleme die zum größtenteil mit FHEM zu tun haben.


Das Projekt:
Ich habe diverse Sensoren an einem Arduino hängen, die würde ich gerne Visualisieren (RSS) und auch loggen.
Der Arduino steuert diverse Mischer und Pumpen.
Firmata etc. möchte ich nicht nutzen, sondern den Arduino seine arbeit machen lassen.
Das funktioniert bereits seit 3 Jahren ohne Probleme und sehr Stabil.
Von Zeit zu Zeit soll der Arduino die Daten über USB senden.

Warum FHEM:
In einem anderem Forum hat mir ein netter Kollege gezeigt, das genau das, was ich eben beschrieben habe (Gerät sendet Daten via USB an FHEM), mit Hilfe dieses
Forum's,  realisiert wurde.
Das andere Gerät ist eine Holzvergaser-Steuerung - Flammtronik.

Nun habe ich auf Basis der "Flammtronik Vorlage" das ganze versucht nachzuvollziehen.

Stichwort ECMD

1. Man braucht eine definitionsdatei? classdef
sudo nano /opt/fhem/ECMD/Arduino.classdef
reading Spontan match "^(.*\r\n\021)+.*$" <-- ich bin mit den Daten der FT nicht so vertraut, aber das soll vermutlich das Ende der Zeichenkette darstellen?
reading Spontan postproc {my $d=$_;CheckFrame("%NAME",$d);} <--- hier wird das Ergebniss der "Subroutine" CheckFrame zurück gegeben
CheckFrame steht in 99_myUtils.pm

2. man brauch 99_myUtils.pm (einen eigene? oder nur eine andere Subroutine - z.B. CheckArduFrame)
CheckFrame nimmt die Daten, korregiert wenn nötig einzelne Werte (P/PL für Pumpe und Primärlüfter) und ruft dann ReportItems auf, welche
erneut die Werte bearbeitet (aus V wird Verlust usw.) und dann ein readingsSingleUpdate für jeden Wert ausführt.
Reste werden zurück gegeben.


sub CheckFrame($$)
{
my $name = shift;
my $hash = $defs{$name};
if (!defined $KeepedRest) { $KeepedRest = ""; }
else { Log3 $hash,5,"Used Prefix from prior line: $KeepedRest" };
my $frame = $KeepedRest . shift;
# Pumpe and Primaerluefter have both "P" as key, so change Primaerluefter to PL
$frame =~ s/P(\d{3})/PL$1/g;

# divide  into hash-table of [key,value] and take undetected rest into extra var forcheck
my %items = $frame=~/([A-Za-z]+)([-+]?[\d.]+)\W+/g;
my $Rest=$'; #';
# Keep all rest of line for next use
$frame=~/((.*\r\n\021)+)/g;
$KeepedRest=$'; #';
CalcItems($hash,\%items);

ReportItems($hash,\%items);

if ($Rest ne '') { Log3 $hash,5,"Unknown rest of frame: $Rest|$KeepedRest (Frame:
$frame)" };
Log3 $hash,5,"CheckFrame finished.";
return $KeepedRest;
}

sub ReportItems($$)
{
my %ItemNotes = (
"T" => "Laufzeit",
"K" => "Kesseltemp",
"A" => "Abgas",
"B" => "Brennkammer",
"PL" => "Primaerluefter",
"O" => "O2",
"S" => "Sekundaerluefter",
"R" => "Ruecknahme",
"V" => "Verlust",
"Rt" => "Rt",
"Ra" => "Ra",
"P" => "Pumpe",
"Z" => "status",
"Sp" => "Speicher",
"w" => "CAN_T1",
"x" => "CAN_T2",
"y" => "CAN_T3",
"z" => "CAN_T4",
"a" => "Temp_a",
"b" => "Temp_b",
"c" => "Temp_c",
"d" => "Temp_d",
"e" => "Temp_e",
"f" => "Temp_f",
"g" => "Temp_g",
"h" => "Temp_h",
"LZ_h" => "Laufzeit_h",
"LZ_m" => "Laufzeit_m",
"U" => "Uhrzeit",
#"HL" => "Heizlast",
#"ENERG" => "Energiemenge",
#"AZT" => "Anheizzeit",
"Dauer_h" => "Dauer_h",
"Dauer_m" => "Dauer_m",
"Dauer_min" => "Dauer_min"
);
my $hash = shift;
my %items = %{shift()};

foreach my $Key (sort keys %items)
{
  my $Notation = $ItemNotes{$Key};
  my $Value = $items{$Key};
  readingsSingleUpdate($hash, $Notation, $Value,1);
}
}




3. ECMD Schnittstelle?
define Arduino ECMD serial /dev/ttyUSB1@9600
attr Arduino classdefs ArduinoMaster=/opt/fhem/ECMD/Arduino.classdef
attr Arduino partial 3
attr Arduino room ArduinoSystem

4. ECMD Gerät? (Virtuelle Schnittstelle)
define Arduino ECMDDevice ArduinoMaster
attr ArduinoDev IODev Arduino
attr ArduinoDev event-on-change-reading .*
attr ArduinoDev room ArduinoSystem

*********** Vorbereitung / Definition Hardware ***********

5. Log Eintrag
define ArduinoLog FileLog ./log/ArduinoLog-%Y-%m.log ArduinoDev:WERT:.*|ArduinoDev:WERT:.*



Das Problem:
Ich verstehe (denke) ich wo die Zeichenkette verarbeitet wird, aber nicht wie.

reading Spontan match "^(.*\r\n\021)+.*$"
Das ist es oder?
Da könnte genauso gut Ägyptisch stehen, ich kapier's nicht.
Wo muss ich weiter suchen?
PERL? FHEM?

Die suche im Internet, irgendwie gibt es da nicht's passendes zu meinem Problem - ich weiß, sagen alle.

Hab ReportItems mal für meine Zeichenkette angepasst.

sub ReportItems($$)
{
my %ItemNotes = (
"T" => "Laufzeit",
  "KVL" => "Kessel VL",
  "KRL" => "Kessel RL", 
  "KT"  => "Kessel",
  "KMP" => "Kessel Mischer Pos",   
   
  "HKVL" => "Heizkreis VL",
  "HKRL" => "Heizkreis RL",
  "HKVS" => "Heizkreis VLSoll",
  "HKMP" => "Heizkreis Mischer Pos",     
   
   
  "AT" => "Aussen",
  "AP1O" => "Puffer1Oben", 
  "AP2O" => "Puffer2Oben",
  "AP3O" => "Puffer3Oben",     
  "AP1M" => "Puffer1Mitte", 
  "AP2M" => "Puffer2Mitte",
  "AP3M" => "Puffer3Mitte",   
  "AP1U" => "Puffer1Unten", 
  "AP2U" => "Puffer2Unten",
  "AP3U" => "Puffer3Unten",   
   
  "HKF" =>  "HeizkreisFreigabe",   
  "HKADD" =>"AnhebungEIN", 
  "HKSUB" =>"DrosselungEIN",
  "HKNA" => "NachtAbsenkungEIN", 
  "HKAN" => "Heizkreis_An",
);

my $hash = shift;
my %items = %{shift()};

foreach my $Key (sort keys %items)
{
my $Notation = $ItemNotes{$Key};
my $Value = $items{$Key};
readingsSingleUpdate($hash, $Notation, $Value,1);
}
}


FHEM ist bei mir auf einem Raspberry installiert.

Danke für die Hilfe
Mathias

Mathias

Hm hallo?  :o

Jemand hier der mir weiterhelfen kann? :'(

Ich würde DAS -> reading Spontan match "^(.*\r\n\021)+.*$"

gerne verstehen, stehe gerade auf dem Schlauch und brauche einen Hinweis, eine Referenz oder irgendwas, das mir weiterhilft.  ::)




Mathias

Ich habe das ganze jetzt in FHEM integriert und bekomme folgende Meldung im Log angezeigt:

Arduino: Unknown code , help me!

Das liegt vermutlich an der oben beschriebenen Stelle, die mir hier keiner erklären kann oder will!?

Bin ich hier im falschen Forum oder handelt es sich um ein unlösbares Problem oder sind alle im Urlaub?

justme1968

zu ecmd kann ich dir nichts sagen.

aber wenn du das was dein arduino sendet unter kontrolle hast schau dir mal das KeyValueProtocoll modul an. damit ist das was du vor hast ganz einfach möglich.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Mathias

Danke Andre,

hab mir die Referenz angesehen und auch deinen Hinweis gefunden
https://forum.fhem.de/index.php/topic,50825.msg424646.html#msg424646

The protocol that the sketch must send is: OK VALUES Key1=Value1,Key2=Value2, ...

habe nun

define myARDUINO JeeLink /dev/ttyACM0@19200

eingefügt und im LOG steht nun

myARDUINO: Unknown code OK VALUES DUMMY T=18:1:43;KVL=74,KRL=75,KT=78,KMP=95,HKVL=40,HKRL=39,HKVS=41,HKMP=60000,AT=13,AP1O=50,AP2O=49,AP3O=-127,AP1M=40,AP2M=39,AP3M=-127,AP1U=38,AP2U=34,AP3U=-127,HKF=1,HKADD=1,HKSUB=0,HKNA=0,REB=1;HKN=0, help me!
2016.03.26 18:18:49 3: myARDUINO: Unknown code OK VALUES DUMMY T=18:2:43;KVL=75,KRL=69,KT=79,KMP=98,HKVL=40,HKRL=39,HKVS=41,HKMP=60000,AT=13,AP1O=50,AP2O=49,AP3O=-127,AP1M=40,AP2M=39,AP3M=-127,AP1U=38,AP2U=34,AP3U=-127,HKF=1,HKADD=1,HKSUB=0,HKNA=0,REB=0;HKN=0, help me!

Das sieht schon mal gut aus!

Denke ich muss da jetzt

define ARDUINO_LOG KeyValueProtocol DUMMY

eintragen?!

Dann kommt aber die Meldung

"Unknown module KeyValueProtocol "

?!

Wzut

#5
mach mal ein fhem Update :)
Die Datei nennet sich 36_KeyValueProtocol.pm und liegt in FHEM, deine 36_JeeLink.pm scheint auch etwas älter zu sein :
Unknown code OK VALUES DUMMY T=18:1:43;
Mit Sicherheit ist das KVP auch nicht bei dir unter Clients gelistet sonst hätte autocreate dir die fehlende Arbeit abgenommen.
Maintainer der Module: MAX, MPD, UbiquitiMP, UbiquitiOut, SIP, BEOK, readingsWatcher

Mathias

Hi, danke für den Hinweis.

update ist gemacht.

also
define ARDUINO_LOG KeyValueProtocol DUMMY 1
ausprobiert und hat funktioniert

jetzt steht im LOG folgendes:
2016.03.26 20:16:35 1: ERROR: Invalid characters in name (not A-Za-z0-9._): KeyValueProtocol_DUMMY_T=20:0:26;KVL=73,KRL=71,KT=76,KMP=81,HKVL=31,HKRL=31,HKVS=39,HKMP=25,AT=11,AP1O=72,AP2O=76,AP3O=-127,AP1M=47,AP2M=46,AP3M=-127,AP1U=39,AP2U=35,AP3U=-127,HKF=1,HKADD=0,HKSUB=0,HKNA=0,REB=0;HKN=1

Das krieg ich aber hin.

Was mir fehlt ist die Möglichkeit, aus der "99_myUtils.pm"

die Funktion

sub ReportArduinoItems($$)
{
my %ItemNotes = (
"T" => "Laufzeit",
  "KVL" => "Kessel_VL",
  "KRL" => "Kessel_RL", 
  "KT"  => "Kessel",
  "KMP" => "Kessel_Mischer_Pos",     
  "HKVL" => "Heizkreis_VL",
  "HKRL" => "Heizkreis_RL",
  "HKVS" => "Heizkreis VLSoll",
  "HKMP" => "Heizkreis_Mischer_Pos",       
  "AT" => "Aussen",
  "AP1O" => "Puffer1Oben", 
  "AP2O" => "Puffer2Oben",
  "AP3O" => "Puffer3Oben",     
  "AP1M" => "Puffer1Mitte", 
  "AP2M" => "Puffer2Mitte",
  "AP3M" => "Puffer3Mitte",   
  "AP1U" => "Puffer1Unten", 
  "AP2U" => "Puffer2Unten",
  "AP3U" => "Puffer3Unten",     
  "HKF" =>  "HeizkreisFreigabe",   
  "HKADD" =>"AnhebungEIN", 
  "HKSUB" =>"DrosselungEIN",
  "HKNA" => "NachtAbsenkungEIN", 
  "HKAN" => "Heizkreis_An",
"REB" => "Rebootet",
"HKN" => "HKNachgestellt"
);

my $hash = shift;
my %items = %{shift()};

foreach my $Key (sort keys %items)
{
my $Notation = $ItemNotes{$Key};
my $Value = $items{$Key};
readingsSingleUpdate($hash, $Notation, $Value,1);
}
}


aufzurufen und dann das ganze ins Arduinolog zu schreiben.

justme1968

ich glaube das format was dein arduino sendet stimmt noch nicht ganz:OK VALUES <type> <id> <key1>=<value1>,<key2>=<value2>,...
zumindest sehe ich die id nicht. die ; in der nachricht ist ziemlich sicher auch nicht beabsichtigt.

es soll bei dir vermutlich so aussehen: OK VALUES DUMMY 1 T=20:0:26,KVL=73,KRL=71,KT=76,KMP=81,HKVL=31,HKRL=31,HKVS=39,HKMP=25,AT=11,AP1O=72,AP2O=76,AP3O=-127,AP1M=47,AP2M=46,AP3M=-127,AP1U=39,AP2U=35,AP3U=-127,HKF=1,HKADD=0,HKSUB=0,HKNA=0,REB=0,HKN=1

du brauchst keine routine in 99_myUtils. die readings werden automatisch angelegt und du kannst sie wie aus jedem anderen device loggen.

gruss
  andre

ps: DUMMY ist vermutlich nicht wirklich geschickt als type :)
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Mathias

Zitat von: justme1968 am 26 März 2016, 20:36:15
ich glaube das format was dein arduino sendet stimmt noch nicht ganz:OK VALUES <type> <id> <key1>=<value1>,<key2>=<value2>,...
zumindest sehe ich die id nicht. die ; in der nachricht ist ziemlich sicher auch nicht beabsichtigt.

es soll bei dir vermutlich so aussehen: OK VALUES DUMMY 1 T=20:0:26,KVL=73,KRL=71,KT=76,KMP=81,HKVL=31,HKRL=31,HKVS=39,HKMP=25,AT=11,AP1O=72,AP2O=76,AP3O=-127,AP1M=47,AP2M=46,AP3M=-127,AP1U=39,AP2U=35,AP3U=-127,HKF=1,HKADD=0,HKSUB=0,HKNA=0,REB=0,HKN=1

du brauchst keine routine in 99_myUtils. die readings werden automatisch angelegt und du kannst sie wie aus jedem anderen device loggen.

gruss
  andre

ps: DUMMY ist vermutlich nicht wirklich geschickt als type :)

Ja, hab eben festgestellt, das da ein ; zuviel drin ist und die ID hatte ich noch nicht eingetragen, ist aber so gut wie erledigt.
DUMMY hatte ich genommen, weil ich hier öfters was von DUMMY device gelesen habe - dachte das sei hier passend, vor allem weil ich mir so vorkomme.
Die Werte in kurzform zu loggen spart etwas platz, werde ich also so lassen.

Ich probier's aus und melde mich dann wieder - vielen vielen dank für eure hilfe

Mathias

Funktioniert

2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog T: 20:40:59
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog KVL: 73
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog KRL: 70
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog KT: 77
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog KMP: 69
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKVL: 29
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKRL: 29
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKVS: 40
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKMP: 25
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AT: 10
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP1O: 74
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP2O: 78
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP3O: -127
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP1M: 60
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP2M: 62
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP3M: -127
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP1U: 40
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP2U: 36
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog AP3U: -127
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKF: 1
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKADD: 0
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKSUB: 0
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog HKNA: 0
2016-03-26 20:57:08 KeyValueProtocol ARDUINOLog REB: 0;HKN=1

bis auf den einen kleinen Fehler.

Noch mal vielen Dank!