TC emulieren

Begonnen von wkarl, 02 Januar 2014, 10:39:55

Vorheriges Thema - Nächstes Thema

martinp876

ja - aber ich muss noch ein paar details einfuegen bei param allgemein

JohanK

Hallo,
Habe diese Konversation nicht ganz begriffen :-) aber trotzdem sehr erfreut mit dem Resultat !

Aber Ich verstehe das bei nicht zurück schicken von einem Ack in der Praxis, bei realen Devices, zu folge hat das der HMLAN noch 2 mal versucht um den Empfänger zu erreichen. Man sieht dass nur wenn Mann den Funkverkehr mitlogged auf einen zweiten HMLAN...Also das generiert extra Funktraffic in dem fall. Weiß nicht ob das in diese Konfiguration auch so sein wird.

freundliche Grüße, und viel dank für diese neue und viel gewünschte Funktionalität !!

Johan

martinp876

Zitat...zu folge hat das der HMLAN noch 2 mal versucht um den Empfänger zu erreichen. Man sieht dass nur wenn Mann den Funkverkehr mitlogged...
exact. das zu steuern fehlt mir das Wissen zum HMLAN - also ist es unvermeidlich

Wiederholt wird von jedem Device, wenn ein gefordertes ACK nicht gekommen ist. Die Anzahl der Wiederholungen ist i.A. 2, kann aber abweichen. In manchen Faellen ist es 0 (nur einmal senden). Unterschiede liegen in den Devices un dggf in deren Einstellungen

HMLAN steht immer auf 2 (1 mal senden, 2 mal wieder holen).

Gruss Martin

frank

hallo ihr beiden,

meine derzeitigen versuche bestätigen diese tatsache.

nach meinem fhem.log unterdrücke ich zur zeit erfolgreich 4 von 5 antworten der virtuellen vd, indem ich die vvd für 4 zyklen in den dummy-zustand versetze. das sollte eine reduzierung von 80% bedeuten.

aber sowohl msgLoadEst vom hmlan, sowie msgStat von hminfo geben in diesem fall nicht die erwartete reduzierung wieder. es gibt keinen linearen zusammenhang. eine reduzierung der werte hat aber trotzdem stattgefunden. bei msgLoadEst hätte ich rechnerisch eine reduzierung im mittel von 9% erwartet, aber nur ca. 5% sind erfolgt. bei msgStat wird sogar noch weniger reduziert. erwartet hätte ich 80msg pro std weniger, aber nur 20msg weniger sind zu beobachten.

aber schon interessant, das msgLoadEst und msgStat die heimlichen antworten mitbekommen, wenngleich sie sie auch unterschiedlich bewerten. wahrscheinlich hat dann auch die länge der antworten einfluss auf auf die 1%-regel, weil der hmlan vermutlich nur mit "0x00" antwortet.
das attribut msgRepeat hat wohl keinen einfluss darauf, denn das habe ich auf 0 gestellt.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

Hi Frank

Zitataber schon interessant, das msgLoadEst und msgStat die heimlichen antworten mitbekommen
nun, ich habe mich bemüht - das waren einige Experimente.
Ja, die Berechnung ist leicht unterscheidlich, sie Aussage auch
Zitatwahrscheinlich hat dann auch die länge der antworten einfluss
nein
Zitatdas attribut msgRepeat hat wohl keinen einfluss darauf, denn das habe ich auf 0 gestellt.
auf die Wiederholungen des HMLAN? Nein, die kann ich nicht beeinflussen (eq3 evtl schon... aber da fehlt die Registerbeschreibung den HMLAN selbst. )

Gruss Martin

frank

hallo martin,

hattest du eventuell wegen der attr param umstellung schon etwas unternommen? in v4901 war mir im angesprochenen bereich nichts neues aufgefallen.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

Hallo Frank,
msgred sollte jetzt funktionieren - gesetzt wird es jedenfalls bei mir.
Machst du es gerade skalierbar? Also jede 2./3./4. message unterdrücken? Gib gescheid, wenn dem so ist
Gruss Martin

