smartVISU visu.js uzsu mit Bedingung?

Begonnen von Hans Franz, 21 Februar 2015, 13:43:04

Vorheriges Thema - Nächstes Thema

bgewehr

Also, sehr gutes Ergebnis:
1. default {} erspart setreading... das ist wirklich einfach und gut!
2. UZSU_execute im converter aufzurufen ist ebenfalls sehr praktisch und erspart dem JSON den Umweg über das Reading, was offensichtlich besser funktioniert

Eines gefällt mir noch gar nicht!
Ich bekomme es einfach nicht mit, wenn mein perl string falsch war. Er wird dann einfach nicht umgesetzt, es entsteht irgenein WDT und ich denke, alles ist in Ordnung.

Können wir nicht ein
try...
except
    setze den perl-script-value auf 'error in perl string: "ursprünglicher perl string"' setzen? Oder einen smartVISU Error oben rechts in der Ecke?

Was meint Ihr?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

dev0

Die simpelste Variante, die mir dazu einfällt und kein zusätzliches Perl Modul benötigt:

  eval $uzsu->{list}[$i]->{condition}->{conditionDevicePerl};
  DoTrigger($device, "ERROR PERLCONDITION", 1) if $@;
  ...

Auf das Event könnte man dann mit einem status.notify regieren.

Muk.s

Ich klinke mich hier auch mal ein  :)

ZitatEine Frage fällt mir ein: sollen wir grundsätzlich wieder einen WDT pro Zeile erstellen oder nur für diejenigen, die eine Condition haben? Das eine ist etwas einfacher als das Andere... Was meint Ihr?

ZitatIch halte die WDT pro Zeile Variante für einfacher und durchschaubarer.

Ein WDT pro Zeile mag einfacher sein, aber bläht es die Anzahl der WDT nicht unnötig auf?
Für eine UZSU mit 6 Zeilen benötige ich heute (ohne condition)  1 WDT, in Zukunft wären das aber 6. Da kommen schnell einige Dutzend WDT zusammen.

Mein Vorschlag wäre folgender: Nur wenn in mindestens einer UZSU Zeile eine Condition vorhanden ist, wird ein WDT pro Zeile erstellt, ansonsten 1 WDT für alle Zeilen

Dürfte mit ein paar zusätzlichen Zeilen in der fronthemUZSU_execute() umsetzbar sein, kann mich ja mal dransetzen.



bgewehr

FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Ich habe grade noch folgendes im log gesehen, worauf wir achten müssen:


2016.03.21 18:40:31 4: [wdt_uzsu_Roll_EG_0] (ReadingsVal("device1","state","") > "100") - NOT accepted, must be command or condition


Was will er denn?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Muk.s

Hier mal auf die Schnelle noch ein Vorschlag für eine modifizierte Version der UZSU_execute, ungetestet und ohne Gewähr  ;)
Für jede Zeile mit Condition wird ein seperater WDT erstellt, alle Zeilen ohne Condition werden in einem gemeinsamen WDT zusammengefasst.
Zumindest ist das der Plan  :) , bin mir aber hiermit $weekdays_all = $weekdays_all.' '.$weekdays; nicht so ganz sicher.


