diff --git a/CHANGED b/CHANGED index 37eb437..b612008 100644 --- a/CHANGED +++ b/CHANGED @@ -1 +1 @@ - Reviewed-by: Marko Oldenburg + [enhancement] - add resetvalveerrors ic24 diff --git a/FHEM/73_GardenaSmartBridge.pm b/FHEM/73_GardenaSmartBridge.pm index d3bec09..934335c 100644 --- a/FHEM/73_GardenaSmartBridge.pm +++ b/FHEM/73_GardenaSmartBridge.pm @@ -737,7 +737,7 @@ sub ErrorHandling { my $i = 0; for my $dev_settings ( @{ $devJson->{settings} } ) { $output .= "[" . $i++ . "]id: $dev_settings->{id} \n"; - $output .= "name: $dev_settings->{name} "; + $output .= "name: $dev_settings->{name} \n"; if ( ref( $dev_settings->{value} ) eq 'ARRAY' || ref( $dev_settings->{value} ) eq 'HASH' ) { @@ -753,16 +753,7 @@ sub ErrorHandling { for my $dev_settings ( @{ $devJson->{abilities} } ) { $output .= "[" . $i++ . "]id: $dev_settings->{id} \n"; - $output .= "name: $dev_settings->{name} "; - - if ( ref( $dev_settings->{value} ) eq 'ARRAY' - || ref( $dev_settings->{value} ) eq 'HASH' ) - { - $output .= 'N/A \n'; - } - else { - $output .= "value: $dev_settings->{value} \n"; - } + $output .= "name: $dev_settings->{name} \n"; } $hash->{helper}{debug_device_output} = $output; diff --git a/FHEM/74_GardenaSmartDevice.pm b/FHEM/74_GardenaSmartDevice.pm index ad92993..6429842 100644 --- a/FHEM/74_GardenaSmartDevice.pm +++ b/FHEM/74_GardenaSmartDevice.pm @@ -7,6 +7,7 @@ # # Special thanks goes to comitters: # - Michael (mbrak) Thanks for Commandref +# - Christian (zife) Thanks for Commandref # - Matthias (Kenneth) Thanks for Wiki entry # - BioS Thanks for predefined start points Code # - fettgu Thanks for Debugging Irrigation Control data flow @@ -166,6 +167,7 @@ sub Initialize { $hash->{AttrList} = "readingValueLanguage:de,en " . "model:watering_computer,sensor,sensor2,mower,ic24,power,electronic_pressure_pump " + . "extendedState:0,1 " . "IODev " . $readingFnAttributes; $hash->{parseParams} = 1; @@ -204,12 +206,12 @@ sub Define { $hash->{helper}{_id} = ''; # IrrigationControl valve control max 6 - $hash->{helper}{schedules_paused_until_1_id} = ''; - $hash->{helper}{schedules_paused_until_2_id} = ''; - $hash->{helper}{schedules_paused_until_3_id} = ''; - $hash->{helper}{schedules_paused_until_4_id} = ''; - $hash->{helper}{schedules_paused_until_5_id} = ''; - $hash->{helper}{schedules_paused_until_6_id} = ''; + $hash->{helper}{schedules_paused_until_1_id} = ''; + $hash->{helper}{schedules_paused_until_2_id} = ''; + $hash->{helper}{schedules_paused_until_3_id} = ''; + $hash->{helper}{schedules_paused_until_4_id} = ''; + $hash->{helper}{schedules_paused_until_5_id} = ''; + $hash->{helper}{schedules_paused_until_6_id} = ''; CommandAttr( undef, "$name IODev $modules{GardenaSmartBridge}{defptr}{BRIDGE}->{NAME}" ) @@ -564,13 +566,24 @@ sub Set { 'manualOverride:slider,1,1,59 cancelOverride:noArg resumeSchedule:noArg stopSchedule manualButtonTime:slider,0,2,100' if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' ); - $list .= -'closeAllValves:noArg stopScheduleValve:selectnumbers,1,1,6,0,lin resumeScheduleValve:selectnumbers,1,1,6,0,lin manualDurationValve1:slider,1,1,90 manualDurationValve2:slider,1,1,90 manualDurationValve3:slider,1,1,90 manualDurationValve4:slider,1,1,90 manualDurationValve5:slider,1,1,90 manualDurationValve6:slider,1,1,90 cancelOverrideValve1:noArg cancelOverrideValve2:noArg cancelOverrideValve3:noArg cancelOverrideValve4:noArg cancelOverrideValve5:noArg cancelOverrideValve6:noArg' - if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ); $list .= 'manualOverride:slider,1,1,90 cancelOverride:noArg operating_mode:automatic,scheduled leakage_detection:watering,washing_machine,domestic_water_supply,off turn_on_pressure:slider,2,0.2,3.0,1 resetValveErrors:noArg' if ( AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' ); + $list .= +'closeAllValves:noArg resetValveErrors:noArg stopScheduleValve:select,'.ReadingsVal( $name, 'ic24-valves_connected', '1' ).' resumeScheduleValve:select,'.ReadingsVal( $name, 'ic24-valves_connected', '1' ) + if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ); + + foreach my $valve (split(',', ReadingsVal( $name, 'ic24-valves_connected', '1'))) { + $list .= ' manualDurationValve'.$valve.':slider,1,1,90 ' + if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ); + } + + foreach my $valve (split(',', ReadingsVal( $name, 'ic24-valves_connected', '1'))) { + $list .= ' cancelOverrideValve'.$valve.':noArg ' + if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ); + } + $list .= 'refresh:temperature,humidity' if ( AttrVal( $name, 'model', 'unknown' ) =~ /sensor.?/ ); @@ -650,6 +663,7 @@ sub WriteReadings { my $name = $hash->{NAME}; my $abilities = scalar( @{ $decode_json->{abilities} } ); my $settings = scalar( @{ $decode_json->{settings} } ); + my $scheduled_events = scalar( @{ $decode_json->{scheduled_events} } ); readingsBeginUpdate($hash); @@ -669,6 +683,7 @@ sub WriteReadings { 'watering' ) ) { + if ( $propertie->{name} eq 'button_config_time' ) { if ( $hash->{helper}{ $propertie->{name} . '_id' } ne $decode_json->{abilities}[$abilities]{id} ) @@ -693,9 +708,9 @@ sub WriteReadings { $hash, $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name}, - RigReadingsValue( $hash, $propertie->{value} ) + (defined ($propertie->{value} ) eq '') ? RigReadingsValue( $hash, 'n/a') : "".RigReadingsValue( $hash, $propertie->{value} ) # cast all data to string with "" ) - if ( defined( $propertie->{value} ) + if ( exists( $propertie->{value} ) && $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name} ne 'radio-quality' && $decode_json->{abilities}[$abilities]{name} . '-' @@ -710,13 +725,17 @@ sub WriteReadings { . $propertie->{name} ne 'humidity-humidity' && $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name} ne 'light-light' + && $decode_json->{abilities}[$abilities]{name} . '-' + . $propertie->{name} ne 'ic24-valves_connected' + && $decode_json->{abilities}[$abilities]{name} . '-' + . $propertie->{name} ne 'ic24-valves_master_config' && ref( $propertie->{value} ) ne "HASH" ); readingsBulkUpdateIfChanged( $hash, $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name}, - RigReadingsValue( $hash, $propertie->{value} ) + "".RigReadingsValue( $hash, $propertie->{value} ) # cast all data to string with "" ) if ( defined( $propertie->{value} ) @@ -743,7 +762,7 @@ sub WriteReadings { $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name} . '_timestamp', - Time::Piece->strptime( + "".Time::Piece->strptime( RigReadingsValue( $hash, $propertie->{timestamp} ), "%Y-%m-%d %H:%M:%S" )->strftime('%s') @@ -775,9 +794,10 @@ sub WriteReadings { . $propertie->{name} eq 'ic24-valves_master_config' ); if ( ref( $propertie->{value} ) eq "HASH" ) { + my $sub_state = 0; my $sub_value = 0; while ( my ( $r, $v ) = each %{ $propertie->{value} } ) { if ( ref( $v ) ne "HASH" ) { - readingsBulkUpdate( + readingsBulkUpdateIfChanged( $hash, $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name} . '_' @@ -786,7 +806,7 @@ sub WriteReadings { ); } else { while ( my ( $i_r, $i_v ) = each %{ $v } ) { - readingsBulkUpdate( + readingsBulkUpdateIfChanged( $hash, $decode_json->{abilities}[$abilities]{name} . '-' . $propertie->{name} . '_' @@ -797,12 +817,109 @@ sub WriteReadings { } } } + # ic24 and other watering devices calc irrigation left in sec + readingsBulkUpdateIfChanged( + $hash, + $decode_json->{abilities}[$abilities]{name} . '-' + . $propertie->{name} + . '_irrigation_left', + ( $propertie->{value}{duration} > 0 ) ? (Time::Piece::localtime->strptime( + RigReadingsValue($hash, $propertie->{timestamp}), "%Y-%m-%d %H:%M:%S") + + ($propertie->{value}{duration} + 3 ) - Time::Piece::localtime->new) : 0 + ) + if ( defined( $propertie->{value} ) + && $decode_json->{abilities}[$abilities]{name} eq 'watering' + ); } } $abilities--; } while ( $abilities >= 0 ); + + if ( + exists( $decode_json->{scheduled_events} ) + # && scalar ($decode_json->{scheduled_events} ) > 0 + && ref ($decode_json->{scheduled_events}) eq 'ARRAY' + && AttrVal( $name, 'model', 'unknown' ) !~ /sensor.?/ ) { + readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_events_count', + scalar( @{$decode_json->{scheduled_events} } ) ); + my $valve_id =1; my $event_id = 0; # ic24 [1..6] | wc, pump [1] + + ## + # validiere schedules + my @soll = ();my @ist=(); my @tmp_ist=(); + for my $cloud_schedules ( @{ $decode_json->{scheduled_events} } ) { + while ( my ( $r, $v ) = each %{ $cloud_schedules } ) { + push @soll, $v if $r eq 'id'; # cloud hat SOLL + } + } + + foreach my $dev_schedules ( sort keys %{ $hash->{READINGS} } ) { + my $dev_reading = ReadingsVal( $name, $dev_schedules, "error" ); + push @ist, $dev_reading if $dev_schedules =~ /schedule.*\d_id/; # push reading _id + push @ist, $1 if $dev_schedules =~ /schedule.*_(\d)_id/; # push readigs d from x_id + + Log3 $name, 5, "[DEBUG] $name - Schedule - Key ist : $dev_schedules "; + Log3 $name, 5, "[DEBUG] $name - Schedule - ID FOUND $dev_reading" if $dev_schedules =~ /schedule.*_\d_id/; # cloud hat SOLL + } + #Log3 $name, 5, "[DEBUG] Cloud:".Dumper(@soll) . "- Internal:". Dumper(@ist); + + ## delete only if cloud != (ist/2) + if ((scalar(@soll) != scalar(@ist/2) + && scalar(@soll) > 0 + && scalar(@ist) > 0) + || (scalar(@ist) eq 2 && scalar(@soll) eq 1 )){ + @tmp_ist = @ist; + while(my $element = shift(@soll)) { + my $schedule_step_int = 0; + + foreach my $sist (@tmp_ist) { + my $step = scalar(@tmp_ist) > 1 ? 2:1; + if ($element eq $sist){ + splice(@ist, $schedule_step_int, $step); # more than 2 items del them, otherwise 1 + } + $schedule_step_int += $step; + } + } + } + #Log3 $name, 5, "[DEBUG] $name - Schedule - Rest ". Dumper(@ist); + # delete only if count soll != count ist. cos the will be overwritten + if (scalar(@ist) > 0 + && scalar(@soll) != scalar(@ist/2) ){ + while (my $old_schedule_id = shift(@ist)) { + if (length($old_schedule_id) == 1) { + foreach (keys %{$hash->{READINGS}}) { + delete $hash->{READINGS}->{$_} if($_ =~ /scheduling-schedules_event_$old_schedule_id.*/); + } + }# fi + Log3 $name, 5, "[DEBUG] - $name : deletereading scheduling-schedules_event_$old_schedule_id.*" if length($old_schedule_id) == 1; + } + } + #### /validiere schedules + + for my $event_schedules ( @{ $decode_json->{scheduled_events} } ) { + $valve_id = $event_schedules->{valve_id} if ( exists($event_schedules->{valve_id} ) ); #ic24 + $event_id++; # event id + + while ( my ( $r, $v ) = each %{ $event_schedules } ) { + readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_event_' + . $event_id + #. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '') + . '_' + . $r, + $v) if (ref($v) ne 'HASH' ); + readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_event_' + . $event_id + #. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '') + . '_' + . $v->{type}, + join(',', @ { $v->{weekdays}}) ) if (ref($v) eq 'HASH' ); + }; + }; + + }; # fi scheduled_events + my $winter_mode; do { @@ -834,7 +951,16 @@ sub WriteReadings { readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_paused_until', $decode_json->{settings}[$settings]{value} ); } - + ##### + #ic24 schedules pause until + if ($decode_json->{settings}[$settings]{name} =~ /schedules_paused_until_?(\d)?$/) { + #my $ventil = substr($decode_json->{settings}[$settings]{name}, -1); # => 1 - 6 + # check if empty, clear scheduling-scheduled_watering_next_start_x + readingsBulkUpdateIfChanged( $hash, 'scheduling-'.$decode_json->{settings}[$settings]{name}, + $decode_json->{settings}[$settings]{value} ); + # CommandAttr( undef, $name . " scheduling-scheduled_watering_next_start_") if ($decode_json->{settings}[$settings]{value} eq '' ) + } +#TODO: Readings und Setter ?! # save electronid pressure pump settings as readings if ( $decode_json->{settings}[$settings]{name} eq 'operating_mode' || $decode_json->{settings}[$settings]{name} eq 'leakage_detection' @@ -844,7 +970,6 @@ sub WriteReadings { } # save winter mode as reading - if ( $decode_json->{settings}[$settings]{name} eq 'winter_mode' ) { readingsBulkUpdateIfChanged( $hash, 'winter_mode', $decode_json->{settings}[$settings]{value} ); @@ -852,6 +977,17 @@ sub WriteReadings { $winter_mode = $decode_json->{settings}[$settings]{value}; } } + + if ( defined( $decode_json->{settings}[$settings]{name} ) + && $decode_json->{settings}[$settings]{name} eq 'valve_names' + && ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY" ) { # or HASH ? + my @valves = @{$decode_json->{settings}[$settings]{value}}; + foreach my $valve( @valves ) { + #Log3 $name, 4, "GardenaSmartDevice ($name) valve_name $valve->{'name'}"; + readingsBulkUpdateIfChanged( $hash, 'valve-valve_name_'.$valve->{"id"}, + $valve->{"name"} ); + } + } if ( ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY" && $decode_json->{settings}[$settings]{name} eq 'starting_points' ) @@ -913,54 +1049,103 @@ sub setState { : 'offline' ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'mower' ); - #online state water control - # zeitplan -> dauert pausiert wenn 2038-01-18T00:00:00.000Z + # ic24 / wc / electronic pump - # watering-watering_timer_1_state idle | scheduled | manual - # watering-watering_timer_1_duration 0 in sec - # scheduling-scheduled_watering_next_start XXX - # scheduling-scheduled_watering_end | end < NOW && duration = 0 => abbruch manuell - # scheduling-schedules_paused_until + if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' + || AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' + || AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' ){ + my @opened_valves; + my $state_string = ''; my $nearst_irrigation = '2999-12-12 12:00'; + my $has_schedule = 0; my $longest_duration = 0; my $processed_item = ''; + my $error_type = 'ok'; + my @valves_connected = AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ? split(',', ReadingsVal( $name, 'ic24-valves_connected', '')) : '1'; - - # 1. Ventil geschlossen, Zeitplan pausiert. - # App zeigt: nichts (wenn vorher ein Zeitplan abgebrochen wurde, steht da "Unterbrochen xx:yy - zz:aa") - # 2. Ventil geschlossen, Zeitplan aktiv. - # App zeigt: "Nächste Bewässerung heute um xx:yy Uhr" (wenn vorher ein Zeitplan abgebrochen wurde, steht da vorher auch "Unterbrochen xx:yy - zz:aa") - # 3. Ventil manuell geoeffnet, späterer Zeitplan aktiv. - # Wird bewässert xx Minuten verbleibend" und "Nächste Bewässerung heute um xx:yy Uhr" - # 4. Ventil manuell geoeffnet, Zeitpläne deaktiviert. - # App zeigt: "Wird bewässert xx Minuten verbleibend" - if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' ){ - my $state_string = ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 ) =~ - m{\A[1-9]([0-9]+)?\z}xms - # offen - ? - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '' ) eq '' ) - # leer ( zeitplan aktiv ... ) - ? sprintf( (RigReadingsValue($hash, 'will be irrigated %.f minutes remaining.').' '.RigReadingsValue($hash, 'next watering: %s')), (ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 )/60), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '')) ) - # zeitplan pausiert - : - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '') eq '2038-01-18T00:00:00.000Z') - # pause bis dauerhaft - ? sprintf( (RigReadingsValue($hash, 'will be irrigated %.f minutes remaining.').' '.RigReadingsValue($hash , 'schedule permanently paused')), (ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 )/60) ) - # naechter termin - : sprintf( RigReadingsValue($hash , 'paused until %s'), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until', '')) ) - # zu - : - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '' ) eq '' ) - # zeitplan aktiv - ? sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash, 'next watering: %s')), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '') ) ) - # zeitplan pausiert + $has_schedule = 1 if ( ReadingsVal($name, 'scheduling-schedules_events_count', '') ne '' ); + for (@valves_connected){ # valves 1 or 1..6 + ## add to opened ventils, if watering active + push @opened_valves, $_ if ( ( ( ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) =~ m{\A[1-9]([0-9]+)?\z}xms ) ? $_ : 0 ) > 0 ); + ## set error type (pumpe required) + $error_type = ReadingsVal( $name, 'error-valve_error_'.$_.'_type', 'ok' ) if (ReadingsVal( $name, 'error-valve_error_'.$_.'_type', 'ok' ) ne 'ok'); + ## find longest irrigation duration + $longest_duration = ReadingsVal( $name, "watering-watering_timer_".$_."_irrigation_left", 0 ) if ( + ( ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) =~ m{\A[1-9]([0-9]+)?\z}xms + && ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) > 0 + && ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) > $longest_duration ) ); + + # y-m-d h:m + $processed_item = AttrVal( $name, 'model', 'unknown' ) eq 'ic24' + ? RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until_'.$_, '')) + : RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until', '')); + + Log3 $name, 5, "[DEBUG] - process: $processed_item"; + Log3 $name, 5, "[DEBUG] - next_start: ". ReadingsVal($name, 'scheduling-scheduled_watering_next_start', ''); # n/a RigReadingsValue( $hash, 'n/a') + # $nearst_irrigation = RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until_'.$_, '')) + if ( ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '') eq RigReadingsValue( $hash, 'n/a') ) { # non next start, schedules paused permanently or next schedule > 1 year; get nearst paused_until + Log3 $name, 5, "[DEBUG] - next_start: empty "; + Log3 $name, 5, "[DEBUG] - empty pro item ".Time::Piece->strptime( $processed_item, "%Y-%m-%d %H:%M:%S"); + Log3 $name, 5, "[DEBUG] - empty nearst ".Time::Piece->strptime( $nearst_irrigation, "%Y-%m-%d %H:%M:%S"); + $nearst_irrigation = $processed_item + if ( Time::Piece->strptime( $processed_item, "%Y-%m-%d %H:%M:%S") + < Time::Piece->strptime( $nearst_irrigation, "%Y-%m-%d %H:%M:%S") + && $has_schedule + && Time::Piece->strptime( $processed_item, "%Y-%m-%d %H:%M:%S") + > Time::Piece->new + ) + } else { + $nearst_irrigation = ReadingsVal($name, 'scheduling-scheduled_watering_next_start', ''); + } + Log3 $name, 5, "[DEBUG] - choosed nearst: $nearst_irrigation"; + + } # for + # override state 4 extendedstates + if ( AttrVal( $name, "extendedState", 0 ) == 1) { + if (scalar(@opened_valves) > 0){ + ## valve 1 will be ir.. 23 minutes remaining + for (@valves_connected){ + $state_string .= sprintf(RigReadingsValue($hash,'valve').' '.$_.' '.(RigReadingsValue($hash, 'watering. %.f minutes left') .'
'), (ReadingsVal( $name, 'watering-watering_timer_'.$_.'_duration', 0 )/60)); + } # /for + } else { + $state_string .= RigReadingsValue($hash, 'closed'); + } + $state_string .= ($has_schedule) ? sprintf( RigReadingsValue($hash, 'next watering: %s'), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-scheduled_watering_next_start', ''))) : sprintf( RigReadingsValue($hash, 'paused until %s') , $nearst_irrigation); + #TODO: Write state format for ventil 1-@valces_connected -> map ? + CommandAttr( undef, $name . ' stateFormat + { + + } + ' ) + if ( AttrVal( $name, 'stateFormat', 'none' ) eq 'none' ); + } else { + Log3 $name, 5, "[DEBUG] - Offene Ventile :".scalar(@opened_valves)." laengste bewaesserung: $longest_duration . hat Zeitplan: $has_schedule Naechster Zeitplan: $nearst_irrigation"; + $state_string = scalar(@opened_valves) > 0 + # offen + ? sprintf( (RigReadingsValue($hash, 'watering. %.f minutes left')), $longest_duration/60) + # zu + : + ( $has_schedule + && $nearst_irrigation ne '2999-12-12 12:00') + # zeitplan aktiv + # ? ( $nearst_irrigation eq '2038-01-18 00:00') sprintf( RigReadingsValue($hash, 'paused until %s') , $nearst_irrigation) + ? ( $nearst_irrigation eq RigReadingsValue( $hash, 'n/a') || $nearst_irrigation =~ '2038-01-18.*') + # dauerhaft pausiert + ? sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash , 'schedule permanently paused')) ) + # naechster zeutplan + : (ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '') eq RigReadingsValue($hash, 'n/a')) + ? sprintf( RigReadingsValue($hash, 'paused until %s') , $nearst_irrigation) + : sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash, 'next watering: %s')), $nearst_irrigation ) + # zeitplan pausiert : RigReadingsValue($hash, 'closed') - ; + ; # state offline | override $state_string = 'offline' if ($online_state eq 'offline'); - + $state_string = ( $error_type ne 'ok' ) ? $error_type : $state_string; + + } readingsBulkUpdate( $hash, 'state', RigReadingsValue( $hash, $state_string ) ); } + # Sensor / Sensor 2 if ( AttrVal( $name, 'model', 'unknown' ) =~ /sensor.?/ ) { my $state_string = ( ReadingsVal( $name, 'device_info-category', 'unknown' ) eq @@ -980,64 +1165,15 @@ sub setState { if ( ReadingsVal( $name, 'device_info-category', 'unknown' ) eq 'sensor' ); -# if ( $online_state eq 'offline') { -# readingsBulkUpdate( $hash, 'humidity-humidity', '-1' ); -# readingsBulkUpdate( $hash, 'ambient_temperature-temperature', '-1' ) if (ReadingsVal($name, 'device_info-category', 'unknown') eq 'sensor'); -# readingsBulkUpdate( $hash, 'light-light', '-1' ) if (ReadingsVal($name, 'device_info-category', 'unknown') eq 'sensor'); -# } #online state sensor I II readingsBulkUpdate( $hash, 'state', $online_state eq 'online' ? RigReadingsValue( $hash, $state_string) : RigReadingsValue( $hash, 'offline') ); } - readingsBulkUpdate( - $hash, 'state', - 'scheduled watering next start: ' - . ( - ReadingsVal( - $name, 'scheduling-scheduled_watering_next_start', - 'no timer' - ) - ) - ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ); - readingsBulkUpdate( $hash, 'state', ReadingsVal( $name, 'power-power_timer', 'no info from power-timer' ) ) if ( AttrVal( $name, 'model', 'unknown' ) eq 'power' ); - #electronic water pump - if ( AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' ) { # | ok | pump_not_filled (Pumpe nicht gefüllt) - my $state_string = ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 ) =~ - m{\A[1-9]([0-9]+)?\z}xms - # offen - ? - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '' ) eq '' ) - # leer ( zeitplan aktiv ... ) - ? sprintf( (RigReadingsValue($hash, 'will be irrigated %.f minutes remaining.').' '.RigReadingsValue($hash, 'next watering: %s')), (ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 )/60), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '')) ) - # zeitplan pausiert - : - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '') eq '2038-01-18T00:00:00.000Z') - # pause bis dauerhaft - ? sprintf( (RigReadingsValue($hash, 'will be irrigated %.f minutes remaining.').' '.RigReadingsValue($hash , 'schedule permanently paused')), (ReadingsVal( $name, 'watering-watering_timer_1_duration', 0 )/60) ) - # naechter termin - : sprintf( RigReadingsValue($hash , 'paused until %s'), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until', '')) ) - # zu - : - ( ReadingsVal($name, 'scheduling-schedules_paused_until', '' ) eq '' ) - # zeitplan aktiv - ? sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash, 'next watering: %s')), RigReadingsValue($hash, ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '') ) ) - # zeitplan pausiert - : RigReadingsValue($hash, 'closed') - ; - # state offline | override - $state_string = 'offline' if ($online_state eq 'offline'); - # check valv error, override state - my $error_type = ReadingsVal( $name, 'error-valve_error_1_type', 'ok' ); - $state_string = ( $error_type ne 'ok' ) ? $error_type : $state_string; - - readingsBulkUpdate( - $hash, 'state', RigReadingsValue( $hash, $state_string ) ); - } return; } @@ -1149,9 +1285,12 @@ sub ReadingLangGerman { 'awake' => 'Aufgewacht', 'schedule permanently paused' => 'Zeitplan dauerhaft pausiert', 'paused until %s' => 'pausiert bis %s', - 'will be irrigated %.f minutes remaining.'=> 'Wird bewässert. %.f Minuten verbleibend.', + 'watering. %.f minutes left' => 'Wird bewässert. %.f Minuten verbleibend.', 'next watering: %s' => 'Nächste Bewässerung: %s', + 'n/a' => 'nicht verfügbar', 'pump_not_filled' => 'Pumpe nicht gefüllt', + 'clean_fine_filter' => 'Filter reinigen', + 'concurrent_limit_reached' => 'Grenze gleichzeitig geöffneter Ventile erreicht', ); if ( @@ -1302,320 +1441,836 @@ sub SetPredefinedStartPoints { =item device =item summary Modul to control GardenaSmart Devices -=item summary_DE Modul zur Steuerung von GardenaSmartgeräten - +=item summary_DE Modul zur Steuerung von GardenaSmartgeräten =begin html

GardenaSmartDevice

- +
+