platformübergreifende I2C Module

Begonnen von klausw, 05 Februar 2014, 14:01:47

Vorheriges Thema - Nächstes Thema

klausw

#90
Zitat von: ntruchsess am 29 März 2014, 23:46:41
das 'try' aus Error mach nix anderes als 'eval' (plus ein bischen schlaue Aufbereitung des Fehlers für das catch). Nimm einfach eval + I2C_BMP180_Catch, so wie es an anderen Stellen auch schon verwendet wird.
Ok baue ich so ein.

Zitat von: ntruchsess am 29 März 2014, 23:46:41
Wir sollten vereinbaren, dass die I2CWrtFn des IODevs grundsätzlich eine Exception (per 'die') werfen darf und alle Client-module diese mit 'eval' abfangen müssen (und das so im Fhemwiki dokumentieren).
Handhabe ich in meinen FRM-modulen genauso. Auf diese Weise ist es sehr einfach alle fatalen Fehlerzustände im IODev einheitlich zu behandeln.
Mir erschließt sich der Sinn noch nicht. Master Modul sollte doch alle fatalen Fehlerzustände abfangen. Wieso müssen wir das Ganze auch noch in die Clients weitertragen?
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

Zitat von: klausw am 29 März 2014, 23:57:10Wieso müssen wir das Ganze auch noch in die Clients weitertragen?

müssen müssen wir gar nix, das ist eine reine Design-entscheidung:

1) Entweder gibt eine Methode Fehlerzustände direkt per return-value zurück (das macht aber eigenentlich nur in rein prozeduralem Code Sinn, wenn die Methode Daten bearbeitet und eingentlich keinen richtigen Rückgabewert hat). Dann kann man so Dinge wie das hier schreiben: return $error if (my $error = doSomeThing(...));

2) Fehlerzustände werden in eine Return-structure mit eingepackt:

sub myMethod()
...
return {
  value => ...,
  status => "ok",
};
...
my $ret = myMethod(...);
return $ret->{status} unless ($ret->{status} eq "ok"));


3) Da der Fehlerzustand ja die Ausnahme ist bleiben die eigentlichen Daten frei von jedem Error-zustand, Fehler werden per Exception propagiert. Das trennt die eigentliche Logik sauber von der Fehlerbehandlung und hat zusätzlich noch den Vorteil, dass man Fehler in verschachtelt aufgerufenen Methoden nicht explizit behandeln und durchreichen muss, sondern diese ganz einfach per Exception ganz außen ankommen:

sub method_A() {
  ...
  dosomething...
  die "Fehler A" if (<errorcondition A>);
  return <richtiger Wert A>;
}

sub method_B() {
  ...
  dosomething...
  die "Fehler B" if (<errorcondition B>);
  return {
    val1 = <richtiger Wert B>,
    val2 = method_A(),
  };
  return;
  return;
}

...
eval {
  ...
  my $value = methodB(...);
  ....
};
if (@_) {
  log "es trat ein Fehler auf: ".@_; #das kann auch 'Fehler A' sein, method_B muss sich darum nicht weiter kümmern.
  return;
};
...


die Klammer mit 'eval{...}' sollte dabei eigentlich möglichst weit 'außen' liegen. D.h. in Fhem in den 'top-level'-methoden der Module (fhem.pl fängt nicht alles per eval ab, da ist weitestgehend o.g. Variante 1) implementiert).
Letztendlich kann man sich mit Variante 3) den ganzen fehlerbehandelnden Code auf den inneren Ebenen inklusive des Weiterreichens nach außen ganz einfach sparen.

Gruß,

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

klausw

Zitat von: ntruchsess am 31 März 2014, 16:04:03
müssen müssen wir gar nix, das ist eine reine Design-entscheidung:

schon klar, aber wollen wollen wir und zwar eine sinnvolle Lösung ;)

Wir können gern 3. machen.
Lösung 2 ist ja die Momentane, aber die hatte ich halt ohne großes NAchdenken übernommen.

Aber zum einen habe ich verstanden, das eval den Code zur Laufzeit compiliert. Wird dadurch nicht das System ausgebrems, wenn ich jede Unterroutine mit damit versehe?
Wie bekomme ich im Fall einer exception die Meldung an das Client Modul?
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

Lies die perldoc von eval, 4.Absatz. 'eval BLOCK' wird nur einmal compiliert.

Zitat von: klausw am 31 März 2014, 18:55:19Wie bekomme ich im Fall einer exception die Meldung an das Client Modul?

im einfachsten Fall indem man die Fehlermeldung direkt mit 'die "hier ist dieser Fehler passiert"' als Exception absetzt. Man kann auch typisierte Exceptions programmieren - siehe die, gegen Ende. Damit kann man dann zwischen unterschiedlichen Exception-typen anhand des Types selbst unterscheiden (z.B. I/0-exceptions vs. Numberformat-exceptions). Das Error-modul erlaubt das recht einfach zu nutzen, aber im Context von fhem braucht man das vermutlich nicht so dringend, da reicht es erst mal festzustellen 'hat nicht geklappt' und die Fehlermeldung in ein 'Error'-reading zu packen. Mit typisierten Exceptions könnte man natürlich richtig fatale Fehler mit einem Abstellen des Moduls quitieren und bei (mutmaßlich) temporären Fehlern einfach weitermachen...

Gruß,

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

klausw

