From 07d1802e2a22c5ade2f2a752b6e51a833caeb944 Mon Sep 17 00:00:00 2001 From: nasseeder1 Date: Fri, 1 May 2020 19:57:22 +0000 Subject: [PATCH] 60_Watches: contrib 0.8.0 git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@21830 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- contrib/DS_Starter/60_Watches.pm | 415 ++++++++++++++++++++++--------- 1 file changed, 297 insertions(+), 118 deletions(-) diff --git a/contrib/DS_Starter/60_Watches.pm b/contrib/DS_Starter/60_Watches.pm index 51b33de96..357d2ea50 100644 --- a/contrib/DS_Starter/60_Watches.pm +++ b/contrib/DS_Starter/60_Watches.pm @@ -36,6 +36,7 @@ use Time::HiRes qw(time gettimeofday tv_interval); # Versions History intern our %Watches_vNotesIntern = ( + "0.8.0" => "01.05.2020 new values 'countdownwatch' for attribute digitalDisplayPattern, switch all watches to server time ", "0.7.0" => "30.04.2020 new set 'continue' for stopwatch ", "0.6.0" => "29.04.2020 new set 'reset' for stopwatch, read 'state' and 'starttime' from readings, add csrf token support ", "0.5.0" => "28.04.2020 new values 'stopwatch', 'staticwatch' for attribute digitalDisplayPattern ", @@ -53,7 +54,7 @@ sub Watches_Initialize { $hash->{SetFn} = "Watches_Set"; $hash->{AttrList} = "digitalColorBackground:colorpicker ". "digitalColorDigits:colorpicker ". - "digitalDisplayPattern:staticwatch,stopwatch,text,watch ". + "digitalDisplayPattern:countdownwatch,staticwatch,stopwatch,text,watch ". "digitalDisplayText ". "modernColorBackground:colorpicker ". "modernColorHand:colorpicker ". @@ -116,18 +117,43 @@ sub Watches_Set { ## no criti my $model = $hash->{MODEL}; my $addp = AttrVal($name,"digitalDisplayPattern","watch"); - return if(IsDisabled($name) || $addp !~ /stopwatch|staticwatch/); + return if(IsDisabled($name) || $addp !~ /stopwatch|staticwatch|countdownwatch/); my $setlist = "Unknown argument $opt, choose one of "; - $setlist .= "time " if($addp =~ /staticwatch/); - $setlist .= "reset:noArg continue:noArg start:noArg stop:noArg" if($addp =~ /stopwatch/); + $setlist .= "time " if($addp =~ /staticwatch/); + $setlist .= "reset:noArg continue:noArg start:noArg stop:noArg " if($addp =~ /stopwatch/); + $setlist .= "countDownInit continue:noArg start:noArg stop:noArg " if($addp =~ /countdownwatch/); if ($opt =~ /\bstart\b/) { + return qq{Please set "countDownInit" before !} if($addp =~ /countdownwatch/ && !ReadingsVal($name, "countInitVal", "")); + my $ms = int(time*1000); - readingsSingleUpdate($hash, "starttime", $ms, 0); - readingsSingleUpdate($hash, "state", "started", 1); + + readingsBeginUpdate ($hash); + ReadingsBulkUpdateValue ($hash, "countDownDone", 0) if($addp =~ /countdownwatch/); + ReadingsBulkUpdateValue ($hash, "starttime", $ms); + ReadingsBulkUpdateValue ($hash, "state", "started"); + readingsEndUpdate ($hash, 1); + + } elsif ($opt eq "countDownInit") { + $prop = ($prop ne "") ? $prop : 70; # Stunden + $prop1 = ($prop1 ne "") ? $prop1 : 70; # Minuten + $prop2 = ($prop2 ne "") ? $prop2 : 70; # Sekunden + return qq{The value for "$opt" is invalid. Use parameter "hh mm ss" like "19 45 13".} if($prop>24 || $prop1>59 || $prop2>59); + + my $st = int(time*1000); # Millisekunden ! + my $ct = $prop*3600 + $prop1*60 + $prop2; # Sekunden ! + + Watches_delread ($name); + readingsBeginUpdate ($hash); + ReadingsBulkUpdateValue ($hash, "countDownDone", 0); + ReadingsBulkUpdateValue ($hash, "countInitVal", $ct); + ReadingsBulkUpdateValue ($hash, "state", "initialized"); + readingsEndUpdate ($hash, 1); } elsif ($opt eq "continue") { + return qq{Please set "countDownInit" before !} if($addp =~ /countdownwatch/ && !ReadingsVal($name, "countInitVal", "")); + if(!ReadingsVal($name, "starttime", "")) { my $ms = int(time*1000); readingsSingleUpdate($hash, "starttime", $ms, 0); @@ -143,13 +169,13 @@ sub Watches_Set { ## no criti readingsSingleUpdate($hash, "state", "initialized", 1); } elsif ($opt eq "time") { - return qq{The value(s) for "time" is invalid. Use parameter "hh mm ss" like "19 45 13".} if($prop>24 || $prop1>59 || $prop2>59); + return qq{The value for "$opt" is invalid. Use parameter "hh mm ss" like "19 45 13".} if($prop>24 || $prop1>59 || $prop2>59); readingsBeginUpdate ($hash); readingsBulkUpdateIfChanged ($hash, "hour", $prop); readingsBulkUpdateIfChanged ($hash, "minute", $prop1); readingsBulkUpdate ($hash, "second", $prop2); - readingsEndUpdate ($hash,0); + readingsEndUpdate ($hash, 1); } else { return "$setlist"; @@ -268,7 +294,7 @@ sub Watches_digital { + ':' + ((minutes < 10) ? '0' : '') + minutes + ':' + ((seconds < 10) ? '0' : '') + seconds"; - } elsif($addp eq "stopwatch") { + } elsif($addp eq "stopwatch" || $addp eq "countdownwatch") { $ddp = "###:##:##"; $ddt = "((hours_$d < 10) ? ' 0' : ' ') + hours_$d + ':' + ((minutes_$d < 10) ? '0' : '') + minutes_$d @@ -313,7 +339,9 @@ sub Watches_digital { // Definition variables var state_$d; - var ms_$d; + var st_$d; + var ct_$d; + var ci_$d; var csrf; var url_$d; var devName_$d; @@ -321,7 +349,7 @@ sub Watches_digital { var hours_$d; var minutes_$d; var seconds_$d; - var startDate_$d; + var startDate_$d; function SegmentDisplay_$d(displayId_$d) { this.displayId_$d = displayId_$d; @@ -886,49 +914,65 @@ sub Watches_digital { function makeCommand (cmd) { return getBaseUrl()+\"cmd=\"+encodeURIComponent(cmd)+\"&XHR=1\"; } - + + // localStorage Set + function localStoreSet (hours, minutes, seconds) { + localStorage.setItem('h_$d', hours); + localStorage.setItem('m_$d', minutes); + localStorage.setItem('s_$d', seconds); + } + animate_$d(); function animate_$d() { var watchkind_$d = '$addp'; if (watchkind_$d == 'watch') { - var time = new Date(); + // aktueller Timestamp in Millisekunden + command = '{ int(time*1000) }'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); ct_$d = parseInt(data); return ct_$d;} ); + var time = new Date(ct_$d); var hours = time.getHours(); var minutes = time.getMinutes(); var seconds = time.getSeconds(); } + if (watchkind_$d == 'staticwatch') { var hours_$d = '$h'; var minutes_$d = '$m'; var seconds_$d = '$s'; } + if (watchkind_$d == 'stopwatch') { - devName_$d = '$d'; - selVal_$d = 'state'; - command = '{ReadingsVal(\"'+devName_$d+'\",\"'+selVal_$d+'\",\"\")}'; - url_$d = makeCommand(command); + devName_$d = '$d'; + + command = '{ReadingsVal(\"'+devName_$d+'\",\"state\",\"\")}'; + url_$d = makeCommand(command); \$.get( url_$d, function (data) {state_$d = data.replace(/\\n/g, ''); return state_$d;} ); - - if (state_$d == 'started') { - selVal_$d = 'starttime'; - command = '{ReadingsNum(\"'+devName_$d+'\",\"'+selVal_$d+'\", 0)}'; + if (state_$d == 'started') { + // == Startzeit == + command = '{ReadingsNum(\"'+devName_$d+'\",\"starttime\", 0)}'; url_$d = makeCommand(command); - \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); ms_$d = parseInt(data); return ms_$d;} ); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); st_$d = parseInt(data); return st_$d;} ); - startDate_$d = new Date(ms_$d); - endDate_$d = new Date(); - elapsesec_$d = ((endDate_$d.getTime() - startDate_$d.getTime()))/1000; // vergangene Millisekunden in Sekunden + startDate_$d = new Date(st_$d); + + // aktueller Timestamp in Millisekunden + command = '{ int(time*1000) }'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); ct_$d = parseInt(data); return ct_$d;} ); + + currDate_$d = new Date(ct_$d); + + elapsesec_$d = ((currDate_$d.getTime() - startDate_$d.getTime()))/1000; // vergangene Millisekunden in Sekunden hours_$d = parseInt(elapsesec_$d / 3600); elapsesec_$d -= hours_$d * 3600; minutes_$d = parseInt(elapsesec_$d / 60); seconds_$d = elapsesec_$d - minutes_$d * 60; - localStorage.setItem('h_$d', hours_$d); - localStorage.setItem('m_$d', minutes_$d); - localStorage.setItem('s_$d', seconds_$d); - + localStoreSet (hours_$d, minutes_$d, seconds_$d); } if (state_$d == 'stopped') { @@ -941,20 +985,91 @@ sub Watches_digital { hours_$d = 0; minutes_$d = 0; seconds_$d = 0; - localStorage.setItem('h_$d', hours_$d); - localStorage.setItem('m_$d', minutes_$d); - localStorage.setItem('s_$d', seconds_$d); + + localStoreSet (hours_$d, minutes_$d, seconds_$d); + } + } + + if (watchkind_$d == 'countdownwatch') { + devName_$d = '$d'; + + command = '{ReadingsVal(\"'+devName_$d+'\",\"state\",\"\")}'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {state_$d = data.replace(/\\n/g, ''); return state_$d;} ); + + if (state_$d == 'started') { + // == Ermittlung Countdown Startwert == + command = '{ReadingsNum(\"'+devName_$d+'\",\"countInitVal\", 0)}'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); ci_$d = parseInt(data); return ci_$d;} ); + countInitVal_$d = ci_$d; // Initialwert Countdown in Sekunden + + // == Ermittlung vergangene Sekunden == + command = '{ReadingsNum(\"'+devName_$d+'\",\"starttime\", 0)}'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); st_$d = parseInt(data); return st_$d;} ); + startDate_$d = new Date(st_$d); + + // aktueller Timestamp in Millisekunden + command = '{ int(time*1000) }'; + url_$d = makeCommand(command); + \$.get( url_$d, function (data) {data = data.replace(/\\n/g, ''); ct_$d = parseInt(data); return ct_$d;} ); + + currDate_$d = new Date(ct_$d); + + elapsesec_$d = ((currDate_$d.getTime() - startDate_$d.getTime()))/1000; // vergangene Millisekunden in Sekunden umrechnen + + // == Countdown errechnen == + countcurr_$d = countInitVal_$d - elapsesec_$d; + if (countcurr_$d < 0) { + countcurr_$d = 0; + } + //log(\"countcurr_$d: \"+countcurr_$d); + + hours_$d = parseInt(countcurr_$d / 3600); + countcurr_$d -= hours_$d * 3600; + minutes_$d = parseInt(countcurr_$d / 60); + seconds_$d = countcurr_$d - minutes_$d * 60; + + localStoreSet (hours_$d, minutes_$d, seconds_$d); + + if (hours_$d + minutes_$d + seconds_$d == 0) { + Reading_$d = 'countDownDone'; + command = '{ CommandSetReading(undef, \"'+devName_$d+' countDownDone 1\") }'; + url_$d = makeCommand(command); + + \$.get(url_$d, function (data) { + command = '{ CommandSetReading(undef, \"'+devName_$d+' state stopped\") }'; + url_$d = makeCommand(command); + \$.get(url_$d); + } + ); + } + } + + if (state_$d == 'stopped') { + hours_$d = localStorage.getItem('h_$d'); + minutes_$d = localStorage.getItem('m_$d'); + seconds_$d = localStorage.getItem('s_$d'); + } + + if (state_$d == 'initialized') { + hours_$d = 0; + minutes_$d = 0; + seconds_$d = 0; + + localStoreSet (hours_$d, minutes_$d, seconds_$d); } } var value = $ddt; - + if(value == ' undefined:undefined:undefined' || value == ' NaN:NaN:NaN') { value = ' : : '; } display_$d.setValue(value); - window.setTimeout('animate_$d()', 100); + window.setTimeout('animate_$d()', 200); } @@ -985,6 +1100,29 @@ sub Watches_station {