Integration von MySensors in FHEM geplant?

Begonnen von fh555, 06 September 2014, 00:40:58

Vorheriges Thema - Nächstes Thema

ntruchsess

Handling von Acknowlege ist implementiert. Das 'MYSENSORS'-device hat dafür das Attribut 'requestAck' bekommen.

Wenn dieses gesetzt ist, dann werden beim Ausführen von 'set XXX'-befehlen die Readings der MYSENSOR_DEVICE-nodes erst dann aktualisiert, wenn das zugehörige Acknowlege eintrifft. Ist das Attribut nicht gesetzt, geschieht dies sofort (schon beim Absenden der C_SET-message).

- Norbert

while (!asleep()) {sheep++};

hexenmeister

Die neue Version gefällt mir sehr gut. Ich musste zwei Kleinigkeiten ändern, damit sie bei mir problemlos läuft. Dafür habe ich Dir testweise ein Pull-Request geschickt (https://github.com/ntruchsess/fhem-mirror/pull/16). Ich denke, ich weiß jetzt wie es geht (sehr einfach :) ).

Zitatfür die Custom-variablen (V_VAR1 ff) hast Du natürlich recht, die kann man nicht hardcoded mappen. Muss ich mir noch mal genauer durch den Kopf gehen lassen, wie man das einerseits flexibel, andererseits nicht unnötig kompliziert bzw. mit unnötig vielen Attributen macht.
Wir können doch beides machen. MappingAttribute erlauben die Readings generell zu umbenennen, was für di Customs von User auch gemacht werden soll. Für die bekannten können wir intern die selbe Map füllen, die auch von den Map-Attributen gepflegt wird. Somit wird der Benutzen nicht mit vielen Atributen behelligt.

Grüße,

Alexander
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

ntruchsess

Zitat von: hexenmeister am 20 Oktober 2014, 21:42:05sehr einfach :)

gell, kaum macht man's richtig, schon geht's -> Danke Dir. :-)

ja, das mit dem Mapping stelle ich mir auch so in der Art vor. Das mit dem Acknowledge braucht wohl noch intensieves Testen (der Retransmit-mechanismus ist noch recht rudimentär, da braucht es noch eine Logik, die die zeitlichen Abstände größer werden läßt und nach einem Timeout das Device auf 'not available' setzt).

Gruß,

Norbert
while (!asleep()) {sheep++};

hexenmeister

#108
ZitatDas mit dem Acknowledge braucht wohl noch intensieves Testen
Das bezieht sich auf Aktors und für Sensoren nicht relevant, richtig? Müsste man mit einem Relay-Skatch testen können, indem man ihn für verschiedene kurze Zeiträume abschaltet?

EDIT: ich habe noch ein Transmitter-Board, kann mir morgen ein Relay-Aktor bauen, dann habe ich sowohl Sensor als auch ein Aktor zum Testen.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

ntruchsess

im Augenblick schickt das MYSENSORS-modul alle message mit gesetztem requestAck-flag. Um Re-transmits zu vermeiden muss man jetzt noch strukturiert ermitteln, welche Messages von der MySensors.cpp sowieso nicht acknowledged werden.

Gruß,

Norbert
while (!asleep()) {sheep++};

hexenmeister

#110
Habe ein Vorschlag für die Implementierung von Readings-Remapping geschickt. Was mir da nicht gefällt, ist die ID-Nummer des Sensors. Habe aber erstmal drin gelassen, da ein Node anscheinend mehrere gleiche Sensoren haben kann. Muss man noch darüber nachdenken. Eine Möglichkeit wäre ein Readings 'temperatur' zu nennen, wenn es nur einen "TEMP"-Wert gesendet wird und Nummer verwenden, wenn es mehrere existieren.

Ich habe mich schon ein wenig in MySensors.cpp umgesehen. Morgen werde mal ich nach den Ack-Verhalten sehen.
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

ntruchsess

