Homematic Wired - Homebrew Devices

Begonnen von Thorsten Pferdekaemper, 27 April 2014, 00:13:17

Vorheriges Thema - Nächstes Thema

Thorsten Pferdekaemper

Hi,
kaum ist man mal ein paar Tage nicht da und schon geht hier die Post ab.
Ich werde mir das ganze auch noch genauer anschauen. Damit sind v.A. die Entwicklungen von Thomas "loetmeister" gemeint. ...oder soll ich warten bis Du soweit bist und dann ein komplettes Review machen? (sofern ich das dann noch kapiere)
Gruß,
   Thorsten
FUIP

jochen_f

Hallo,

erst einmal vielen Dank für das gute Tutorial und die vielen Informationen über das verwendete Protokoll.

Ich hatte hier noch ein paar alte Aktoren von Elektor mit einem Atmega88 rumliegen. Leider passte das in C++ bzw. mit Arduino entwickelte HBW dort nicht drauf. Daher habe ich mal geschaut, in wieweit eine optimierte C Implementierung funktionieren könnte.

Herausgekommen sind 3 Implementierungen, die jeweils auf das Elektor Testboard, das Relais Board und ein etwas aufgebohrtes Testboard passen. Sie benötigen ca. 5k Flash und passen damit bequem auf die Atmega88 Chips.

Implementiert sind Tasten, digitale Ein- und Ausgänge und auch Peerings.

Zu finden sind sie hier: https://git.colab.de/jochen/avr-hbw/

Eine Frage habe ich aber noch zu der XML Datei. Dort findet man manchmal einen Special Parameter "BEHAVIOUR", mit dem man scheinbar Alternativen bilden kann. Gibt es dazu genaueres? Ich würde die Port C Pins gerne alternativ als Analogeingänge nutzen, das sollte aber einstellbar sein. Geht das?

Gruß, Jochen

loetmeister

Zitat von: Thorsten Pferdekaemper am 01 April 2018, 21:34:46
Ich werde mir das ganze auch noch genauer anschauen. Damit sind v.A. die Entwicklungen von Thomas "loetmeister" gemeint. ...oder soll ich warten bis Du soweit bist und dann ein komplettes Review machen? (sofern ich das dann noch kapiere)

Hi Thorsten,

Ich passe noch XML und Code an das dynamischen Zeitformat an. Es wäre aber schon mal gut zu wissen ob die Änderungen an der lib ok sind.  ::)  8)
Man könnte in Zukunft eine switch simple und dazu passend link switch simple haben, mit dem bisherigen Funktionsumfang. Die erweiterten Funktionen als separate lib... Da weiß ich aber nicht wie das in der HBWired richtig einbindet um zwischen simple und advanced zu wechseln.

https://github.com/loetmeister/HBWired/commit/0dfb801c744f65bcdf50b9163986b35be134d6ee

Gruß,
Thomas

Thorsten Pferdekaemper

Hi,
Zitat von: jochen_f am 01 April 2018, 22:13:52
Ich hatte hier noch ein paar alte Aktoren von Elektor mit einem Atmega88 rumliegen...
ich würde Dir empfehlen, dazu einen neuen Thread aufzumachen. Sollte tatsächlich jemand daran interessiert sein, dann wird derjenige kaum in diesem großen Thread zufällig drauf stoßen. (Ich verstehe sowieso nicht, warum sich immer wieder in sowieso schon unübersichtliche Threads gehängt wird.)

Zitat
Eine Frage habe ich aber noch zu der XML Datei. Dort findet man manchmal einen Special Parameter "BEHAVIOUR", mit dem man scheinbar Alternativen bilden kann. Gibt es dazu genaueres? Ich würde die Port C Pins gerne alternativ als Analogeingänge nutzen, das sollte aber einstellbar sein. Geht das?
Auch das wäre einen eigenen Thread wert, oder nicht?
Genaueres gibt es dazu nicht wirklich. Ich habe da auch eine ganze Weile herumexperimentiert, bis das in FHEM geklappt hat. Schau Dir dazu am besten mal eins der Standard-XMLs an von Geräten, die sowas können. Ich glaube, beim 12/14er findet man dazu einiges.
Gruß,
    Thorsten
FUIP

Thorsten Pferdekaemper