###############################################################################
#
# Umsetzen der UZSU-Settings für ein device
#
###############################################################################
sub UZSU_execute($$)
{
my ($device, $uzsu) = @_;
my $weekdays = "";
my $weekdays_all = "";   ## added by muk.s
my $condition_exist = 0; ## added by muk.s
my $perlString = "";

$uzsu = decode_json($uzsu);

fhem('delete wdt_uzsu_'.$device.'.*');

for(my $i=0; $i < @{$uzsu->{list}}; $i++) {
$condition_exist = 0;   ## added by muk.s
$weekdays = $uzsu->{list}[$i]->{rrule};
     $weekdays = substr($weekdays,18,50);

     # if the structure contains the holidays list, use it!
     if ($uzsu->{list}[$i]->{holiday}->{weekend}) {
if ($weekdays ne '') {
$weekdays = $weekdays . ',';
}
      $weekdays = $weekdays . '$we';
     }
     if ($uzsu->{list}[$i]->{holiday}->{work}) {
if ($weekdays ne '') {
$weekdays = $weekdays . ',';
}
      $weekdays = $weekdays . '!$we';
     }
     
     if ($uzsu->{list}[$i]->{event} eq 'time'){
         $weekdays = $weekdays.'|'.$uzsu->{list}[$i]->{time}.'|'.$uzsu->{list}[$i]->{value};
     } else {
         # Bugfix below: because sunset_abs from 99_sunrise_el does not work if max-time = ""
         if ($uzsu->{list}[$i]->{timeMin} ne '' and $uzsu->{list}[$i]->{timeMax} ne '') {
             $weekdays = $weekdays.'|{'.$uzsu->{list}[$i]->{event}.'_abs("REAL",'.$uzsu->{list}[$i]->{timeOffset} * 60 .',"'.$uzsu->{list}[$i]->{timeMin}.'","'.$uzsu->{list}[$i]->{timeMax}.'")}|'.$uzsu->{list}[$i]->{value};
         } else {
             $weekdays = $weekdays.'|{'.$uzsu->{list}[$i]->{event}.'_abs("REAL",'.$uzsu->{list}[$i]->{timeOffset} * 60 .',,)}|'.$uzsu->{list}[$i]->{value};
         }
     }
     
     # if the structure contains a condition, use it!
if ($uzsu->{list}[$i]->{condition}->{conditionActive}) {
    $condition_exist = 1;  ## added by muk.s
    if ($uzsu->{list}[$i]->{condition}->{conditionType} eq 'Perl') {
Log 4,  'uzsu Perl-Condition\n';
$perlString = $uzsu->{list}[$i]->{condition}->{conditionDevicePerl};
Log 4, 'uzsu ' .  $perlString;
#$perlString =~ s/\\"/"/ig;
#Log 4, 'uzsu ' .  $perlString;
      $weekdays = $weekdays.' ('.$perlString.')';
Log 4, 'uzsu ' , $weekdays;
      } else {
Log 4, 'uzsu non-Perl-Condition\n';
      $weekdays = $weekdays.' (ReadingsVal("'.$uzsu->{list}[$i]->{condition}->{conditionDevicePerl}.'","state","") '.$uzsu->{list}[$i]->{condition}->{conditionType}.' "'.$uzsu->{list}[$i]->{condition}->{conditionValue}.'")';
      }
     } else {
   # if the uzsu row has no condition, add row to $weekdays_all
   $weekdays_all = $weekdays_all.' '.$weekdays; ## added by muk.s
}

     # create single WDT with condition
if ($uzsu->{list}[$i]->{active} && $condition_exist != 0){
         fhem('defmod wdt_uzsu_'.$device.'_'.$i.' WeekdayTimer '.$device.' en '.$weekdays);
         fhem('attr wdt_uzsu_'.$device.'_'.$i.' room UZSU');
         fhem('attr wdt_uzsu_'.$device.'_'.$i.' group '.$device);
     }
    ## moved by muk.s to end of sub
}
# create combined WDT for all non-condition rows - added by muk.s
if ($weekdays_all ne '') {
    fhem('defmod wdt_uzsu_'.$device.' WeekdayTimer '.$device.' en '.$weekdays);
    fhem('attr wdt_uzsu_'.$device.' room UZSU');
    fhem('attr wdt_uzsu_'.$device.' group '.$device);
}
#fhem('save');   # use only if you want to save WDT settings immediately.
}

package fronthem;
use strict;
use warnings;


bgewehr

Also nach etwas überlegen frage ich mich, ob das den Aufwand wert ist. Die WDT werden im Raum UZSU nach devices gruppiert und wenn es 100 sind, ist das eigentlich nicht schlimm, da sie keine Last oder sonstige Nachteile erzeugen, oder?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