ps - sehe gerade deine Antwort - eigentlich sollte es eingecheckt sein.
Also attr param msgReduce setzt den Helper korrekt.
Die Verarbeitung habe ich nicht getestet - mache ich jetzt mal
Gruss Martin

frank

hallo martin,

ZitatMachst du es gerade skalierbar? Also jede 2./3./4. message unterdrücken?
bevor ich daran gehe, wollte ich erst einmal versuchen, die beiden funktionen derart um zu bauen, dass man im falle einer unterdrückung die internalTimer gleich auf den "gewünschten" zeitpunkt stellt. dann hätte man nicht so viele "sinnlose" kurze timer am laufen. gibt vielleicht mehr performance? oder was meinst du?

dann muss ich jetzt wohl zum svn!  :)

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

frank

#128
hallo martin,

msgReduce klappt immer noch nicht.  :(

mit 6 log einträgen andiesen stellen:

    elsif ($md =~ m/^virtual_/){
      Log 1,"##### init1 ##### cmd:$cmd, model:$md, attrVal:$attrVal, msgRdc:$hash->{helper}{vd}{msgRed}";
      if ($cmd eq "set"){
        if ($attrVal eq "noOnOff"){# no action    
        }
        elsif ($attrVal eq "msgReduce"){#set param
          $hash->{helper}{vd}{msgRed}=1;
        }
        else{
          return "attribut param not defined for this entity";
        }
      }
      else{
        delete $hash->{helper}{vd}{msgRed};
      }
       Log 1,"##### init2 ##### cmd:$cmd, model:$md, attrVal:$attrVal, msgRdc:$hash->{helper}{vd}{msgRed}";
    }
#######################################################
sub CUL_HM_valvePosUpdt(@) {#update valve position periodically to please valve
  my($in ) = @_;
  my(undef,$vId) = split(':',$in);
  my $hash = CUL_HM_id2Hash($vId);
  my $name = $hash->{NAME};
  my $msgCnt = $hash->{helper}{vd}{msgCnt};
  my ($idl,$lo,$hi,$nextTimer);
  my $tn = gettimeofday();
  $hash->{helper}{vd}{next} = ReadingsVal($name,".next",$tn)
        if (!defined $hash->{helper}{vd}{next});
  $hash->{helper}{vd}{nextF} = $hash->{helper}{vd}{next};
# int32_t result = (((_address << 8) | messageCounter) * 1103515245 + 12345) >> 16;
#                          4e6d = 20077                        12996205 = C64E6D
# return (result & 0xFF) + 480;

  if ($tn > ($hash->{helper}{vd}{nextF} + 3000)){# mised 20 periods;
    Log3 $name,3,"CUL_HM $name virtualTC timer off by:".int($tn - $hash->{helper}{vd}{nextF});
    $hash->{helper}{vd}{nextF} = $tn;
  }
  do {
    $msgCnt = ($msgCnt +1) %256;
    $idl = $hash->{helper}{vd}{idl}+$msgCnt;
    $lo = int(($idl*0x4e6d +12345)/0x10000)&0xff;
    $hi = ($hash->{helper}{vd}{idh}+$idl*198)&0xff;
    $nextTimer = (($lo+$hi)&0xff)/4 + 120;
    $hash->{helper}{vd}{nextF} += $nextTimer;
  } until ($hash->{helper}{vd}{nextF} > $tn);

  $hash->{helper}{vd}{nextM} = $tn+$nextTimer;
  $hash->{helper}{vd}{msgCnt} = $msgCnt;
  if ($hash->{helper}{vd}{cmd}){
    if    ($hash->{helper}{vd}{typ} == 1){
      my $vc = ReadingsVal($name,"valveCtrl","init");
      if(!defined $hash->{helper}{vd}{msgRed}){
        $hash->{helper}{vd}{msgRed} = 0;
      }
Log 1,"##### updt1:$name, vCtrl:$vc, msgRdc:$hash->{helper}{vd}{msgRed} #####";

      if (!(($vc eq "init") ||
            ($vc eq "ok") && $hash->{helper}{vd}{msgRed})) {#if ready,idle,miss,lost
Log 1,"##### updt2:$name, vCtrl:$vc, msgRdc:$hash->{helper}{vd}{msgRed} #####";
      CUL_HM_PushCmdStack($hash,sprintf("%02X%s%s%s"
                                           ,$msgCnt
                                           ,$hash->{helper}{vd}{cmd}
                                           ,$hash->{helper}{virtTC}
                                           ,$hash->{helper}{vd}{val}));
      }
      InternalTimer($tn+10,"CUL_HM_valvePosTmr","valveTmr:$vId",0);
    }
    elsif ($hash->{helper}{vd}{typ} == 2){
      CUL_HM_PushCmdStack($hash,sprintf("%02X%s%s"
                                        ,$msgCnt
                                        ,$hash->{helper}{vd}{cmd}
                                        ,$hash->{helper}{vd}{val}));
      $hash->{helper}{vd}{next} = $hash->{helper}{vd}{nextM};
      InternalTimer($hash->{helper}{vd}{next},"CUL_HM_valvePosUpdt","valvePos:$vId",0);
    }
  }
  else{
    delete $hash->{helper}{virtTC};
    CUL_HM_UpdtReadSingle($hash,"state","stopped",1);
    return;# terminate processing
  }
  $hash->{helper}{virtTC} = "00";
  CUL_HM_ProcessCmdStack($hash);
}
sub CUL_HM_valvePosTmr(@) {#calc next vd wakeup
  my($in ) = @_;
  my(undef,$vId) = split(':',$in);
  my $hash = CUL_HM_id2Hash($vId);
  my $name = $hash->{NAME};
  my $vc = ReadingsVal($name,"valveCtrl","init");
Log 1,"##### tmr1:$name, vCtrl:$vc, msgRdc:$hash->{helper}{vd}{msgRed} #####";
  if ($vc eq "init") {
  $hash->{helper}{vd}{next} = $hash->{helper}{vd}{nextF};
  CUL_HM_UpdtReadSingle($hash,"valveCtrl","ready",1);
  }
  elsif (($vc eq "ok") && $hash->{helper}{vd}{msgRed}) {
Log 1,"##### tmr2:$name, vCtrl:$vc, msgRdc:$hash->{helper}{vd}{msgRed} #####";
  $hash->{helper}{vd}{miss} = 1;
  $hash->{helper}{vd}{next} = $hash->{helper}{vd}{nextF};
  CUL_HM_UpdtReadSingle($hash,"valveCtrl","idle",1);
  }
  else {
    my $pn = CUL_HM_id2Name($hash->{helper}{vd}{id});
    my $ackTime = ReadingsTimestamp($pn, "ValvePosition", "");
    my $vc;
    if (!$ackTime || $ackTime eq $hash->{helper}{vd}{ackT} ){
      $hash->{helper}{vd}{next} = $hash->{helper}{vd}{nextF};
      $vc = (++$hash->{helper}{vd}{miss} > 5)
                                          ?"lost"
                                          :"miss_".$hash->{helper}{vd}{miss};
      Log3 $name,5,"CUL_HM $name virtualTC use fail-timer";
    }
    else{
      CUL_HM_UpdtReadBulk($hash,0,".next:".$hash->{helper}{vd}{next}
                                 ,".msgCnt:".($hash->{helper}{vd}{msgCnt}-1));
      $hash->{helper}{vd}{next} = $hash->{helper}{vd}{nextM};
      $vc = "ok";
      $hash->{helper}{vd}{miss} = 0;
    }
    CUL_HM_UpdtReadSingle($hash,"valveCtrl",$vc,1)
          if(ReadingsVal($name,"valveCtrl","") ne $vc);
    $hash->{helper}{vd}{ackT} = $ackTime;
  }
  InternalTimer($hash->{helper}{vd}{next},"CUL_HM_valvePosUpdt","valvePos:$vId",0);
}


erhalte ich folgende logausgaben in fhem.log:

0.nach shutdown, restart (attr war angelegt)
2014.02.13 22:10:51.327 1: ##### init1 ##### cmd:set, model:virtual_1, attrVal:msgReduce, msgRdc:
2014.02.13 22:10:51.329 1: ##### init2 ##### cmd:set, model:virtual_1, attrVal:msgReduce, msgRdc:1

1. funktiondurchlauf
2014.02.13 22:10:56.565 1: ##### updt1:VentilControler.Kueche_Btn1, vCtrl:init, msgRdc:0 #####
2014.02.13 22:11:06.572 1: ##### tmr1:VentilControler.Kueche_Btn1, vCtrl:init, msgRdc:0 #####

2. funktiondurchlauf
2014.02.13 22:11:18.875 1: ##### updt1:VentilControler.Kueche_Btn1, vCtrl:ready, msgRdc:0 #####
2014.02.13 22:11:18.877 1: ##### updt2:VentilControler.Kueche_Btn1, vCtrl:ready, msgRdc:0 #####
2014.02.13 22:11:28.883 1: ##### tmr1:VentilControler.Kueche_Btn1, vCtrl:ready, msgRdc:0 #####

3. funktiondurchlauf
2014.02.13 22:13:36.388 1: ##### updt1:VentilControler.Kueche_Btn1, vCtrl:ok, msgRdc:0 #####
2014.02.13 22:13:36.389 1: ##### updt2:VentilControler.Kueche_Btn1, vCtrl:ok, msgRdc:0 #####
2014.02.13 22:13:46.400 1: ##### tmr1:VentilControler.Kueche_Btn1, vCtrl:ok, msgRdc:0 #####

##############################################################################################

deleteattr parentdev param msgReduce
2014.02.13 23:01:39.581 1: ##### init1 ##### cmd:del, model:virtual_1, attrVal:, msgRdc:1
2014.02.13 23:01:39.583 1: ##### init2 ##### cmd:del, model:virtual_1, attrVal:, msgRdc:

attr parentdev param msgReduce
2014.02.13 23:06:02.063 1: ##### init1 ##### cmd:set, model:virtual_1, attrVal:msgReduce, msgRdc:
2014.02.13 23:06:02.065 1: ##### init2 ##### cmd:set, model:virtual_1, attrVal:msgReduce, msgRdc:1


$hash->{helper}{vd}{msgRed} ist in den funktionen nicht definiert und wird dann dort neu definiert und zu 0 gesetzt.
attribut setzen geht nur im parent. ein get param liefert in parent und channel undef.

jetzt habe ich es einigermassen durch folgende änderung zum laufen bekommen:

    elsif ($md =~ m/^virtual_/){
my $myHash = CUL_HM_id2Hash(CUL_HM_hash2Id($hash)."01");
Log 1,"##### init1 ##### cmd:$cmd, model:$md, attrVal:$attrVal, msgRdc:$hash->{helper}{vd}{msgRed}";
      if ($cmd eq "set"){
        if ($attrVal eq "noOnOff"){# no action    
        }
        elsif ($attrVal eq "msgReduce"){#set param
          $myHash->{helper}{vd}{msgRed}=1;
        }
        else{
          return "attribut param not defined for this entity";
        }
      }
      else{
        delete $myHash->{helper}{vd}{msgRed};
      }
Log 1,"##### init2 ##### cmd:$cmd, model:$md, attrVal:$attrVal, msgRdc:$hash->{helper}{vd}{msgRed}";
    }


aber:
komischerweise werden nach einem neustart zwar die werte initialisiert in elsif, aber wiederum sind sie in den funktionen nicht definiert. erst ein weiteres setzen der attribute bewirkt das die funktionen nun die werte auch kennen. ab da funktioniert es.
und weiterhin ergibt ein get param msgreduce in parent und child undef.

heute nacht träume ich von "hash".  ???

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

hm - mus sich einmal testen.
Du hast den "param " schon am channel gesetzt, nicht etwa am virtuellen Device? dann geht es nicht.

Timer sparen macht sinn...
gegenargumente sind aenderungen an der Ventilstellung. Eigentlich sollte die Message nur ausgelassen werden, wenn keine Aenderung in der Zwischenzeit stattgefunden hat.

Zum sparen: Die Anzahl laufender Timer kannst du  nicht reduzieren, das ist immer einer je virtTC. Sollte aber kaum Performance kosten. Was du sparst ist der Aufruf und die Bearbeitung der Prozedur. Vom Konzept waere also zu beachten
1) wenn skip, dann gleich in CUL_HM_valvePosUpdt. CUL_HM_valvePosTmr kennt kein Reduced
2) skip nur wenn die letzte Message ein ack hatte
3) skip nur, wenn der wert nicht geaendert wurde (oder anders herum: force send if changed)