Zitat von: loetmeister am 01 April 2018, 23:24:39Ich passe noch XML und Code an das dynamischen Zeitformat an. Es wäre aber schon mal gut zu wissen ob die Änderungen an der lib ok sind.  ::)  8)
Beim "dynamischen Zeitformat" habe ich gesehen, dass Du das mit vier Bytes anstatt der üblichen zwei machen willst. Das finde ich jetzt nicht so toll. Warum willst Du das erweitern?

Die Änderungen in der Lib sehen im Prinzip gut aus. Du hast ja nur überall den Parameter keyPressNum dazugenommen. Das kann zwar zu Inkompatibilitäten führen, aber die sind dann ziemlich einfach zu korrigieren.
Nur eine Kleinigkeit hätte ich gern anders. In HBWired.cpp hast Du es so gemacht:

receiveKeyEvent(senderAddress, frameData[1], frameData[2], frameData[3], frameData[3] & 0x01);

Ich hätte es lieber so:

receiveKeyEvent(senderAddress, frameData[1], frameData[2], frameData[3] >> 2, frameData[3] & 0x01);

Die untersten zwei Bits haben nämlich nichts mit der Tastendruck-Nummer zu tun. Für das, was Du vorhast, spielt das zwar keine Rolle, aber es ist trotzdem "richtiger", würde ich sagen.
Schickst Du mir dann einen Pull-Request dazu?

Zitat
Man könnte in Zukunft eine switch simple und dazu passend link switch simple haben, mit dem bisherigen Funktionsumfang. Die erweiterten Funktionen als separate lib... Da weiß ich aber nicht wie das in der HBWired richtig einbindet um zwischen simple und advanced zu wechseln.
Also das keyPressNum bauen wir einfach für alle ein. Das tut ja kaum weh. Ansonsten, also für die ganzen vielen Einstellungen für Peerings, hätte ich erwartet, dass es halt für die "advanced"-Dinger eigene Subklassen von HBWChannel bzw. HBWLinkReceiver gibt, die dann im Konstruktor von HBWDevice verwendet werden.
Wahrscheinlich müsste ein Großteil der Logik in der neuen Subklasse von HBWLinkReceiver sein, d.h. wir bräuchten wahrscheinlich noch eine loop-Methode in HBWLinkReceiver. Das könnten wir aber einfach einbauen.

Gruß,
    Thorsten
FUIP

loetmeister

Hi,

Zitat von: Thorsten Pferdekaemper am 02 April 2018, 22:31:14
Beim "dynamischen Zeitformat" habe ich gesehen, dass Du das mit vier Bytes anstatt der üblichen zwei machen willst. Das finde ich jetzt nicht so toll. Warum willst Du das erweitern?
Ja, es waren ursprünglich 2 Byte. Das kostet mir aber zu viel Platz im EEPROM, lieber mehr peerings, als Relais im Millisekunden Intervall schalten können  ::)

Bsp.: "HMW-LC-Sw2-DR" (16 bit)
<physical type="integer" size="2.0" interface="eeprom" endian="little">
[...]
<conversion type="float_configtime" factors="0.1,1,60,1000" value_size="1.6"/>


Ich habe es auf ein Byte und andere Multiplikatoren geändert. Damit sind immer noch 17,5 Stunden Zeiten möglich.
<logical type="float" min="0.0" max="63000.0" default="0.0" unit="s"/>
<physical type="integer" size="1.0" interface="eeprom" endian="little">
[...]
<conversion type="float_configtime" factors="1,60,1000,6000" value_size="0.8"/>

1 - 63 Sekunden (Sekundengenau)
60 - 3780  Sekunden (max. 63 Minuten, 60 Sekunden Schritte)
4000 - 63000 Sekunden (max. 17,5 Stunden, 1000 Sekunden Schritte ~16,6 Minuten)
... hoffe das stimmt. :)
Jedenfalls habe ich den Code und XML entsprechend angepasst. Testkaninchen ist HBW-LC-Sw-12.
(https://github.com/loetmeister/HBWired/tree/828c8a48382b0b32c61e4daf264e773bbccbb3ad/HBW-LC-Sw-12)

Zitat

receiveKeyEvent(senderAddress, frameData[1], frameData[2], frameData[3] >> 2, frameData[3] & 0x01);

Die untersten zwei Bits haben nämlich nichts mit der Tastendruck-Nummer zu tun. Für das, was Du vorhast, spielt das zwar keine Rolle, aber es ist trotzdem "richtiger", würde ich sagen.
Klingt gut, habe ich geändert.
Den bitshift hatte ich im link/set code... da hab ich es wieder raus genommen. Den Zusätzlichen Parameter hatte ich vorher "senderValue" genannt, aber dann auf keyPressNum geändert, da ja für den Event 0x4B/0xCB nur key events kommen sollten(?) :)

