FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: ak323 am 16 Januar 2017, 22:20:46

Titel: [gelöst] ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 16 Januar 2017, 22:20:46
Hallo zusammen !
Ich bekomme einen ReadingsVal "15" zurück und möchte mir diesen statt als 15 als 16-Bit Bitstring darstellen lassen - also "0000000000001111" 
(-> gibt mir die Schaltzustände von 16 Ausgängen meiner Wärmepumpe an)

Kann mir jemand einen Tipp geben, wie ich das realisieren kann ?
(Suche findet leider nichts)

VG ak323
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Otto123 am 16 Januar 2017, 22:42:26
Hi,

obwohl ich relativ wenig Ahnung davon habe -> $dual = sprintf("%b",$decimal);
Zumindest ergibt {sprintf("%b",15)} -> 1111 in der FHEM Kommandozeile.

Jetzt musst Du bloß noch das Format für 16 bit finden.

Gruß Otto
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Markus Bloch am 16 Januar 2017, 22:52:24
Einfach nochmal durch sprintf() jagen und als 16 stellige Zahl mit führenden 0'en ausgeben:

sprintf("%016d",sprintf("%b",15))
=>
0000000000001111
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 16 Januar 2017, 22:57:37

{ sprintf("%016b",15) }
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Otto123 am 16 Januar 2017, 22:58:41
Hi Markus,
geht doch noch einfacher  8)
{sprintf("%016b",15)}
betateilchen war schneller  ???
Gruß Otto
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Markus Bloch am 16 Januar 2017, 23:00:08
Verdammt, ich hatte das auch probiert, aber ohne die Null vorneweg  >:(
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: CoolTux am 16 Januar 2017, 23:02:12

{ sprintf("%016b",ReadingsVal($name,$reading,default)) }


Ich wollte auch mal was schreiben.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 16 Januar 2017, 23:05:48

{ sprintf("%016b",ReadingsNum($name,$reading,$default)) }


Es geht schließlich um Zahlen.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: CoolTux am 16 Januar 2017, 23:08:50
Ja Du hast Recht. Wenn dann richtig. Kann ja auch mal Müll drin stehen.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 05 Oktober 2020, 21:06:15
Supi Ihr Spitzen-Experten ... !
Funktioniert 1A ...

Wenn Ihr mir jetzt noch erklärt, wie ich ein einzelnes Bit auslese (z.B. b0), um damit ein Icon anzuzeigen, dann seid Ihr sogar Helden !

Also:
Wenn b0 = 0, Icon Quellenpumpe inaktiv, wenn b0 = 1, Icon Quellenpumpe aktiv.

Danke schonmal .. ak323
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Sany am 08 Oktober 2020, 16:16:14
Hallo ak323,

beim Arduino hatte ich mal damit zu tun, es geht aber auch in Perl. Kurz gesagt: Die Zahl "maskieren" führt zum Ergebnis. Maskieren geht mit einer binären Addition.
Bsp:

              dez       bin
Zahl          6        0110
Maske         4        0100
---------------------------
&(binär Addition)      0100




Ein Versuch nur mit einer Maske hat bei größeren Zahlen nicht immer gestimmt, weshalb folgende Methode besser ist:
Die gewünschte Zahl wird bitweise so weit nach rechts verschoben, bis die gewünschte Stelle ganz rechts steht. Dann wird einfach mit 1 maskiert, also binär addiert und du hast dann 1 oder 0 als Ergebnis. Beim Zählen, wie weit nach rechts verschoben wird, musst du von 0 anfangen. Im Beispiel oben also 2.


4 (0110) >> 2 ergibt 1 (0001), Maske 0001 binär addiert(&) ergibt 1. 3 (0011) >> 2 ergibt 0 (0000), maskiert(&) mit 1 (0001) ergibt 0.


Du musst vorher auch nichts umwandeln, binäres Rechen geht direkt mit den Dezimalzahlen.


Hier ein Dummy zum rumspielen (als RAW direkt zum einfügen)




defmod Waermepumpe dummy
attr Waermepumpe readingList Ausgang Maske
attr Waermepumpe room Test
attr Waermepumpe setList Ausgang:textField Maske:selectnumbers,0,1,15,0,lin
attr Waermepumpe stateFormat einzelBit
attr Waermepumpe userReadings AusgangBIN:Ausgang.* { sprintf("%016b",ReadingsNum($name,"Ausgang",0));; }, einzelBit {(((ReadingsNum($name,"Ausgang",0) >> ReadingsNum($name,"Maske",0)) & 1) == 1)?"on":"off";;}, BINmaske { sprintf("%016b",1 << ReadingsNum($name,"Maske",0));; }
attr Waermepumpe webCmd Ausgang:Maske
attr Waermepumpe webCmdLabel "Zahl 0-65535":"Stelle des Bit 0-15"



Im textfeld Ausgang eine Zahl eintippen und dann ausserhalb des Textfelds klicken, dann wird der Wert übernommen. Dann kannst Du damit rumspielen mit Zahlen, die Deine Wärmepumpe ausspuckt und welches "Bit" du dann auslesen willst. In der Detailansicht siehst Du auch die einzelnen "bits"


Weitere Infos zu den Grundlagen: https://rolfrost.de/bitops.html


Viele Erfolg!
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 08 Oktober 2020, 21:15:03
Dake Sany,
japp .. das funktioniert soweit .. jetzt muss es es nur noch an die realen Readings meiner Wärmepumpe angepasst bekommen ...
Werde berichen, wenn ich mal zum Probieren gefunden habe.

VG ak323
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 22 Januar 2022, 13:07:30
Hallo Leute, ich muß das Thema  noch mal hochholen, da ich immer noch die 16 Schaltausgänge einzeln darstellen zu versuche ..
Das Listing liefert folgendes:

Internals:
   NAME       WaermepumpeStati
   NR         1264
   STATE      on
   TYPE       dummy
   READINGS:
     2022-01-22 12:57:29   Ausgang         1
     2022-01-22 12:57:29   AusgangBIN      0000000000000001
     2022-01-22 12:57:30   BINmaske        0000000000000001
     2022-01-22 12:57:30   Maske           0
     2022-01-22 12:57:30   einzelBit       on
Attributes:
   group      Wärmepumpe
   readingList Ausgang Maske
   room       TEST
   setList    Ausgang:textField Maske:selectnumbers,0,1,15,0,lin
   stateFormat einzelBit
   userReadings AusgangBIN:Ausgang.* { sprintf("%016b",ReadingsNum($name,"Ausgang",0)); }, einzelBit {(((ReadingsNum($name,"Ausgang",0) >> ReadingsNum($name,"Maske",0)) & 1) == 1)?"on":"off";}, BINmaske { sprintf("%016b",1 << ReadingsNum($name,"Maske",0)); }
   webCmd     Ausgang:Maske
   webCmdLabel "Zahl 0-65535":"Stelle des Bit 0-15"



Der Ausgang ist die Dezimaldarstellung des Ausgangs der Wärmepumpe
AusgangBIN die Umwandlung in 16 bit
BINmaske stellt ein welches Bit betrachtet werden soll (hier das 0, also das ganz rechte)
einzelBit zeigt mit "on", daß es auf 1 steht

Jetzt möchte ich für jedes der Bits ein Dummy definieren, welches den Status der jeweiligen Bits darstellt.
Das hier funktioniert leider trotz viele Versuche nicht:

define WaermepumpeStatiBit0 dummy
attr WaermepumpeStatiBit0 devStateIcon off:sani_pump@orange on:sani_pump
attr WaermepumpeStatiBit0 event-on-change-reading .*
attr WaermepumpeStatiBit0 group Wärmepumpe
attr WaermepumpeStatiBit0 room TEST
attr WaermepumpeStatiBit0 stateFormat 1
attr WaermepumpeStatiBit0 userReadings AusgangBINBit0:Ausgang.* { sprintf("%016b",ReadingsNum($name,"Ausgang",0));; }, einzelBit {(((ReadingsNum($name,"Ausgang",0) >> ReadingsNum($name,0,0)) & 1) == 1)?"on":"off";;}, BINmaske { sprintf("%016b",1 << ReadingsNum($name,0,0));; }


-> hier habe ich Maske auf 0 gesetzt, weil nicht ja das ganz rechte Bit interessiert, ... entsprechen 1, 2, 3 bei den weiteren war meine Vorstellung ..

Kann mir bitte noch mal jemand "auf die Sprünge" helfen ?

Danke nochmals, ak323
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Otto123 am 22 Januar 2022, 14:07:33
Du meinst sowas? 16 Dummies waren mir zuviel. Ich habe es mal zu Fuß in 16 Readings verpackt. Kann man sicher besser machen.
Den Ursprung einzelBit, BINMaske und Maske habe ich mal drin gelassen, der ist eigentlich obsolete
defmod Waermepumpe dummy
attr Waermepumpe readingList Ausgang Maske
attr Waermepumpe room TEST
attr Waermepumpe setList Ausgang:textField Maske:selectnumbers,0,1,15,0,lin
attr Waermepumpe stateFormat einzelBit
attr Waermepumpe userReadings AusgangBIN:Ausgang.* { sprintf("%016b",ReadingsNum($name,"Ausgang",0));; }, \
einzelBit {(((ReadingsNum($name,"Ausgang",0) >> ReadingsNum($name,"Maske",0)) & 1) == 1)?"on":"off";;},\
einzel00 {(((ReadingsNum($name,"Ausgang",0) >> 0) & 1) == 1)?"on":"off";;},\
einzel01 {(((ReadingsNum($name,"Ausgang",0) >> 1) & 1) == 1)?"on":"off";;},\
einzel02 {(((ReadingsNum($name,"Ausgang",0) >> 2) & 1) == 1)?"on":"off";;},\
einzel03 {(((ReadingsNum($name,"Ausgang",0) >> 3) & 1) == 1)?"on":"off";;},\
einzel04 {(((ReadingsNum($name,"Ausgang",0) >> 4) & 1) == 1)?"on":"off";;},\
einzel05 {(((ReadingsNum($name,"Ausgang",0) >> 5) & 1) == 1)?"on":"off";;},\
einzel06 {(((ReadingsNum($name,"Ausgang",0) >> 6) & 1) == 1)?"on":"off";;},\
einzel07 {(((ReadingsNum($name,"Ausgang",0) >> 7) & 1) == 1)?"on":"off";;},\
einzel08 {(((ReadingsNum($name,"Ausgang",0) >> 8) & 1) == 1)?"on":"off";;},\
einzel09 {(((ReadingsNum($name,"Ausgang",0) >> 9) & 1) == 1)?"on":"off";;},\
einzel10 {(((ReadingsNum($name,"Ausgang",0) >> 10) & 1) == 1)?"on":"off";;},\
einzel11 {(((ReadingsNum($name,"Ausgang",0) >> 11) & 1) == 1)?"on":"off";;},\
einzel12 {(((ReadingsNum($name,"Ausgang",0) >> 12) & 1) == 1)?"on":"off";;},\
einzel13 {(((ReadingsNum($name,"Ausgang",0) >> 13) & 1) == 1)?"on":"off";;},\
einzel14 {(((ReadingsNum($name,"Ausgang",0) >> 14) & 1) == 1)?"on":"off";;},\
einzel15 {(((ReadingsNum($name,"Ausgang",0) >> 15) & 1) == 1)?"on":"off";;},\
BINmaske { sprintf("%016b",1 << ReadingsNum($name,"Maske",0));; }
attr Waermepumpe webCmd Ausgang:Maske
attr Waermepumpe webCmdLabel "Zahl 0-65535":"Stelle des Bit 0-15"
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 22 Januar 2022, 15:50:27
Hmmm.. danke Otto123, ...
genau so .... !

Jetzt kann ich die einzelnen Readings entsprechend weiterverarbeiten ...
DANKE !

##################################
Readings
Ausgang
4
2022-01-22 16:02:18
AusgangBIN
0000000000000100
2022-01-22 16:02:18
BINmaske
0000000000000001
2022-01-22 16:02:18
Maske
0
2022-01-22 15:59:59
einzel00
off
2022-01-22 16:02:18
einzel01
off
2022-01-22 16:02:18
einzel02
on
2022-01-22 16:02:18
einzel03
off
2022-01-22 16:02:18
einzel04
off
2022-01-22 16:02:18
einzel05
off
2022-01-22 16:02:18
einzel06
off
2022-01-22 16:02:18
einzel07
off
2022-01-22 16:02:18
einzel08
off
2022-01-22 16:02:18
einzel09
off
2022-01-22 16:02:18
einzel10
off
2022-01-22 16:02:18
einzel11
off
2022-01-22 16:02:18
einzel12
off
2022-01-22 16:02:18
einzel13
off
2022-01-22 16:02:18
einzel14
off
2022-01-22 16:02:18
einzel15
off
2022-01-22 16:02:18
einzelBit
off
2022-01-22 16:02:18
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 22 Januar 2022, 16:18:15
Zitat von: ak323 am 22 Januar 2022, 13:07:30
ReadingsNum($name,0,0)

Das funktioniert so nicht.
Da wo Du die fette Null hast, muss der Name eines readings stehen, kein absoluter Wert.
Da kein reading mit dem Namen "0" gefunden wird, wird der defaultwert (dritter Parameter) zurückgegeben.
Das funktioniert also eher "zufällig" so, wie Du es möchtest.

Wenn Du an der Stelle mit einem absoluten Wert arbeiten willst, kannst Du einfach den absoluten Wert hinschreiben anstatt einen Funktionsaufruf.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 22 Januar 2022, 17:14:49
Danke, wieder was dazu gelernt.
Ott0123's Definition funktioniert und hat mir weiter geholfen ...

Jetzt muß ich nur noch ein Readingsproxy für die einzelxx Bits definiert bekommen .. dann kann ich mir den Status jeder geschalteten Komponente anzeigen ...
Aber auch hier habe ich so meine Probleme ..  8)
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 22 Januar 2022, 18:17:23
Zitat von: Otto123 am 22 Januar 2022, 14:07:33
Ich habe es mal zu Fuß in 16 Readings verpackt. Kann man sicher besser machen.