#111
ja, ein Node kann natürlich mehrere gleichartige Sensoren haben. Wenn man das dynamisch machen wollte (indem man nur den Typ des Readings mapped), hat man hier natürlich die Schwierigkeit, dass man das beim Auswerten der Attribute nicht wissen kann, welche und wie viele childIds der Sensor wirklich hat. (Das weis man eventuell beim Eintreffen der ersten C_SET-messages auch noch nicht - man kann die Presentation-messages nach meinem Verständnis ja nicht geziehlt abfragen - mein Versuch mit der I_REBOOT-message war wenig erfolgreich (ein Arduino mit Standard-bootloader geht da in einen nur durch Trennen von der Stromversorgung abbrechbaren Boot-loop). Bleibt eigentlich nur, als AttributeWert die childId explizit mit aufzunehmen. Dann läßt sich das bisherige Reading beim Anlegen oder Löschen des Mappings sauber aufräumen bzw. in das neue Reading überführen.
Die statischen Mappings müssten nach der Logik fast schon zwingend die childId übernehmen.

Also:

attr <node> map_TEMP_1 temperature

bzw.

attr <node> map_TEMP_1 temperature1
attr <node> map_TEMP_2 temperature2

automatisch gemappt wäre es immer:
TEMP_X -> temperatureX

Gruß,

Norbert
while (!asleep()) {sheep++};

hexenmeister

#112
Zitatein Arduino mit Standard-bootloader
Bei MySensors scheint ein eigenes Bootloader zu geben, wenn ich richtig sehe, sogar mit OTA Möglichkeit. Habe mir aber noch nicht näher angesehen.

Deine Beschreibung fürs Mapping schein mir ein sauber gangbarer Weg zu sein.

ZitatDann läßt sich das bisherige Reading beim Anlegen oder Löschen des Mappings sauber aufräumen bzw. in das neue Reading überführen.
Danke nicht, dass das in der Praxis wirklich nötig ist, kaum jemand wird die Mapping-Attribute dynamisch ändern. Aber ist in jedem Fall konsequent und sehr sauber. Sollte also rein.

Viele Grüße,

Alexander
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

ntruchsess

#113
Was ich auch noch nicht eindeutig entschieden habe: Sollte man den Inhalt der Presentation-messages in Internals, Readings oder Attributen ablegen? Internals wären optisch 'am schönsten', damit die aber einen Neustart überleben müsste man die Logik allerdings weitestgehend selbst implementieren. Bei Readings und Attribute hätte man das quasi automatisch.
Define-parameter wie bei MYSENSORS_SENSOR bzw. MYSENSORS_NODE fallen wg. der möglichen 254 childIds ja eher aus.

Sinnvoll ist das, weil man sonst kaum erkennen kann, wenn die childIds der Sensoren mal versehendlich nicht mehr eindeutig sind.

Gruß,

Norbert
while (!asleep()) {sheep++};

ntruchsess

Zitat von: hexenmeister am 21 Oktober 2014, 00:05:35
kaum jemand wird die Mapping-Attribute dynamisch ändern.

Das sehe ich nicht so. Vieleicht nicht oft, aber mindestens dann, wenn man mit dem was Autocreate erzeugt nicht zufrieden ist.
while (!asleep()) {sheep++};

ntruchsess

#115
pull-request gemerged und noch mal überarbeitet commit 1, commit 2.

Kann jetzt Typ und Values mappen (die Value-mappings sind optional. Wird beim Mappen kein value-mapping gefunden, wird einfach der unveränderte Wert benutzt):

attr <node> mapReadingType LIGHT switch 0:off 1:on

(dieses Mapping für LIGHT ist schon genau so als default drin, das muss man tatsächlich nicht mehr extra angeben - mir fällt blos grade kein anderes Beispiel mit gemappten values ein)

Das Definitionsbeispiel für den RelayWithButtonActuator.ino verkürzt sich damit drastisch:


define gateway MYSENSORS /dev/ttyUSB0@115200
attr gateway stateFormat connection
define node MYSENSORS_DEVICE <nodeid>
attr node IODev gateway
attr node stateFormat switch_1
attr node setCommands on:LIGHT_1:1 off:LIGHT_1:0


setCommands und set_<type>_<childId> müssen noch dahingehend überarbeitet werden, dass sie die selben Mappings verwenden, damit man 'attr node setCommands on:switch_1:on off:switch_1:off' verwenden kann.

Gruß,

Norbert
while (!asleep()) {sheep++};

ntruchsess

#116
setCommands und set_<type>_<childId> kommen jetzt auch mit per mapReadingType_<type> gemappten Readings klar:


define gateway MYSENSORS /dev/ttyUSB3@115200
attr gateway requestAck 1
attr gateway stateFormat connection

define node MYSENSORS_DEVICE <nodeid>
attr node IODev gateway
attr node stateFormat switch_1

#3 Varianten den switch zu schalten:
#entweder setCommand: (set node on/set node off)
attr node setCommands on:switch_1:on off:switch_1:off

#oder set_<reading> (set node switch_1 on/set node switch_1 off)
attr node set_switch_1 on,off

#oder set_<TYPE> (set LIGHT_1 0/set LIGHT_1 1)
attr node set_LIGHT_1 0,1


der Vollständigkeit halber noch mal die Links auf die Dateien

00_MYSENSORS
10_MYSENSORS_DEVICE.pm
lib/Device/MySensors/Constants.pm
lib/Device/MySensors/Message.pm

(oder einfach den mysensors_unified-branch aus meinem fhem-mirror auschecken:

git clone https://github.com/ntruchsess/fhem-mirror.git
git checkout mysensors_unified


Wenn Ihr meint, das Modul ist 'reif', dann checke ich es ins SVN ein.

Gruß,

Norbert
while (!asleep()) {sheep++};

hexenmeister

Hallo!

So, habe endlich Zeit, habe alles upgedatet, Relay-Node zusammengesteckt, bin am Testen...

Noch ohne autocreate: nach dem Einschalten der Node kommen folgende Meldungen:

2014.10.21 21:48:08.210 3: MYSENSORS: ignoring internal-msg from unknown radioId 127, childId 255 for I_SKETCH_VERSION
2014.10.21 21:48:08.255 3: MYSENSORS: ignoring presentation-msg from unknown radioId 127, childId 1, sensorType 3


Hat Node die ID 127 von dem FHEM bekommen? Oder hatte ich schon etwas im EEPROM? Also EPPROM an dieser Stelle gelöscht. Aber wieder ID 127.
Diese sollte vor der Aufnahme noch nicht vergeben werden. Das klingt nach einem Bug.


Jetzt Test für die Inclusion, ausgelöst durch Taster am Gateway.
Funktioniert, Device wird erstellt.
Ein Paar Warnungen im Log:
2014.10.21 22:09:03.714 1: PERL WARNING: Use of uninitialized value $fields[1] in join or string at FHEM/lib/Device/MySensors/Message.pm line 33.
2014.10.21 22:09:03.715 3: stacktrace:
2014.10.21 22:09:03.715 3:     main::__ANON__                      called by FHEM/lib/Device/MySensors/Message.pm (33)
2014.10.21 22:09:03.716 3:     Device::MySensors::Message::createMsg called by ./FHEM/00_MYSENSORS.pm (369)
2014.10.21 22:09:03.716 3:     MYSENSORS::sendMessage              called by ./FHEM/10_MYSENSORS_DEVICE.pm (302)
2014.10.21 22:09:03.717 3:     MYSENSORS::DEVICE::sendClientMessage called by ./FHEM/10_MYSENSORS_DEVICE.pm (263)
2014.10.21 22:09:03.718 3:     MYSENSORS::DEVICE::onInternalMessage called by ./FHEM/00_MYSENSORS.pm (315)
2014.10.21 22:09:03.723 3:     MYSENSORS::onInternalMsg            called by ./FHEM/00_MYSENSORS.pm (261)
2014.10.21 22:09:03.724 3:     MYSENSORS::Read                     called by fhem.pl (2923)
2014.10.21 22:09:03.724 3:     main::CallFn                        called by fhem.pl (598)
2014.10.21 22:09:03.725 1: PERL WARNING: Use of uninitialized value in sprintf at FHEM/lib/Device/MySensors/Message.pm line 40.
2014.10.21 22:09:03.725 3: stacktrace:
2014.10.21 22:09:03.726 3:     main::__ANON__                      called by FHEM/lib/Device/MySensors/Message.pm (40)
2014.10.21 22:09:03.726 3:     Device::MySensors::Message::dumpMsg called by ./FHEM/00_MYSENSORS.pm (370)
2014.10.21 22:09:03.727 3:     MYSENSORS::sendMessage              called by ./FHEM/10_MYSENSORS_DEVICE.pm (302)
2014.10.21 22:09:03.727 3:     MYSENSORS::DEVICE::sendClientMessage called by ./FHEM/10_MYSENSORS_DEVICE.pm (263)
2014.10.21 22:09:03.728 3:     MYSENSORS::DEVICE::onInternalMessage called by ./FHEM/00_MYSENSORS.pm (315)
2014.10.21 22:09:03.729 3:     MYSENSORS::onInternalMsg            called by ./FHEM/00_MYSENSORS.pm (261)
2014.10.21 22:09:03.729 3:     MYSENSORS::Read                     called by fhem.pl (2923)
2014.10.21 22:09:03.730 3:     main::CallFn                        called by fhem.pl (598)


mit dem gesetzten autocreate funktioniert genauso.


Schalten:
attr MYSENSOR_127 setCommands on:switch_1:on off:switch_1:off
funktioniert, Relay schaltet "falsch rum" (mein Relay-Modul schaltet bei low). Also umdrehen:
attr MYSENSOR_127 setCommands on:switch_1:off off:switch_1:on
Funktioniert richtig. Evtl. wäre sollte bei dieser Änderung, der Schaltbefehl entsprechend dem nuen Zustand gesendet werden? Oder doch besser nicht? Ich neige dazu, das eher nicht zu machen...

attr MYSENSOR_127 set_switch_1 on,off
wieder falsch rum, hier kann man aber wohl nichts 'umdrehen'?

attr MYSENSOR_127 set_LIGHT_1 0,1
erwartungsgemäß 'andersrum'. Auch hier wäre die Option zum 'Umdrehen' hilfreich.


Mein DHT11 Sensor-Node funktioniert auch weiterhin.
Anscheinend sendet der Sketch die Werte nur, wenn sie sich ändern, ansonsten kann ich die unregelmäßige und nicht gleichzitige AKtualisierungen von TEMP und HUM nicht erklären.

requestAck im DEVICE gesetzt: wenn ich die Relay-Node ausmache, on-Befehl sende und wieder die Node einschalte, dann bleibt sie nach der Initialisierung ausgeschaltet.

requestAck im Gateway gesetzt: jetzt bekommt Relay-Node nach dem Einschalten immer den gewünschten Zustand, egal wann geschaltet wurde: vor oder nach dem Auschalten. Mega cool ;)

(übrigens, hier ist es inkonsequent: Bei Device gilt yes/no, beim Gateway wird 1 erwartet.)

Dennoch ein Problem mit dieser Option. Danach wird der Log kontinuierlich zugemüllt:

2014.10.21 22:48:00.831 3: stacktrace:
2014.10.21 22:48:00.832 3:     main::__ANON__                      called by ./FHEM/10_MYSENSORS_DEVICE.pm (308)
2014.10.21 22:48:00.833 3:     MYSENSORS::DEVICE::mapReading       called by ./FHEM/10_MYSENSORS_DEVICE.pm (215)
2014.10.21 22:48:00.834 3:     MYSENSORS::DEVICE::onSetMessage     called by ./FHEM/00_MYSENSORS.pm (295)
2014.10.21 22:48:00.835 3:     MYSENSORS::onSetMsg                 called by ./FHEM/00_MYSENSORS.pm (253)
2014.10.21 22:48:00.836 3:     MYSENSORS::Read                     called by fhem.pl (2923)
2014.10.21 22:48:00.837 3:     main::CallFn                        called by fhem.pl (598)
2014.10.21 22:48:01.842 1: PERL WARNING: Use of uninitialized value $value in hash element at ./FHEM/10_MYSENSORS_DEVICE.pm line 309.
2014.10.21 22:48:01.843 3: stacktrace:
2014.10.21 22:48:01.844 3:     main::__ANON__                      called by ./FHEM/10_MYSENSORS_DEVICE.pm (308)
2014.10.21 22:48:01.846 3:     MYSENSORS::DEVICE::mapReading       called by ./FHEM/10_MYSENSORS_DEVICE.pm (215)
2014.10.21 22:48:01.847 3:     MYSENSORS::DEVICE::onSetMessage     called by ./FHEM/00_MYSENSORS.pm (295)
2014.10.21 22:48:01.847 3:     MYSENSORS::onSetMsg                 called by ./FHEM/00_MYSENSORS.pm (253)
2014.10.21 22:48:01.849 3:     MYSENSORS::Read                     called by fhem.pl (2923)
2014.10.21 22:48:01.849 3:     main::CallFn                        called by fhem.pl (598)


Auschalten von Relay-Node stoppt den Spuk. Löschen von requestAck im Gateway auch.
Liegt hier eine ACK-Schleife vor?
Nach dem wieder setzen setzt von requestAck setzt die Schleife erst wenn Hardware aus und wieder angemacht wird.


Kann ich noch etwas gezielt testen?
Bis dahin werde ich mir erstmal den Code anzuschauen.

Grüße,

Alexander
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

hexenmeister

Bis auf meine Anmerkungen funktioniert bei mir alles sehr stabil und vorhersagbar. Die Schaltbefehle kommen gefühlt verzögerungsfrei.
Sehr gute Arbeit!

Ich denke, ich werde nach und nach andere Gerätschaften von der MySensors-Seite nachbauen und ein oder anderes auch produktiv einsetzen.

Was ich jedoch noch überlege: Ich würde ggf. in meinem haus mehrere (min zwei) Gateways einsetzen müssen. Repeater-Nodes will ich eher vermeiden. Die Frage ist, ob das alles dann noch korrekt funktioniert. Ich vermute, es kann Probleme geben mit der Erkennung von doppelten (durch mehrere Gateways empfangenen) Messages. Eine Message-Nummer oder ID gibt es ja nicht.

Grüße,

Alexander
Maintainer: MQTT_GENERIC_BRIDGE, SYSMON, SMARTMON, systemd_watchdog, MQTT, MQTT_DEVICE, MQTT_BRIDGE
Contrib: dev_proxy

ntruchsess

2. Gateway sollte nicht nötig sein, die Sensoren können ja im Repeater-mode arbeiten. Dazu muss im Setup des Sketches der MySensor::begin-methode der optionale Parameter repeaterMode (Default false) mit true übergeben werden. So ein Repeater-sensor kann dann natürlich nicht sinnvoll mit Batterie laufen. Habe ich aber noch nicht getestet, ich hab erst mal nur 2 nRF24L01 gekauft, da hätte ich besser gleich richtig zulangen sollen.

Die Herrusforderung mit Repeatern ist aber das gleiche, weil deren Messages ja genauso vom Gateway empfangen werden.

Ansonsten könnte man aber auch mehrere Gateways auf unterschiedlichen Kanälen (siehe MyConfig.h) laufen lassen.
while (!asleep()) {sheep++};