Werde einmal nachdenken...
Die Performance der timerprocedur kann man ausmessen und die moegliche Einsparung bewerten. Dann entscheiden, wie es zusammenpasst

Gruss Martin

frank

hallo martin,

ZitatDu hast den "param " schon am channel gesetzt, nicht etwa am virtuellen Device? dann geht es nicht.

wie mehrfach gesagt, geht das bei mir ja nicht!

dann ist aber endlich klar, warum nicht. ich habe meinen channel attr model umbenannt. rate mal. nicht mehr "virtual_1", sondern aus dem riesigen angebot des pulldown menue den eintrag "hm-cc-tc".

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

Zitatwie mehrfach gesagt, geht das bei mir ja nicht!
ok - also param gibt es bei virtuellen channels...
model und sybtype sollte man nicht aendern...

ich habe eine dynamische einstellung vorbereitet - muss ich noch testen
attr vtc param msgReduce:5
sendet dann erst den 5.
attr vtc param msgReduce
weiterhin ein skip.

Ausserdem gefaellt mir das valveCtrl "idle" nicht. Wenn du msgReduced einschaltest wuerde dies im normalbetrieb kontinuierlich trigger generieren. Daher ist es in meiner version(kann erst heute Abend testen, dauert also) eliminiert. Ich denke du brauchst es bestenfalls zum testen

