HTTPMOD und MesagePack

Begonnen von Nobby1805, 23 Februar 2023, 18:47:55

Vorheriges Thema - Nächstes Thema

Nobby1805

Hallo zusammen,

meine Frage steht schon in der Überschrift. wie komme ich an die Daten des Servers wenn diese nicht per JSON sondern per MessagePack codiert sind?

Vielen Dank für jeden Hinweis
Nobby
FHEM-Featurelevel: 6.2   (fhem.pl:28227/2023-11-29) auf Windows 10 Pro mit Strawberry Perl 5.32.1.1-32bit
TabletUI: 2.7.15
IO: 2xHMLAN(0.965)|HMUSB2(0.967)

rudolfkoenig

Bis auf Weiteres vmtl. nur durch eigene Programmierung, immerhin gibt es ein Perl Modul, der beim Auspacken hilft.

Wer verwendet MessagePack?

Nobby1805

Die Lichtsteuerung SunRiser 8 der Fa. LEDAquaristik, in den FAQs wird auch die Integration in Fhem erwähnt, hat aber wohl noch niemand gemacht

https://www.ledaquaristik.de/FAQ

ZitatDas gesamte Web Frontend benutzt eine API um Ihre Konfiguration zu dem SunRiser zu bringen. Diese API erlaubt das Setzen der Konfiguration, Firmware einzuspielen oder alle anderen Funktionen die Sie im Web Interface haben.

Die Kommunikaton dafür läuft als MessagePack über HTTP vom SunRiser. Wir planen hier wenigstens eine weitere API über GET Parameter hinzuzufügen um z.B. in Systeme wie Fhem eingebunden zu werden. Auf Anfrage werden wir auch gern die MessagePack API dokumentieren, planen aber soweit dies nur für die GET API zutun.

Die Abfrage mit HTTP?MOD klappt schon, ich benötige exakt 2 Byte aus der Message ... muss mal schauen, wie ich daran komme
FHEM-Featurelevel: 6.2   (fhem.pl:28227/2023-11-29) auf Windows 10 Pro mit Strawberry Perl 5.32.1.1-32bit
TabletUI: 2.7.15
IO: 2xHMLAN(0.965)|HMUSB2(0.967)

Nobby1805

Ich hatte gehofft, mit dem Attribut parseFunction1 eine Routine einhängen zu können die die MessagePack Struktur auflöst damit danach der Rest mit Regex bearbeitet werden kann
Soweit ich den Code im Modul verstehe, wird die Funktion aber erst sehr spät aufgerufen und man muss dann dort auch die Umwandlung und Zuweisung selbst machen ... ?? :-(

Vielleicht kann sich ja auch der Modulautor dazu bitte einmal äußern

So halbwegs habe ich das Problem inzwischen gelöst bekommen, es bleibt nur 1 Problem: das Ergebnis ist ein Byte und das Reading erhält z.B. den Wert A (hex 41) müsste aber die Zahl 65 sein. Kriegt man das irgendwie mit Bordmitteln / Regex hin?

Viele Grüße
Nobby
FHEM-Featurelevel: 6.2   (fhem.pl:28227/2023-11-29) auf Windows 10 Pro mit Strawberry Perl 5.32.1.1-32bit
TabletUI: 2.7.15
IO: 2xHMLAN(0.965)|HMUSB2(0.967)

rudolfkoenig

#4
Hier ein Beispielprogramm, wie man einfache MessagePacks in FHEM uebernehmen kann, leider nicht mir HTTPMOD.
Voraussetzung ist die Installation von Data::MessagePack, z.Bsp. mit "sudo cpan -i Data::MessagePack"

Zunaechst in FHEM/99_myUtils.pm Folgendes hinterlegen:
use Data::MessagePack;
sub
messagePack($$;@)
{
  my ($me,$url,@rd) = @_;
  HttpUtils_NonblockingGet({ url=>$url, callback=>sub($$$){
    return Log 1, "ERROR: messagePack: $_[1]" if($_[1]);
    my $mp = Data::MessagePack->new()->unpack($_[2]);
    map { readingsSingleUpdate($defs{$me}, $_, $mp->{$_}, 1); } @rd;
  }});
}


Aufruf aus FHEM kann z.Bsp. per at erfolgen:
define mp at +*00:10 { messagePack($SELF, 'http://localhost:8083/fhem/test/x2.MessagePack', 'compact', 'schema')  }


x2.MessagePack enthaelt das auf dem MessagePack Homepage (https://msgpack.org/) prominent sichtbares Beispiel mit compact und schema.

rudolfkoenig

Zitatdas Ergebnis ist ein Byte und das Reading erhält z.B. den Wert A (hex 41) müsste aber die Zahl 65 sein. Kriegt man das irgendwie mit Bordmitteln / Regex hin?

Mit Regex wird eine generisch Loesung unuebersichtlich.
Fuer die Umwandlung hat perl die ord Funktion (ord("A") == 0x41 == 65).
Oder wenn man was maechtigeres haben will, dan unpack().

Nobby1805

Erst einmal vielen Dank an rudolfkoenig für die Hilfe  :D

Ich habe es inzwischen nur mit Bordmitteln hinbekommen, zwar nur für meinen speziellen Anwendungsfall ... aber das reicht mir nach einer (fast) Nachtschicht erst einmal

defmod AquaTemp HTTPMOD http://192.168.1.45/state 600
attr AquaTemp getURL http://192.168.1.45/state
attr AquaTemp preProcessRegex s/.*(sensor)s.*3d28.{10}(.)/$1 $2/g
attr AquaTemp reading01Encode none
attr AquaTemp reading01Name sensor
attr AquaTemp reading01Regex sensor.(.)
attr AquaTemp userReadings Temp {ord(ReadingsVal("AquaTemp","sensor",0))/10.}
attr AquaTemp verbose 4

setstate AquaTemp 2023-02-25 11:23:28 Temp 22.6
setstate AquaTemp 2023-02-25 11:23:28 sensor �


das preProcessRegex und das reading01Regex kann man vermutlich auch noch zu einem kombinieren, aber es läuft und das reicht mir

Viele Grüße Nobby1805

PS der String der vom Server kommt sieht übrigens so aus��time�c���tick�ki�uptime����service_mode��logsize�ܨ��errsize�Bs�pwms��1��2��3�ѡ4��5��6��7��8��sensors��b500000cce343d28����
oder mit einem Tool aufgelöst
Zitat{
   "time": 1677147297,
   "tick": 150075377,
   "uptime": 150075,
   "service_mode": 0,
   "logsize": 14451660,
   "errsize": 4346715,
   "pwms": {
      "1": 520,
      "2": 520,
      "3": 721,
      "4": 0,
      "5": 520,
      "6": 0,
      "7": 0,
      "8": 0
   },
   "sensors": {
      "b500000cce343d28": [
         1,
         226
      ]
   }
}
FHEM-Featurelevel: 6.2   (fhem.pl:28227/2023-11-29) auf Windows 10 Pro mit Strawberry Perl 5.32.1.1-32bit
TabletUI: 2.7.15
IO: 2xHMLAN(0.965)|HMUSB2(0.967)

Nobby1805

Hallo , ich schon wieder :)

läuft alles OK, bis auf dass keine Events bei der Änderung des Wertes erzeugt werden

EventOn...Reading hilft nicht, was tun?
FHEM-Featurelevel: 6.2   (fhem.pl:28227/2023-11-29) auf Windows 10 Pro mit Strawberry Perl 5.32.1.1-32bit
TabletUI: 2.7.15
IO: 2xHMLAN(0.965)|HMUSB2(0.967)