panStamp support

Begonnen von justme1968, 24 April 2013, 21:38:24

Vorheriges Thema - Nächstes Thema

justme1968

guten abend,

auch wenn es noch viel zu früh und unfertig ist hier kurz ein hinweis das ich mit der integration der panStick hardware in fhem angefangen habe. falls noch jemand etwas in dieser richtung tut wäre es schön zusammen daran zu arbeiten.

mehr hier: Link

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

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

justme1968

ich habe die panStamp/panStick kombination inzwischen ohne probleme in fhem laufen.

da das modul aus einem umbenannten cul modul entstanden ist und ich versucht habe alle features wie send und receive queue, 1% check, usb device öffnen und autocreate bei unbekannten nachrichten beizubehalten ist es dem cul modul immer noch sehr ähnlich.die unterschiede sind die initialisierungs sequenz, ein anderes zeilenende zeichen, die liste der client module und natürlich die fs20 und hm besonderheiten.

alles was nicht direkt mit dem protokoll oder der hardware zu tun hat ist aber noch so ähnlich oder identisch das es fast schade ist den code zu kopieren statt gemeinsam zu verwenden.

welche meinung gibt es hierzu?

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

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

rudolfkoenig

Bevor wir CUL.pm umbauen, um ein paar Zeilen zu sparen, wuerde ich die Zeilen lieber duplizieren. Das vereifacht auch die Aenderung von CUL.pm, da nicht jeder ein panStamp zur Verfuegung hat, um damit zu testen.

justme1968

ich habe hier Link eben eine erste test version gepostet.

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

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

justme1968

bis jetzt sind die panstamp module nach dem gleichen zweistufigen modell wie die cul/fs20/hm module implementiert.

ich würde das für panstamp/swap gerne auf ein dreistufiges konzept erweitern. d.h neben dem modul das das funkmodem bedient und dem modul das das protokoll implementiert und ganz generisch mit allen swap devices umgehen kann noch eine dritte ebene mit modulen die device spezifische funktionen anbieten.

zur erklärung: die kommunikation per swap erfolgt über abstrakte 'register' die gesendet und empfangen und so gelesen und beschrieben werden können. ein register kann ein oder mehrere readings oder 'anweisungen' enthalten. mit dem swap modul ist es möglich jedes beliebige swap device über sein device description xml file in fhem einzubinden. um mit dem device zu kommunizieren stehen dann regGet und regSet kommandos auf recht niedriger ebene zur verfügung. das reicht zum beispiel völlig aus um sensor werte wie temperatur,feuchtigkeit oder luftdruck zu lesen und wie jeden anderen sosor in fhem einzubinden. auch das schalten von relais oder dem rgb led board ist so möglich.

sobald das device aber 'intelligenter' wird und z.b dim,pct oder ein äquivalent zu on-for-timer anbietet ist es nicht mehr besonders intuitiv das 'zu fuss' über die register zu machen und es wäre schön in fhem ein on-for-timer abzusetzen das dann auf die entsprechenden register im swap protokoll gemappt wird und vom swap modul dann über das panstamp modul gesendet wird. für den rückweg gilt im prinzip das gleiche. eine vom panstamp modul empfangene nachricht wird vom swap modul geparsed und aufbereitet und sollte dann je nach device z.b. als lampe oder dimmer in fhem erscheinen.

ich habe jetzt ein wenig experimentiert und es scheint z.b. so etwas möglich zu sein:

sub
SWAP_RGB_Initialize($)
{
  my ($hash) = @_;
 
  require "$attr{global}{modpath}/FHEM/34_SWAP.pm";

  $hash->{SWAP_SetFn}     = "SWAP_RGB_Set";
  $hash->{SWAP_GetFn}     = "SWAP_RGB_Get";
  $hash->{SWAP_ParseFn}  = "SWAP_RGB_Parse";

  return SWAP_Initialize($hash);
}


d.h. ein hypothetisches rgb led modul setzt seine eigenen set und get und parse methoden und ruft die initialisierung des normalen swap moduls auf. das normale swap modul ruft dann an geeigneter stelle in den normalen set, get und parse methoden zusätzlich zu den generischen auch noch die jeweils device spezifischen routinen auf. diese implementieren dann die in fhem für eine lampe vorgesehenen on/of/on-for-timer/... und setz diese auf die low level register kommandos um.