ich weiß nicht, ob es 'besser' ist, aber auf jeden Fall performanter, da viel weniger Funktionsaufrufe von ReadingsNum() und viel weniger Texte ("on","off")


attr Waermepumpe userReadings AusgangBIN:Ausgang.* {$data{v}= ReadingsNum($name,'Ausgang',0);;$data{0}='off';;$data{1}='on';;sprintf("%016b",$data{v});;}, \
einzel00 {$data{$data{v} >>  0 & 1}},\
einzel01 {$data{$data{v} >>  1 & 1}},\
einzel02 {$data{$data{v} >>  2 & 1}},\
einzel03 {$data{$data{v} >>  3 & 1}},\
einzel04 {$data{$data{v} >>  4 & 1}},\
einzel05 {$data{$data{v} >>  5 & 1}},\
einzel06 {$data{$data{v} >>  6 & 1}},\
einzel07 {$data{$data{v} >>  7 & 1}},\
einzel08 {$data{$data{v} >>  8 & 1}},\
einzel09 {$data{$data{v} >>  9 & 1}},\
einzel10 {$data{$data{v} >> 10 & 1}},\
einzel11 {$data{$data{v} >> 11 & 1}},\
einzel12 {$data{$data{v} >> 12 & 1}},\
einzel13 {$data{$data{v} >> 13 & 1}},\
einzel14 {$data{$data{v} >> 14 & 1}},\
einzel15 {$data{$data{v} >> 15 & 1}}
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 22 Januar 2022, 18:39:27
Danke betateilchen, Dein Ansatz funktioniert auch !