Pull-Request kommt..

Zitat
Also das keyPressNum bauen wir einfach für alle ein. Das tut ja kaum weh. Ansonsten, also für die ganzen vielen Einstellungen für Peerings, hätte ich erwartet, dass es halt für die "advanced"-Dinger eigene Subklassen von HBWChannel bzw. HBWLinkReceiver gibt, die dann im Konstruktor von HBWDevice verwendet werden.
Wahrscheinlich müsste ein Großteil der Logik in der neuen Subklasse von HBWLinkReceiver sein, d.h. wir bräuchten wahrscheinlich noch eine loop-Methode in HBWLinkReceiver. Das könnten wir aber einfach einbauen.
Schaue ich mir die Tage mal an. Im Moment ist der Code über HBWLinkSwitch (HBWLinkReceiver), HBWChanSw::set und HBWChanSw::loop verteilt...

Gruß,
Thomas

Thorsten Pferdekaemper

Hi,
das wird jetzt mal wieder alles relativ viel... D.h. es kann gut sein, dass ich da was übersehe.

Zitat von: loetmeister am 03 April 2018, 00:58:14
Ja, es waren ursprünglich 2 Byte. Das kostet mir aber zu viel Platz im EEPROM, lieber mehr peerings, als Relais im Millisekunden Intervall schalten können  ::)
Ach so. Ich dachte, Du wolltest das von 2 auf 4 erweitern. Das hätte ich etwas seltsam gefunden, so finde ich es nur etwas unschön. Hast Du mal ausgerechnet, wie viele Peerings Du mit den beiden Varianten hinbekommen würdest?

Zitat
aber dann auf keyPressNum geändert, da ja für den Event 0x4B/0xCB nur key events kommen sollten(?) :)
Ja, genau. Das ist nur für Key Events.

Zitat
Pull-Request kommt..
Ich dachte eigentlich, dass der Pull-Request nur für die keyPressNum Erweiterung ist. Das, was Du mir jetzt geschickt hast, ist für alle Änderungen. Das würde ich ungern einfach so übernehmen. Kannst Du das irgendwie splitten, so dass ich erst einmal nur die keyPressNum-Änderungen übernehmen kann?

Zitat
Schaue ich mir die Tage mal an. Im Moment ist der Code über HBWLinkSwitch (HBWLinkReceiver), HBWChanSw::set und HBWChanSw::loop verteilt...
Das habe ich jetzt auch gesehen, wobei da ein paar Sachen dabei sind, die mir noch nicht so gefallen bzw. zu dem ich noch Fragen/Kommentare habe.

NO_DEBUG_OUTPUT: Gab es da ein Problem oder warum willst Du das abschalten?

Momentan wird in HBWLinkSwitch nur das EEPROM ausgelesen, aber die "eigentliche Arbeit" ist beim Aktor selbst. Das finde ich nicht so geschickt. Meiner Meinung nach sollte die ganze Logik im LinkReceiver (also HBWLinkSwitch in dem Fall) sein. Insbesondere sollte die set-Methode nicht so missbraucht werden. Es sollten nur die Daten übergeben werden, die tatsächlich für ein "set" gebraucht werden.

TOGGLE_TO_COUNTER (und ähnliche): Was ist denn das? Wo gibt es das ansonsten bei HMW? Die Implementierung sieht so aus, als ob man damit erreichen will, dass auch bei "vergessenen" Tastendrücken richtig getoggelt wird. Ich denke, dass das bei Peerings mit mehreren Tastern seltsame Effekte geben kann, genauso bei gemischten kurzen und langen Tastendrücken, die unterschiedliche Sachen machen sollen. (Die Zählung ist für kurze und lange gemeinsam.)

Funktioniert das hier wirklich?

device->readEEPROM(&data, eepromStart + EEPROM_SIZE * i + 6, 7);     