klingt das halbwegs vernünftig? ist eine solche dreiteilung langfristig vielleicht noch an anderer stelle interessant?

gruss
  andre



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

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

Tobias

eine kurze zwischenfrage: muss auf den panstamps irgendwelche firmware drauf? Muss ich da etwas selbst in bascom oder C programmieren?? Ich hoffe nicht, bin froh perl etwas zu können ;)
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

justme1968

ja. es muss was drauf.

es gibt aber schon diverse sketches für temperatur/luftdruck/feuctigkeit, bodenfeuchte, relais und io, 1-wire und das rgb board. selber programmieren musst du also eigentlich nur wenn du eigene/neue hardware anschliessen willst. für die 'fertige' hardware musst du nur den beispiel code drauf brennen. das geht mit einem mausklick.

ansonsten ist es c++ und viel viel einfacher als perl :)

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

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

justme1968

ich habe die idee noch etwas erweitert und jeweils eine set und get liste analog zur AttList und ähnlich wie in den SetExtensions verwendet:$hash->{SWAP_SetList}   = { on => 0, off => 0, "on-for-timer" => 1, rgb => 1, toggle => 0, };. der ansatz die 'parent' initialize funktion aufzurufen funktioniert bis jetzt ziemlich gut. eine einzige kleine unschönheit habe ich bis jetzt bemerkt: ich muss im generellen initialize vor dem aufruf von AssignIoPort den TYPE auf den type des generellen moduls setzen und danach wieder auf den des spezialisierten moduls.

wäre es denkbar AssignIoPort so zu erweitern das wenn kein direkter match auf den modul typ in der client liste gefunden die suche auf module die mit dem typ als prefix beginnen erweitert wird? so das z.b. ein modul SWAP_RGB auch bei einer client liste von nur :SWAP: matched.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

Dreiteilung:
- ich habe prinzipiell nichts dagegen, obwohl dreistufig hier missversteaendlich ist: es ist entweder das generische oder das spezialisierte Modul, der die Anfragen beantwortet.
- ZWave.pm macht sowas aehnliches meiner Ansicht nach recht elegant :), auch wenn es nur zwei Ebenen verwendet: ein Geraet kann mehrere Klassen (== interfaces) haben, und je nach interface gibt es zusaetzliche Befehle bzw. Parse Funktionen. Aber wie gesagt, ich habe nichts gegen alternative Loesungesansaetze.

AssignIoPort:
- die Notwendigkeite einer Fallback auf Dateibasis verstehe ich nicht: wer soll wann wessen IoDevice sein, bzw. wo passt es jetzt nicht?
- AssignIoPort sollte nicht in Initialize sondern in define oder AttrFn durchgefuehrt werden.

justme1968

was meinst du genau mit missverständlich? so wie ich es gerade verwende ist es auf der logischen ebene tatsächlich so das beide module anfragen beantworten. das allgemeine stellt z.b. die generellen register kommandos zur verfügung und leitet die anderen kommandos an das spezielle modul weiter. aus nutzer sicht verwendet er nur das spezielle modul das die speziellen und allgemeinen kommandos bereitstellt. aus entwickler sicht 'erbt' das spezielle modul die allgemeinen kommandos. es sind also wirklich drei ebenen:
- hardware/funk (panstamp -> entspricht cul)
- protokoll und generische funktionen (swap)
- device spezifisch: licht/dimmer/...

bei fs20 ist im prinzip die 1. und 2. ebene zusammen gefasst weil an den nachrichten direkt erkenn bar ist um welches device es geht( schalter/wetter/...) bei homematic ist die 2. und 3. zusammen gefasst weil sich ein modul um alle homematic devices kümmert. bei swap geht beides nicht wirklich weil zum einen ich nicht auf ebene 1. entscheiden kann zu welchem device sie gehören und zum anderen die devices von den unterschiedlichsten 'herstellern' kommen und das gleiche register völlig unterschiedliches bedeuten kann.

