FRM_IN: state wird jetzt sofort nach define/connect/restart etc. gesetzt

Begonnen von ntruchsess, 22 November 2013, 18:20:34

Vorheriges Thema - Nächstes Thema

ntruchsess

#15
Zitat von: Achim am 06 Dezember 2013, 08:14:17Das Problem tritt dann auf, wenn man mit FHEM den internen Pullup Widerstand einschaltet. Ich vermute das beim Reconnect das Setzen des internen Pullups den vorhandenen Zustand 0 "überschreibt" und daher keine Leveländerung von Firmata gesendet wird.

Dieser Fehler ist jetzt behoben. Lag daran, dass die perl-firmata den State der Pins intern speichert und den Callback im FRM_IN nur aufgerufen hat, wenn sich der Zustand (aus Sicht der perl-firmata) beim Empfangen einer Digital-message auch geändert hat.

Fix ist ins fhem-SVN committed.

Wenn man den FRM_IN-internen counter verwendet, können mit internem pullup aber weiterhin noch Pulse beim Initialisieren gezählt werden (da macht der Pin ja tatsächlich einen Statusübergang), dafür mache ich einen separaten Patch.

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

fhainz

Hallo!

Ich nutze eine Arduino Mega um Impulse eines Stromzählers zu zählen. Mir ist auch schon aufgefallen das hochgezählt wird wenn fhem neu startet.
Hab gerade ein Update gemacht und das mal ausprobiert. Das reading "reading" ist im normal fall on und wenn ein Impuls vom Stromzähler kommt, kurz off.
Leider wird bei mir durch den neustart immer noch reading auf off gesetzt und dann wieder on. activeLow hab ich testweise mal auf on mal auf off gehabt. Hat leider nichts bewirkt.
Hab ich vielleicht noch etwas falsch definiert?

Internals:
   CFGFN      ./FHEM/arduino.cfg
   DEF        46
   IODev      FIRMATA
   NAME       arduino_pin_46
   NR         67
   PIN        46
   STATE      1393518630.63931
   TYPE       FRM_IN
   Readings:
     2014-02-27 17:30:30   lastPower       175
     2014-02-27 17:30:30   power           0.87
     2014-02-27 17:30:30   power_avg_day   673.0
     2014-02-27 17:30:30   power_avg_month 136.0
     2014-02-27 17:30:30   power_cum_day   42417816.07
     2014-02-27 17:30:30   power_cum_month 325718641.129995
     2014-02-27 00:17:26   power_max_day   1993.1
     2014-02-23 13:43:53   power_max_month 1999.9
     2014-02-27 17:30:09   power_min_day   0.1
     2014-02-25 12:32:09   power_min_month 0.1
     2014-02-27 17:31:40   reading         on
     2014-02-27 17:30:30   state           Initialized
     2014-02-27 17:30:30   time            1393518630.63931
Attributes:
   alias      Stromzähler Boiler
   internal-pullup on
   room       Arduino
   stateFormat time
   userReadings time:reading:.off { use Time::HiRes qw(time); time(); }, power:reading:.off { ReadingsVal("d_stromverbrauchBoiler","state",0); }


Grüße

ntruchsess

Zitat von: fhainz am 27 Februar 2014, 17:42:56Hab ich vielleicht noch etwas falsch definiert?

nein, denn:

Zitat von: ntruchsess am 26 Februar 2014, 18:30:06Wenn man den FRM_IN-internen counter verwendet, können mit internem pullup aber weiterhin noch Pulse beim Initialisieren gezählt werden (da macht der Pin ja tatsächlich einen Statusübergang), dafür mache ich einen separaten Patch.

ich muss halt noch was einbauen, was den counter erst aktiviert, nachdem der Statusübergang vom Aktivieren des internen-pullups stattgefunden hat.

Gruß,

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

fhainz

Du meinst du internen counter das Attribut count-mode oder?
Das nutzt ich nicht. Ich zähle die statusänderungen mittels notify, einer Funktionen in der 99_myUtils.pm und hourCounter.

arduino_pin_46:reading:.off { stromverbrauchBerechnen("arduino_pin_46","d_stromverbrauchBoiler",2000,80); }

sub stromverbrauchBerechnen($$$$) {
 
  my $readingDevice = shift;   #Trigger
  my $writingDevice = shift;   #Device in dem das state geschrieben wird
 
  my $maxPower = shift;   #Maximale Leistung in W. Größere Werte werden ignoriert 
  my $allowedDeltaPower = shift;   #Maximaler Leistungsunterschied in W. Erst nach dem 2. größeren reading wird geschrieben um Peaks zu verhindern.
 
  my $power = 3600 / ( time() - OldValue($readingDevice) );
  my $lastPower = ReadingsVal($readingDevice,"power",0);
  my $readingLastPower = ReadingsVal($readingDevice,"lastPower",0);
 
  $power = int(100 * $power + 0.5) / 100;
 
  if( $power > ( $lastPower + $allowedDeltaPower ) && $power < $maxPower ){
    if( $readingLastPower eq "0" ){
      setReading($readingDevice,"lastPower",$power);
    }
    else{
      setReading($writingDevice,"state",$power);
      setReading($readingDevice,"lastPower",0);
    }
  }
  elsif( $power > $maxPower  || $power < 0 )
  {
  }
  else{
    setReading($writingDevice,"state",$power);
    if( $readingLastPower > 0 ) {
      setReading($readingDevice,"lastPower",0);
    } 
  }
}


Grüße

ntruchsess

Zitat von: fhainz am 27 Februar 2014, 18:37:27Du meinst du internen counter das Attribut count-mode oder?

Ja, aber im Prinzip ist es das gleiche Problem, der FRM_IN-interne counter zählt praktisch genauso. Der Firmata-default für einen input-pin ist ohne Pullup, wenn man den Pullup-aktiviert, gibt es mindestens einen Statusübergang von off nach on (oder auch mehrere, weil der Pin ja vor aktivieren des internen Pullups oftmals 'in der leeren Luft' hängt).

Aber gut dass Du darauf hinweist, ich baue das dann mal so, dass das der default-wert von 'reading' bei gesetztem internal-pullup 'on' ist, damit es keinen Statusübergang gibt.

Gruß,

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

fhainz

Alles klar verstehe das Problem schon!
Danke das du noch einbaust!

Grüße