(Aus HBWLinkSwitch::receiveKeyEvent)
Die Variable data ist ja schon ein Zeiger (Arrays und Zeiger sind fast dasselbe). D.h. mir ist nicht so ganz klar, wo &data tatsächlich hinzeigt. Vielleicht hier sicherheitshalber pdata verwenden (natürlich nicht &pdata).
   
Gruß,
   Thorsten   
FUIP

loetmeister

Hi Thorsten,

Zitat von: Thorsten Pferdekaemper am 04 April 2018, 23:06:31
Ach so. Ich dachte, Du wolltest das von 2 auf 4 erweitern. Das hätte ich etwas seltsam gefunden, so finde ich es nur etwas unschön. Hast Du mal ausgerechnet, wie viele Peerings Du mit den beiden Varianten hinbekommen würdest?
Wenn ich die ersten 32 byte im EEPROM reserviere, habe ich bei 12 Kanälen ein zusätzliches peering pro Kanal "gewonnen".
address_step="20" address_start="0x20" --> 49 (4 peerings pro Kanal - 12 Kanäle im Device)
Bei der Original Zeit Konfiguration sind es 8 byte mehr, also step 28 --> 35 peerings

ZitatIch dachte eigentlich, dass der Pull-Request nur für die keyPressNum Erweiterung ist. Das, was Du mir jetzt geschickt hast, ist für alle Änderungen. Das würde ich ungern einfach so übernehmen. Kannst Du das irgendwie splitten, so dass ich erst einmal nur die keyPressNum-Änderungen übernehmen kann?
Hm... ich müsste wohl einen eigenen Branch anlegen... und nur noch pull requests für den "sauberen" master stellen :)
Bisher habe ich ja nur HBW-LC-Sw-12 "verbastelt und dort eine Kopie der LinkSwitch lib abgelegt....

ZitatNO_DEBUG_OUTPUT: Gab es da ein Problem oder warum willst Du das abschalten?
Nein, kein Problem. Wollte es nur per direktive abschaltbar machen - für die "produktiven" Geräte. Weniger im loop()  ;)

Zitat
Momentan wird in HBWLinkSwitch nur das EEPROM ausgelesen, aber die "eigentliche Arbeit" ist beim Aktor selbst. Das finde ich nicht so geschickt. Meiner Meinung nach sollte die ganze Logik im LinkReceiver (also HBWLinkSwitch in dem Fall) sein. Insbesondere sollte die set-Methode nicht so missbraucht werden. Es sollten nur die Daten übergeben werden, die tatsächlich für ein "set" gebraucht werden.
Ich versuche das mal etwas besser aufzuteilen...
Wäre es möglich/sinvoll alles in HBWLinkSwitch zu packen? Die meisten Vorgänge beziehen sich ja auf einen bestimmten Kanal. (Alle timer, Status, etc.)
Das eigentlich set() ist in setOutput() gewandert. Ich schaue das ich set() wieder ins original versetzte, dann brauche ich aber eine neue Funktion im HBWSwitch, die ich in HBWLinkSwitch aufrufen kann, statt set().

Zitat
TOGGLE_TO_COUNTER (und ähnliche): Was ist denn das? Wo gibt es das ansonsten bei HMW? Die Implementierung sieht so aus, als ob man damit erreichen will, dass auch bei "vergessenen" Tastendrücken richtig getoggelt wird. Ich denke, dass das bei Peerings mit mehreren Tastern seltsame Effekte geben kann, genauso bei gemischten kurzen und langen Tastendrücken, die unterschiedliche Sachen machen sollen. (Die Zählung ist für kurze und lange gemeinsam.)
Das gibts im original Dimmer. Bei ungeraden Tastendruckzähler wird Eingeschaltet, bei geraden Aus. Damit kann man bei einem mehrfach peering für eine Taste (z.B. nur kurzer Tastendruck) alle Ausgänge gleich schalten. (spätestens nach der zweiten Betätigung ist es wieder synchron)
Das"normale" toggle ist ja noch da... :)

ZitatFunktioniert das hier wirklich?

device->readEEPROM(&data, eepromStart + EEPROM_SIZE * i + 6, 7);     