zwave schaue ich mir mal an. mir geht es aber nicht nur darum das ein gerät mehrere klassen/interfaces haben kann sondern darum das der code für diese unterschiedlichen geräte zum einen nicht alle in einem file stehen müssen sondern auch von völlig unterschiedlichen entwicklern kommen können die sich nur sehr minimal abstimmen müssen.

ein konkretes beispiel ist der rgb led kontroller. der funktioniert mit dem generellen modul auf register ebene. so zu sagen zu fuss. um ihm on und off kommandos beizubringen wäre ein weg im generellen modul sonderfälle einzubauen und dann z.b. diese zusätzlichen kommandos mit anzubieten. jetzt erweitere ich aber z.b. meine rgb firmware noch um ein on-for-timer das auf dem modul selber läuft und habe noch die ir fernbedienung implementiert. das wären dann wieder noch mehr sonderfälle. das ist zwar an sich schon nicht schön (und funktioniert z.b. bei homematic nur weil alle geräte von einem hersteller kommen und ein einziger entwickler alle implementiert). es wird aber spätestens dann wirklich unhandlich wenn die geräte von unterschiedlichen 'herstellern' kommen und nicht mehr ein entwickler alles implementiert oder auch nur koodriniert. wenn jemand sein rgb modul auf andere art erweitert und dann seine Änderungen lokal einbaut und die beim nächsten update wieder flöten gehen ist es einfach nicht gut. schöner ist es wenn er ein 'abgeleitetes' modul schreiben kann das NUR die erweiterten kommandos anbietet und alles andere an das allgemeine SWAP modul delegiert. in meiner beispiel implementierung an der ich gerade arbeite schrumpft so das led modul auf ein initialize, ein set und ein get mit einer hand voll zeilen. das define, das protokoll, io und alle allgemeinen kommandos bleiben im allgemeinen modul.

zum AssignIoPort: die kurze antwort: natürlich wird es im initialize durchgeführt, zur zeit wird aber geprüft ob das modul exakt in der client liste ist. ich möchte aber das alle jetzigen und zukünftigen clients matchen ohne das ich die client liste jedes mal für ein neues spezialisiertes modul oder jeden anwender der sein eigenes modul schreibt erweitern muss. also wünsche ich mir ein matchen auf z.b. auf SWAP\w*.

die lange antwort: in der client liste von panStamp steht :SWAP:, das generelle modul heißt SWAP und dort im define wird das AssignIoPort aufgerufen. bis hierher noch kein problem. jetzt schreibe ich das 'erweiterete' SWAP_RGB modul. in diesem brauche ich kein define weil mir das define des allgemeinen moduls reicht. also verwende ich es in meinem initialize direkt als DefFn ohne eine eigene zu implementieren (real mache ich sogar noch weniger in dem ich auch das initialize des allgemeinen SWAP moduls verwende und so noch nicht mal etwas vom define wissen muss). jetzt ist aber der TYPE des moduls während  des define aufrufs nicht mehr SWAP sondern SWAP_RGB und das matched nicht mehr auf die client liste des panStamp moduls und ich bekomme kein IODev. zur zeit löse ich es im define des allgemeinen moduls so:  my $type = $hash->{TYPE};
  $hash->{TYPE} = "SWAP";
  AssignIoPort($hash);
  $hash->{TYPE} = $type;
das ist aber nicht sehr elegant.

schon wieder so viele worte für etwas das eigentlich ganz einfach ist wenn man es vor sich hat :). und nerven soll es auch nicht...
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

justme1968

wie wäre es wenn man AssignIoPort den TYPE einfach als optionalen parameter übergeben könnte?
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

> was meinst du genau mit missverständlich?

Dass aus benutzersicht nicht 3 Geraete definiert werden muessen, sondern nur zwei. Das dritte Modul wird per "use" geholt, und ist nur fuer den Entwickler wichtig.


AssignIoPort: ich bin nicht ganz sicher, ob man sich mit der freien Erweiterbarkeit ein gefallen tut, aber ich habe jetzt AssignIoPort so geaendert, dass die Client Elemente als regexp (in ^$) geprueft werden. Damit sollte dein Problem auch loesbar sein.

justme1968

ich bin gerade dabei die unterstützung für den repeater mode in das swap modul einzubauen. eigentlich wäre das eine schöne anwendung für die AddDuplicate/CheckDuplicate funktionen. leider sind die aber aus zwei gründen zur zeit nicht dafür zu gebrauchen:

- es werden nur duplikate von unterschiedlichen IODevs erkannt. im repeater mode werden aber identische nachrichten vom gleichen IODev empfangen.

- es steckt 'wissen' über den aufbau einer fs20 nachricht drin bzw.  das hinzufügen und der check sind eigentlich noch zu früh weil es direkt nach dem empfang im IODev bzw im dispatch passiert. eigentlich gehört aber beides von der logik her nach das parsen weil erst dann identische nachrichten (die sich z.b. im sender, einer prüfsumme oder einem timestamp die alle durch das resend verändert werden können) wirklich unterscheiden kann.

ersteres könnte man lösen in dem man den check auf unterschiedliches IODev einfach streicht. mir fällt kein fall ein bei dem das probleme machen sollte.

das zweite könnte man lösen in dem man auf irgend eine art angeben kann welche teile einer nachricht von der prüfung ausgenommen werden sollen oder in dem man dem device dessen parse funktion aufgerufen wird eine 'fingerprint' funktion gibt die die nachricht so aufbereitet das ein einfache vergleich ausreicht:

- AddDuplicate wird nicht mehr vom IODev aufgerufen (sondern von Dispatch s.u.)
- im IODev gibt es ein flag das angibt ob der check auf duplikate durchgefürt werden soll.
- Dispatch ruft CheckDuplicate nicht mit der nachricht auf die dispatched werden soll sondern mit einer vom parsenden device aufbereiteten (dem fingerprint)
- wenn es kein duplikat ist ruft Dispatch AddDuplicate mit der aufbereitete version auf

ist so eine generelle lösung sinnvoll bzw. würdest du so etwas allgemein einbauen? oder ist dir eine lösung im device lieber?


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

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

rudolfkoenig

> es werden nur duplikate von unterschiedlichen IODevs erkannt.

Ist ja auch exakt dafuer gebaut.


> im repeater mode werden aber identische nachrichten vom gleichen IODev empfangen.

Wenn man sowas richtig loesen will, dann sollten die Repeater-Nachrichten erkennbar sein, und der Repeater als eigenstaendiges Geraet in fhem angelegt sein (wie z.Bsp. CUL_RFR), damit wuerde CheckDuplicate die doppelten Nachrichten auch filtern. Und man wuesste als Enduser, woher die Nachrichten kommen, ob der Repeater ueberhaupt was fuer sein Geld tut, usw.

Wenn das nicht geht, dann kann der Benutzer immer noch event-min-interval setzen.


> steckt 'wissen' über den aufbau einer fs20 nachricht drin

Ja, aber nicht sehr viel. Und den Aufwand fuer eine "richtige" Loesung finde ich nicht im Verhaeltnis zum Gewinn. Notfalls kann man diese Pruefung nochmals verschaerfen.


> mir fällt kein fall ein bei dem das probleme machen sollte.

Mir schon: dimup/dimdown bei FS20 Geraeten.


justme1968

der panstamp repeater mode ist kein eigenständiges device sondern die moeglichkeit das jeder panstamp wie in einem mesh network nachrichten erneut senden kann. ein eigenes device wie es fuer homematic passend wäre ist hier nicht sinnvoll. event-min-intervall ist nicht geeignet weil dann alle schnell aufeinander folgende nachrichten unterdrückt werden. wie z.b. beim rauf oder runter dimmen.

nicht viel wissen. aber genug um es nicht wiederverwendbar zu machen.

mir ist nicht ganz klar warum das verschieben und zusammenfassen jeweils genau der zwei zeilen die jetzt die nachricht für die pruefung auf aufbereiten und das kombinieren von prüfen und hinzufügen an einer zentralen stelle kein grosser aufwand im vergleich den kompletten code zu duplizieren. vielleicht irre ich mich aber die idee die mir vorschwebt ist eigenich recht einfach.

das dimup/dimdown beispiel ist mir nicht ganz klar. wenn aufeinander folgende nachrichten sich nicht anhand eines zaehlers oder timestamp unterscheiden ist die prüfung auf unterschiedliche IODev dich nur ein workaround fuer eine zeitliche schwelle.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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