Gruss Martin

frank

Zitatmodel und sybtype sollte man nicht aendern...
das dachte ich auch immer. ...doch während der suche nach einem fehler, nötigte mich dieses kilometerlange pulldown-menue förmlich dazu.  ;)

ZitatAusserdem gefaellt mir das valveCtrl "idle" nicht. ... Ich denke du brauchst es bestenfalls zum testen
ein name, unterschiedlich zu "ok", ist zur zeit zwingend erforderlich. sonst wird immer gesendet, weil immer "ok".

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

martinp876

Zitatein name, unterschiedlich zu "ok", ist zur zeit zwingend erforderlich. sonst wird immer gesendet, weil immer "ok".
schon klar - jetzt. Daher sollte es auch geaendert werden.
Aktueller Ansatz ist, helper/msgRed nicht als flag sondern als limit zu nutzen. Also Werte 0...9 zulassen (ok, ab 5 wird es schwierig ;) andere Diskussion) .
helper/miss wird inkrementiert (ohne reading-change) bis der megRed level erreicht ist. Dann kann valveCtrl ok stehen bleiben.
Wenn miss >= msgRep wird wieder gesendet, miss =0 gesetzt (so ein ACK kommt) und es geht von vorne los.

Klingt ok?

Gruss Martin

frank

hallo martin,

ZitatAktueller Ansatz ist, helper/msgRed nicht als flag sondern als limit zu nutzen. Also Werte 0...9 zulassen (ok, ab 5 wird es schwierig ;) andere Diskussion) .
helper/miss wird inkrementiert (ohne reading-change) bis der megRed level erreicht ist. Dann kann valveCtrl ok stehen bleiben.
Wenn miss >= msgRep wird wieder gesendet, miss =0 gesetzt (so ein ACK kommt) und es geht von vorne los.

theoretisch ganz gut.  ;)

dabei würde wohl auch die korrekte fehlerausgabe miss_n erhalten bleiben. also zb 3 mal auslassen, dann fehler => miss_4.

hilfreich wäre dann aber ein event, das den aktuellen msgRed signalisiert, um zu loggen. also beim umschalten, oder so. sonst kann man zb im fehler-log keine zusammenhänge zum modus feststellen.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html