(Aus HBWLinkSwitch::receiveKeyEvent)
Die Variable data ist ja schon ein Zeiger (Arrays und Zeiger sind fast dasselbe). D.h. mir ist nicht so ganz klar, wo &data tatsächlich hinzeigt. Vielleicht hier sicherheitshalber pdata verwenden (natürlich nicht &pdata).
Hat funktioniert... sollte eigentlich beides auf die Adresse/Anfang des Arrays data[] zeigen. Jedenfalls bekomme ich die Werte aus dem EEPROM. :)
Ich kann auch *pdata wieder raus nehmen. Brauche ich gar nicht mehr....
        device->readEEPROM(&data, eepromStart + EEPROM_SIZE * i + 13, 7);     // read all parameters (must be consecutive)
        device->set(targetChannel,NUM_PEER_PARAMS,data);


Gruß,
Thomas

Thorsten Pferdekaemper

Zitat von: loetmeister am 05 April 2018, 00:37:40
Wenn ich die ersten 32 byte im EEPROM reserviere, habe ich bei 12 Kanälen ein zusätzliches peering pro Kanal "gewonnen".
address_step="20" address_start="0x20" --> 49 (4 peerings pro Kanal - 12 Kanäle im Device)
Bei der Original Zeit Konfiguration sind es 8 byte mehr, also step 28 --> 35 peerings
Ich glaube zwar nicht, dass Du jemals auch nur die 35 ausnutzen wirst, aber ich kann mich auch irren. Bei mir daheim habe ich meistens die Original 12/7er eingebaut und im Durchschnitt wahrscheinlich so ungefähr 1,5 Peerings pro Switch.
Ich fände es halt schöner, wenn wir erst einmal eine Art Standard-Peering zusammengebastelt bekommen, aber diese Stelle kann man später leicht noch ändern oder eben zwei Versionen machen.

Zitat
Hm... ich müsste wohl einen eigenen Branch anlegen... und nur noch pull requests für den "sauberen" master stellen :)
Bisher habe ich ja nur HBW-LC-Sw-12 "verbastelt und dort eine Kopie der LinkSwitch lib abgelegt....
Wenn das so richtig Aufwand wird, dann lass es mal. So wichtig ist es ja nicht, dass wir das sofort reinbringen. Den Aufwand sollten wir dann lieber in eine vollständige und gute Lösung stecken.

Zitat
Nein, kein Problem. Wollte es nur per direktive abschaltbar machen - für die "produktiven" Geräte. Weniger im loop()  ;)
Ok. Es wäre schön, wenn wir zwei serielle Schnittstellen in der Hardware hätten, aber dann müsste man sich wieder was eigenes basteln oder etwas größeres nehmen. Möglicherweise ist es "abschaltbar" gar nicht so schlecht.

Zitat
Ich versuche das mal etwas besser aufzuteilen...
Wäre es möglich/sinvoll alles in HBWLinkSwitch zu packen? Die meisten Vorgänge beziehen sich ja auf einen bestimmten Kanal. (Alle timer, Status, etc.)
Ich glaube trotzdem, dass das alles im HBWLinkSwitch abgehandelt werden sollte. Die ganzen Einstellungen beziehen sich auf die Verknüpfung. Außerdem sollten im Kanal eher die Hardware-Spezifika gekapselt sein. D.h. es wäre schön, wenn wir eine "Link"-Klasse hätten, die man dann mit verschiedenen "Switch"-Klassen verwenden kann. Bei Deinem Gerät scheint ja schon die Hardware etwas besonders zu sein.

Zitat
Das eigentlich set() ist in setOutput() gewandert. Ich schaue das ich set() wieder ins original versetzte, dann brauche ich aber eine neue Funktion im HBWSwitch, die ich in HBWLinkSwitch aufrufen kann, statt set().
Siehe oben. Ich glaube, dass man das hinbekommen kann, ohne irgend etwas an der Switch-Klasse zu ändern. Das einzige, was man meiner Meinung nach hinzufügen müsste, ist eine loop-Methode in der Link-Klasse, die dann automatisch regelmäßig aufgerufen wird.

Zitat
Das gibts im original Dimmer. Bei ungeraden Tastendruckzähler wird Eingeschaltet, bei geraden Aus. Damit kann man bei einem mehrfach peering für eine Taste (z.B. nur kurzer Tastendruck) alle Ausgänge gleich schalten. (spätestens nach der zweiten Betätigung ist es wieder synchron)
Das"normale" toggle ist ja noch da... :)
Ah, jetzt ja. Ich hab's jetzt auch gefunden. Das klingt tatsächlich sinnvoll und ich könnte das bei mir sogar anwenden. Die 12/7er haben das leider nicht, wie es aussieht.