Wenn Ihr mir jetzt noch einen Tipp gebt, wie ich den Status der Einzelbits jeweils angezeigt bekomme, dann seid Ihr meine Helden (beide !)

define WpumpeSA00 readingsProxy Waermepumpe:einzel00
attr WpumpeSA00 alias Quellenpumpe2
attr WpumpeSA00 devStateIcon on:sani_buffer_temp_all@orange off:sani_buffer_temp_all
attr WpumpeSA00 event-on-change-reading .*
attr WpumpeSA00 group Wärmepumpe
attr WpumpeSA00 room TEST
attr WpumpeSA00 stateFormat state
attr WpumpeSA00 valueFn {($VALUE == 1)?"on":"off"}


... funktioniert leider nicht ... / verzweifel ..
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Otto123 am 22 Januar 2022, 18:56:22
Zitat von: betateilchen am 22 Januar 2022, 18:17:23
ich weiß nicht, ob es 'besser' ist, aber auf jeden Fall performanter, da viel weniger Funktionsaufrufe von ReadingsNum() und viel weniger Texte ("on","off")
Danke für so ein Beispiel. Hab ich es richtig verstanden?
%data ist ein Hash der im userReadings (überall in FHEM?) zur Verfügung steht und den ich (der User - # Hash for user data) befüllen kann. Es ist so eine Art "grüne Variable" die immer recycled wird?
Du füllst drei key/value Pärchen und verwendest diese zur weiteren Abfrage?

So ein Beispiel habe ich schon lange mal gesucht :) 
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 22 Januar 2022, 18:59:51
Zitat von: ak323 am 22 Januar 2022, 18:39:27
Wenn Ihr mir jetzt noch einen Tipp gebt, wie ich den Status der Einzelbits jeweils angezeigt bekomme, dann seid Ihr meine Helden (beide !)