bgewehr

Ich habe als nächstes vor, die DelayedExecutionCondition anzugehen, dann passt die Filterung nach nur Condition schon wieder nicht und es wird noch komplizierter, die Fälle zu unterscheiden. Lohnt das wirklich?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Muk.s

Ob es sich lohnt bzw gelohnt hätte, wird sich spätestens in der Praxis zeigen  :)
Vielleicht sollte man das ganze auch von einer anderen Seite angehen und das WeekdayTimer Modul entsprechend anpassen, aber das wäre ein anderer Thread.

bgewehr

Was hältst Du davon: ich mache erst mal die DelayedExecutionCondition und danach optimieren wir auf möglichst wenige WDT?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Muk.s


bgewehr

FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868

Muk.s

#42
Sollte eigentlich nicht so aufwendig sein.
Die DelayedExecutionCondition ist ja nur simpler True/False Flag. Im Grunde würde ein zusätzliches Feld in der UZSU widget reichen in den man einen Perl string eingibt der True bzw 1 zurückgibt und diesen als DelayedExecutionCondition attribute speichert.  Wenn man das Feld, analog zu den conditions, in jeder Zeile zur Verfügung hätte, würde das die größtmögliche Flexibilität bieten. Zu überlegen wäre, ob man den String in der UZSU_execute eventuell noch nach Syntaxfehler abklopft.   

Gerade mal getestet:
   
{(Value("Fenster_Bad") eq "auf" )}

funktioniert bestens.

Edit: Gerade gesehen, mworion hat die DelayedExecutionCondition schon im widget umgesetzt

Muk.s

So, hier mal eine auf das uzsu_widget V4.4 angepasste UZSU_execute.
Getestet mit SmartVisu 2.8 - funktioniert soweit.

Ich habe noch eine kleine Änderung bei der conditions auswertung eingebaut. Damit sind auch solche conditions möglich:
{ fhem("set DEVICE_X $EVENT") if( Value("device") eq "on" ) }

Schöne Ostern