Zitat
Hat funktioniert... sollte eigentlich beides auf die Adresse/Anfang des Arrays data[] zeigen. Jedenfalls bekomme ich die Werte aus dem EEPROM. :)
Ich habe mir gerade nochmal die C++-Feinheiten dazu betrachtet. Tatsächlich ist es wohl in dem Fall egal, ob man "&data" oder einfach nur "data" verwendet, da wir sowieso auf void* casten. Ich habe nur noch nie gesehen, dass jemand das mit "&data" macht.

Gruß,
   Thorsten
FUIP

loetmeister

#474
Hi,

Zitat von: Thorsten Pferdekaemper am 05 April 2018, 14:38:28
Ich glaube trotzdem, dass das alles im HBWLinkSwitch abgehandelt werden sollte. Die ganzen Einstellungen beziehen sich auf die Verknüpfung. Außerdem sollten im Kanal eher die Hardware-Spezifika gekapselt sein. D.h. es wäre schön, wenn wir eine "Link"-Klasse hätten, die man dann mit verschiedenen "Switch"-Klassen verwenden kann.
[...]
dass man das hinbekommen kann, ohne irgend etwas an der Switch-Klasse zu ändern. Das einzige, was man meiner Meinung nach hinzufügen müsste, ist eine loop-Methode in der Link-Klasse, die dann automatisch regelmäßig aufgerufen wird.
Möglich ist das bestimmt... ob ich das auf die Reihe bekomme eine andere Frage  ::)

Angenommen ich nehme meinen neuen Code aus dem set() und loop() der Switch Klasse raus, da würde ich folgende Unterteilung vornehmen.
In der Klasse von HBWLinkSwitch (HBWLinkReceiver) müsste ich Arrays für alle Variablen anlegen welche ich später im loop() brauche. Den HBWLinkReceiver loop dann genau wie den channels loop() im device loop aufrufen?

HBWLinkReceiver receiveKeyEvent()
// read EEPROM (wie bisher auch), direkte Aktionen prüfen, die direkt ausgeführt werden können -> channel set(), z.B.:
// SHORT_ACTION_TYPE, ACTIVE
// TOGGLE_USE
// store values from peering/EEPROM for state machine (um sie im loop() zu nutzen)
// jumpTargets[NUM_CHANNELS], on/offTime[NUM_CHANNELS], on/offDelayTime[NUM_CHANNELS], usw.

HBWLinkReceiver loop()
// state machine
// check timer, set new timer, set new state
// lastStateChangeTime[targetChannel]; / stateCangeWaitTime[targetChannel];

void HBWDevice::loop()
   for(uint8_t i = 0; i < numChannels; i++) {
        channels[i]->loop(this,i);
       HBWLinkReceiver->loop(i); // <--- neu
}


Geht das in die Richtig, die du angedacht hast? Was mich noch ein wenig verunsichert, die Aussage: "Die ganzen Einstellungen beziehen sich auf die Verknüpfung"
Die Einstellungen / Werte kommen von der Verknüpfung, beziehen sich aber auf den Verknüpften Kanal. Ich muss ja weiter die nächsten Aktionen ausführen können. (z.B. nach einem on delay in die jumpTargets schauen und z.B. zur on Time springen, o.ä.).

Gruß,
Thomas

Thorsten Pferdekaemper

Hi,
ich habe jetzt nochmal ein bisschen darüber nachgedacht. Es ist wohl tatsächlich etwas ungeschickt, alles in der HBWLinkReceiver-Subklasse abzuarbeiten. Das Ding weiß schonmal gar nicht, wie viele Kanäle es eigentlich gibt und das ganze dynamisch zu machen ist auf so kleiner Hardware nicht wirklich gut.
Also müsste man die "state machine" im Kanal selbst (HBWSwitch) implementieren, während HBWLinkSwitch sozusagen nur die Liste abklappert und das EEPROM liest. Natürlich muss HBWLinkSwitch dann auch die Daten irgendwie an den Kanal weitergeben. Das sollte dann aber meiner Meinung nach mit einer neuen Methode passieren und nicht mit set(). Wie wär's mit triggerEvent()?
Gruß,
   Thorsten
FUIP

loetmeister

Hi,