im ganzen Leben hab ich noch kein readingsProxy verwendet... extra für Dich...


defmod WpumpeSA00 readingsProxy Waermepumpe:einzel00
attr WpumpeSA00 devStateIcon on:10px-kreis-rot off:10px-kreis-gruen


funktioniert bei mir einwandfrei.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 22 Januar 2022, 19:03:54
Zitat von: Otto123 am 22 Januar 2022, 18:56:22
%data ist ein Hash der im userReadings (überall in FHEM?) zur Verfügung steht

Überall in FHEM. Ein Blick in die fhem.pl macht schlau:

use vars qw(%data);             # Hash for user data

Zitat von: Otto123 am 22 Januar 2022, 18:56:22
Du füllst drei key/value Pärchen

Ich fülle drei Variablen, die 'zufällig' in einem hash liegen und über diesen angesprochen werden.

Wenn man es ganz korrekt machen möchte, würde man die drei Variablen nach der Verarbeitung wieder aus dem hash löschen.
Aber zugunsten der Übersichtlichkeit habe ich das weggelassen.

Zitat von: Otto123 am 22 Januar 2022, 18:56:22
So ein Beispiel habe ich schon lange mal gesucht :) 

Was ist denn daran so besonders? Das sind doch absolute FHEM basics.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: Otto123 am 22 Januar 2022, 19:09:50
Zitat von: betateilchen am 22 Januar 2022, 19:03:54
Was ist denn daran so besonders? Das sind doch absolute FHEM basics.
Für Dich Du alter 🦊 ;)
Kurz und gut: der %data Hash und das ich ihn verwenden darf war mir neu :) hab oft im userReadings alles doppelt und dreifach eingelesen.
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: betateilchen am 22 Januar 2022, 19:13:23
Du machst sowieso komische Sachen in FHEM... 8)
Titel: Antw:ReadingsVal: Dezimal Wert in BitString darstellen ?
Beitrag von: ak323 am 22 Januar 2022, 19:14:32
Danke Otto123 und betateilchen !

Ihr habt mir sehr geholfen ... und selber auch noch was gelernt !  8)

Absolut nett von EUCH !
VG ak323