###############################################################################
#
# Umsetzen der UZSU-Settings für ein device
# for use with UZSUwidget V4.4
#
###############################################################################
sub UZSU_execute($@)
{
my ($device, $uzsu) = @_;
my $weekdays = "";
my $delayedExec ="";
my $perlString = "";

$uzsu = decode_json($uzsu);

fhem('delete wdt_uzsu_'.$device.'.*');

for(my $i=0; $i < @{$uzsu->{list}}; $i++) {
     $weekdays = $uzsu->{list}[$i]->{rrule};
     $weekdays = substr($weekdays,18,50);
$delayedExec = "";

     # if the structure contains the holidays list, use it!
     if ($uzsu->{list}[$i]->{holiday}->{weekend}) {
if ($weekdays ne '') {
$weekdays = $weekdays . ',';
}
      $weekdays = $weekdays . '$we';
     }
     if ($uzsu->{list}[$i]->{holiday}->{work}) {
if ($weekdays ne '') {
$weekdays = $weekdays . ',';
}
      $weekdays = $weekdays . '!$we';
     }
     
     if ($uzsu->{list}[$i]->{event} eq 'time'){
         $weekdays = $weekdays.'|'.$uzsu->{list}[$i]->{time}.'|'.$uzsu->{list}[$i]->{value};
     } else {
         # Bugfix below: because sunset_abs from 99_sunrise_el does not work if max-time = ""
         if ($uzsu->{list}[$i]->{timeMin} ne '' and $uzsu->{list}[$i]->{timeMax} ne '') {
             $weekdays = $weekdays.'|{'.$uzsu->{list}[$i]->{event}.'_abs("REAL",'.$uzsu->{list}[$i]->{timeOffset} * 60 .',"'.$uzsu->{list}[$i]->{timeMin}.'","'.$uzsu->{list}[$i]->{timeMax}.'")}|'.$uzsu->{list}[$i]->{value};
         } else {
             $weekdays = $weekdays.'|{'.$uzsu->{list}[$i]->{event}.'_abs("REAL",'.$uzsu->{list}[$i]->{timeOffset} * 60 .',,)}|'.$uzsu->{list}[$i]->{value};
         }
     }
     
     # if the structure contains a condition, use it!
if ($uzsu->{list}[$i]->{condition}->{active}) {
    if ($uzsu->{list}[$i]->{condition}->{type} eq 'Perl') {
Log 4,  'uzsu Perl-Condition\n';
$perlString = $uzsu->{list}[$i]->{condition}->{devicePerl};
Log 4, 'uzsu ' .  $perlString;
#$perlString =~ s/\\"/"/ig;
#Log 4, 'uzsu ' .  $perlString;
                if (substr($perlString,0,1) eq "{") {
                   $weekdays = $weekdays.' '.$perlString;
                } else {
         $weekdays = $weekdays.' ('.$perlString.')';
                }
Log 4, 'uzsu ' . $weekdays;
      } else {
Log 4, 'uzsu non-Perl-Condition\n';
      $weekdays = $weekdays.' (ReadingsVal("'.$uzsu->{list}[$i]->{condition}->{devicePerl}.'","state","") '.$uzsu->{list}[$i]->{condition}->{type}.' "'.$uzsu->{list}[$i]->{condition}->{value}.'")';
      }
     }

    # if the structure contains a delayedExec, use it!
if ($uzsu->{list}[$i]->{delayedExec}->{active}) {
    if ($uzsu->{list}[$i]->{delayedExec}->{type} eq 'Perl') {
Log 4,  'uzsu Perl-Condition\n';
$perlString = $uzsu->{list}[$i]->{delayedExec}->{devicePerl};
Log 4, 'uzsu ' .  $perlString;
#$perlString =~ s/\\"/"/ig;
#Log 4, 'uzsu ' .  $perlString;
      $delayedExec = $perlString;
#Log 4, 'uzsu ' , $weekdays;
      } else {
Log 4, 'uzsu non-Perl-Condition\n';
      $delayedExec = '{ (ReadingsVal("'.$uzsu->{list}[$i]->{delayedExec}->{devicePerl}.'","state","") '.$uzsu->{list}[$i]->{delayedExec}->{type}.' "'.$uzsu->{list}[$i]->{delayedExec}->{value}.'") }';
      }
     }


     if ($uzsu->{list}[$i]->{active}){
         fhem('defmod wdt_uzsu_'.$device.'_'.$i.' WeekdayTimer '.$device.' en '.$weekdays);
         fhem('attr wdt_uzsu_'.$device.'_'.$i.' room UZSU');
         fhem('attr wdt_uzsu_'.$device.'_'.$i.' group '.$device);
if ($delayedExec) {
fhem('attr wdt_uzsu_'.$device.'_'.$i.' delayedExecutionCond '.$delayedExec);
}
     }
     #fhem('save');   # use only if you want to save WDT settings immediately.
}
}

package fronthem;
use strict;
use warnings;

bgewehr

Sehr gut, klasse! Ich bin noch dafür, auf die Eingabe der {} zu verzichten, weil es die Condition auch nicht will. Dann besser beide perl strings ohne {} und die Funktion fügt das hinzu, wenn nötig. Was meinst Du?
FritzBox 7590, Synology DS216+II mit Docker
Docker: FHEM mit hmlan, Homebridge, node-red, mosquitto, ems-collector für Buderus EMS mit AVR Net-IO
Gartenwasser über MQTT auf R/Pi A+
Volkszaehler.org auf R/Pi 2B mit Pi_Erweiterung
Raspberrymatic auf R/Pi 4B mit RPI-RF-MOD u. CUL868