Hallo Norbert,

dann lass es uns einfach so machen. Die Anzahl der Module ist im Moment ja noch überschaubar, was die Änderungsarbeit in Grenzen hält.
Typisiert muss denke ich nicht sein, da Fehler sie Ausnahme sein sollten.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

klausw

Hallo Norbert,

hastDu Dein LCD I2C schon testen können?
Ich habe noch ein C-Control I2C LCD Display daliegen. Das habe ich am Raspberry angeschlossen.
Es basiert auf dem PCF8574. Direkt über RPII2C kann ich Werte schreiben und diese auch zurücklesen. Sprich die Anbindung funktioniert.
Allerdings bekomm ich keinen Text auf das Display.
Mit Display On/Off kann ich manchmal die Hintergrundbeleuchtung toggeln und ein paar Sonderzeichen sind auch schon zu sehen. Aber leider nichts definiertes.

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

Zitat von: klausw am 01 April 2014, 00:20:52
hastDu Dein LCD I2C schon testen können?
...
Es basiert auf dem PCF8574.
ja, läuft bei mir (mir FRM). Wenn Deines nicht läuft, kann das aber auch an der Verbindung von PDC8574 und dem eigentlichen Displaycontroller liegen. (Also wenn die Pins anders gemappt sind, als bei meinem). Muss morgen mal das Pinout raussuchen, dann kann man vergleichen.

Gruß,

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

klausw

Zitat von: ntruchsess am 01 April 2014, 01:04:45
ja, läuft bei mir (mir FRM). Wenn Deines nicht läuft, kann das aber auch an der Verbindung von PDC8574 und dem eigentlichen Displaycontroller liegen. (Also wenn die Pins anders gemappt sind, als bei meinem). Muss morgen mal das Pinout raussuchen, dann kann man vergleichen.
Hoffentlich ist es das. Das RPII2C funktioniert ja eigentlich.
Lässt sich das Modul ummappen oder muss man ein weiteres erschaffen?

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

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

ntruchsess

#99
hier mal das Mapping der PCF8574T Pins und LCD bei meinem I2C-LCD-Display mit Adaper von Saintsmart (P0..P7 bezieht sich auf die logischen Portbits des PCF8574, nicht auf die physikalischen Pinsnummern)


LCD:       PCF8574T
1:  VSS
2:  VDD
3:  V0
4:  RS <-> P0
5:  RW <-> P1
6:  E  <-> P2
7:  D0
8:  D1
9:  D2
10: D3
11: D4 <-> P4
12: D5 <-> P5
13: D6 <-> P6
14: D7 <-> P7
15: LED Anode
16: LED Kathode


P3 steuert wohl die LED (Über einen Transistor)

Gruß,

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

klausw

Hallo Norbert,

bei meinem Display ist das Mapping anders:

LCD:       PCF8574T
1:  VSS
2:  VDD
3:  V0
4:  RS <-> P5
5:  RW <-> P4
6:  E  <-> P6
7:  D0
8:  D1
9:  D2
10: D3
11: D4 <-> P0
12: D5 <-> P1
13: D6 <-> P2
14: D7 <-> P3
15: LED Anode <-> P7 (über Transistor)


könntest Du das Mapping über die Attribute einstellbar machen?

Grüße
Klaus
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

mach mal einen Enduser-tauglichen Vorschlag wie das zugehörige Attribut zum Re-mappen syntaktisch aussehen soll, dann baue ich das ein.
while (!asleep()) {sheep++};

klausw

Zitat von: ntruchsess am 01 April 2014, 15:18:40
mach mal einen Enduser-tauglichen Vorschlag wie das zugehörige Attribut zum Re-mappen syntaktisch aussehen soll, dann baue ich das ein.

Touché! ;)

Am einfachsten wäre es sicherlich, die Portbits nacheinander mit Leerzeichen dazwischen zu nehmen. In der Commandref ist dazu die Reihenfolge der Pins am LCD beschrieben auf die referenziert wird:
RS | R/W | E | Bel. | D4 | D5 | D6 | D7

das Attribut wäre dann für Deinen Fall:
0 1 2 3 4 5 6 7
und für meinen:
5 4 6 7 0 1 2 3

über einzelne Attribute ist es meiner Meinung nach zu umständlich.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280

ntruchsess

danke, irgendwie startet die Phantasie bei mir manchmal erst, wenn ich einen Vorschlag sehe ;-)

vieleicht sollte man etwas expliziter sein:

RS=0,RW=1,E=2,LED=3,D4=4,D5=5,D6=6,D7=7


was meinst Du? Ich tu mich immer schwer so was zu bewerten, ich bin kein Enduser.
while (!asleep()) {sheep++};

klausw

wem sagst du das

es ist genauer, aber dann müsstest Du es als Default Attribut erzeugen.
Dann ist es meiner Meinung nach gut verständlich.
Die Fehlermöglichkeiten sind halt höher wenn man es komplett selbst schreiben muss.
RasPi B v2 mit FHEM 18B20 über 1Wire, LED PWM Treiber über I2C, Luchtdruck-, Feuchtesensor und ein paar Schalter/LED\'s zum testen
Module: RPI_GPIO, RPII2C, I2C_EEPROM, I2C_MCP23008, I2C_MCP23017, I2C_MCP342x, I2C_PCA9532, I2C_PCF8574, I2C_SHT21, I2C_BME280