Zitat von: Thorsten Pferdekaemper am 07 April 2018, 22:52:28
Also müsste man die "state machine" im Kanal selbst (HBWSwitch) implementieren, während HBWLinkSwitch sozusagen nur die Liste abklappert und das EEPROM liest. Natürlich muss HBWLinkSwitch dann auch die Daten irgendwie an den Kanal weitergeben. Das sollte dann aber meiner Meinung nach mit einer neuen Methode passieren und nicht mit set(). Wie wär's mit triggerEvent()?

Klingt gut.. habe mal peeringEventTrigger() als namen genommen. Bisher ist es sehr nah an der original set() Funktion, auch was den Aufruf über das Device angeht. Könnte man das eleganter/einfacher lösen?

Der Aufbau ist wie folgt. ("set()" ist wieder Standard, d.h. nur Ausgänge und logging setzen)

In HBWLinkSwitch::receiveKeyEvent wird peeringEventTrigger() aufgerufen:
device->peeringEventTrigger(targetChannel,data);    // channel, data

Dann über HBWired:
void HBWDevice::peeringEventTrigger(uint8_t channel, uint8_t const * const data){
// to avoid crashes, do not try to set any channels, which do not exist
if(channel < numChannels)
        channels[channel]->peeringEventTrigger(this, data);
}


Um dann in HBWChannelSw::peeringEventTrigger oder loop() den Ausgang mit "set()" zu setzten:
this->set(device,1,&level);

Die weitere Methode hat 6 Byte RAM und 112 Byte Programmspeicher gekostet...  ???


Gruß,
Thomas

Thorsten Pferdekaemper

Zitat von: loetmeister am 12 April 2018, 00:18:27
Klingt gut.. habe mal peeringEventTrigger() als namen genommen. Bisher ist es sehr nah an der original set() Funktion, auch was den Aufruf über das Device angeht. Könnte man das eleganter/einfacher lösen?
Im Prinzip finde ich das elegant. Man hat eine Indirektion über HBWDevice, so dass die Link-Klasse gar nicht wissen muss, was da für Channels dranhängen. Außerdem erlaubt man HBWDevice, die Channels so zu verwalten, wie es gerade passt. Wenn die Link-Klasse direkt auf die Channels-Liste zugreifen würde könnte man das nicht mehr so machen. Unschön ist natürlich, dass es viel Programmspeicher etc. kostet.

Zitat
Die weitere Methode hat 6 Byte RAM und 112 Byte Programmspeicher gekostet...  ???
Mmm... Also was im Prinzip immer gemacht werden muss ist die Prüfung, ob der Kanal überhaupt existiert (es ist relativ einfach, ein kaputtes Peering anzulegen, was ansonsten das Device lahmlegen könnte). Aber wir können uns vielleicht sparen, die Methode "virtual" zu machen. Dann könnte man es noch mit "inline" versuchen. Also statt...

virtual void peeringEventTrigger(HBWDevice*, uint8_t const * const data);

...das Ding mal so deklarieren:

inline void peeringEventTrigger(HBWDevice*, uint8_t const * const data);

Da die Methode nur an einer Stelle aufgerufen wird dürfte das zumindest nicht mehr Programmspeicher brauchen.
Gruß,
   Thorsten
FUIP

loetmeister

Hi,

Zitat von: Thorsten Pferdekaemper am 13 April 2018, 14:26:03
...das Ding mal so deklarieren:

inline void peeringEventTrigger(HBWDevice*, uint8_t const * const data);

Da die Methode nur an einer Stelle aufgerufen wird dürfte das zumindest nicht mehr Programmspeicher brauchen.

Danke. Habe mal "wild" rumprobiert. In class HBWChannel kann ich es nicht auf "inline" ändern. Dann spar ich zwar 88 Byte aber es läuft nicht mehr. :o  ;D
In class HBWDevice kann ich es ändern, spart 26 Byte.

Ich schau mal das ich was aufräume und es als library HBWSwitchAdvanced und HBWLinkSwitchAdvanced verpacke...

Gruß,
Thomas

Thorsten Pferdekaemper

Zitat von: loetmeister am 14 April 2018, 01:31:03Danke. Habe mal "wild" rumprobiert. In class HBWChannel kann ich es nicht auf "inline" ändern. Dann spar ich zwar 88 Byte aber es läuft nicht mehr. :o  ;D
Nein, da geht das natürlich nicht. Dort brauchst Du ja den Vererbungsmechanismus.
Gruß,
   Thorsten
FUIP