patch-fix_div_with_attributes #91
							
								
								
									
										3972
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3972
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -441,7 +441,9 @@ sub Set {
 | 
				
			|||||||
        return "usage: $cmd" if ( scalar( @{$aArg} ) != 2 );
 | 
					        return "usage: $cmd" if ( scalar( @{$aArg} ) != 2 );
 | 
				
			||||||
        my $new_helper       = $aArg->[0];
 | 
					        my $new_helper       = $aArg->[0];
 | 
				
			||||||
        my $new_helper_value = $aArg->[1];
 | 
					        my $new_helper_value = $aArg->[1];
 | 
				
			||||||
      Log3( $name, 5, "[DEBUG] - GardenaSmartBridge ($name) - override helper $new_helper with $new_helper_value");
 | 
					        Log3( $name, 5,
 | 
				
			||||||
 | 
					"[DEBUG] - GardenaSmartBridge ($name) - override helper $new_helper with $new_helper_value"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        $hash->{helper}{$new_helper} = $new_helper_value;
 | 
					        $hash->{helper}{$new_helper} = $new_helper_value;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
@@ -611,8 +613,7 @@ sub ErrorHandling {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
        $data =~ /Error/
 | 
					        $data =~ /Error/ && $data !~ /lastLonaErrorCode/
 | 
				
			||||||
        && $data !~ /lastLonaErrorCode/
 | 
					 | 
				
			||||||
        || (   defined($decode_json)
 | 
					        || (   defined($decode_json)
 | 
				
			||||||
            && ref($decode_json) eq 'HASH'
 | 
					            && ref($decode_json) eq 'HASH'
 | 
				
			||||||
            && defined( $decode_json->{errors} ) )
 | 
					            && defined( $decode_json->{errors} ) )
 | 
				
			||||||
@@ -1574,7 +1575,7 @@ sub DeletePassword {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.5.2",
 | 
					  "version": "v2.6.0",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
					    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -197,12 +197,12 @@ sub Define {
 | 
				
			|||||||
    $hash->{helper}{eco_mode_id}               = '';
 | 
					    $hash->{helper}{eco_mode_id}               = '';
 | 
				
			||||||
    $hash->{helper}{button_config_time_id}     = '';
 | 
					    $hash->{helper}{button_config_time_id}     = '';
 | 
				
			||||||
    $hash->{helper}{winter_mode_id}            = '';
 | 
					    $hash->{helper}{winter_mode_id}            = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Electroni Pressure Pump
 | 
					    # Electroni Pressure Pump
 | 
				
			||||||
    $hash->{helper}{operating_mode_id}    = '';
 | 
					    $hash->{helper}{operating_mode_id}    = '';
 | 
				
			||||||
    $hash->{helper}{leakage_detection_id} = '';
 | 
					    $hash->{helper}{leakage_detection_id} = '';
 | 
				
			||||||
    $hash->{helper}{turn_on_pressure_id}  = '';
 | 
					    $hash->{helper}{turn_on_pressure_id}  = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    $hash->{helper}{_id} = '';
 | 
					    $hash->{helper}{_id} = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # IrrigationControl valve control max 6
 | 
					    # IrrigationControl valve control max 6
 | 
				
			||||||
@@ -288,8 +288,10 @@ sub Set {
 | 
				
			|||||||
    my $mainboard_version =
 | 
					    my $mainboard_version =
 | 
				
			||||||
      ReadingsVal( $name, 'mower_type-mainboard_version', 0.0 );
 | 
					      ReadingsVal( $name, 'mower_type-mainboard_version', 0.0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my ($Sekunden, $Minuten, $Stunden, $Monatstag, $Monat,
 | 
					    my (
 | 
				
			||||||
        $Jahr, $Wochentag, $Jahrestag, $Sommerzeit) = localtime(time);
 | 
					        $Sekunden, $Minuten,   $Stunden,   $Monatstag, $Monat,
 | 
				
			||||||
 | 
					        $Jahr,     $Wochentag, $Jahrestag, $Sommerzeit
 | 
				
			||||||
 | 
					    ) = localtime(time);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $timezone_offset = $Sommerzeit ? 0 : ( Time::Piece->new )->tzoffset;
 | 
					    my $timezone_offset = $Sommerzeit ? 0 : ( Time::Piece->new )->tzoffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -487,8 +489,10 @@ sub Set {
 | 
				
			|||||||
    ### Watering_pressure_pump
 | 
					    ### Watering_pressure_pump
 | 
				
			||||||
    elsif ( lc $cmd eq 'operating_mode' ) {
 | 
					    elsif ( lc $cmd eq 'operating_mode' ) {
 | 
				
			||||||
        my $op_mode = $aArg->[0];
 | 
					        my $op_mode = $aArg->[0];
 | 
				
			||||||
      $payload = '"settings":{"name":"operating_mode",'
 | 
					        $payload =
 | 
				
			||||||
                 .'"value":"'.$op_mode.'",'
 | 
					            '"settings":{"name":"operating_mode",'
 | 
				
			||||||
 | 
					          . '"value":"'
 | 
				
			||||||
 | 
					          . $op_mode . '",'
 | 
				
			||||||
          . '"device":"'
 | 
					          . '"device":"'
 | 
				
			||||||
          . $hash->{DEVICEID} . '"}';
 | 
					          . $hash->{DEVICEID} . '"}';
 | 
				
			||||||
        $abilities  = 'watering_pressure_pump_settings';
 | 
					        $abilities  = 'watering_pressure_pump_settings';
 | 
				
			||||||
@@ -496,8 +500,10 @@ sub Set {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( lc $cmd eq 'leakage_detection' ) {
 | 
					    elsif ( lc $cmd eq 'leakage_detection' ) {
 | 
				
			||||||
        my $leakdetection_mode = $aArg->[0];
 | 
					        my $leakdetection_mode = $aArg->[0];
 | 
				
			||||||
      $payload = '"settings":{"name":"leakage_detection",'
 | 
					        $payload =
 | 
				
			||||||
                 .'"value":"'.$leakdetection_mode.'",'
 | 
					            '"settings":{"name":"leakage_detection",'
 | 
				
			||||||
 | 
					          . '"value":"'
 | 
				
			||||||
 | 
					          . $leakdetection_mode . '",'
 | 
				
			||||||
          . '"device":"'
 | 
					          . '"device":"'
 | 
				
			||||||
          . $hash->{DEVICEID} . '"}';
 | 
					          . $hash->{DEVICEID} . '"}';
 | 
				
			||||||
        $abilities  = 'watering_pressure_pump_settings';
 | 
					        $abilities  = 'watering_pressure_pump_settings';
 | 
				
			||||||
@@ -505,16 +511,17 @@ sub Set {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( lc $cmd eq 'turn_on_pressure' ) {
 | 
					    elsif ( lc $cmd eq 'turn_on_pressure' ) {
 | 
				
			||||||
        my $turnonpressure = $aArg->[0];
 | 
					        my $turnonpressure = $aArg->[0];
 | 
				
			||||||
      $payload = '"settings":{"name":"turn_on_pressure",'
 | 
					        $payload =
 | 
				
			||||||
                 .'"value":"'.$turnonpressure.'",'
 | 
					            '"settings":{"name":"turn_on_pressure",'
 | 
				
			||||||
 | 
					          . '"value":"'
 | 
				
			||||||
 | 
					          . $turnonpressure . '",'
 | 
				
			||||||
          . '"device":"'
 | 
					          . '"device":"'
 | 
				
			||||||
          . $hash->{DEVICEID} . '"}';
 | 
					          . $hash->{DEVICEID} . '"}';
 | 
				
			||||||
        $abilities  = 'watering_pressure_pump_settings';
 | 
					        $abilities  = 'watering_pressure_pump_settings';
 | 
				
			||||||
        $service_id = $hash->{helper}->{'turn_on_pressure_id'};
 | 
					        $service_id = $hash->{helper}->{'turn_on_pressure_id'};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    elsif ( lc $cmd eq 'resetvalveerrors' ) {
 | 
					    elsif ( lc $cmd eq 'resetvalveerrors' ) {
 | 
				
			||||||
      $payload = '"name":"reset_valve_errors",'
 | 
					        $payload   = '"name":"reset_valve_errors",' . ' "parameters": {}';
 | 
				
			||||||
                 .' "parameters": {}';
 | 
					 | 
				
			||||||
        $abilities = 'error';
 | 
					        $abilities = 'error';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -566,20 +573,28 @@ sub Set {
 | 
				
			|||||||
'manualOverride:slider,1,1,59 cancelOverride:noArg resumeSchedule:noArg stopSchedule manualButtonTime:slider,0,2,100 resetValveErrors:noArg'
 | 
					'manualOverride:slider,1,1,59 cancelOverride:noArg resumeSchedule:noArg stopSchedule manualButtonTime:slider,0,2,100 resetValveErrors:noArg'
 | 
				
			||||||
          if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
 | 
					          if ( AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $list .=
 | 
				
			||||||
        $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'
 | 
					'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' );
 | 
					          if ( AttrVal( $name, 'model', 'unknown' ) eq
 | 
				
			||||||
 | 
					            'electronic_pressure_pump' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $list .=
 | 
					        $list .=
 | 
				
			||||||
'closeAllValves:noArg resetValveErrors:noArg stopScheduleValve:select,'.ReadingsVal( $name, 'ic24-valves_connected', '1' ).' resumeScheduleValve:select,'.ReadingsVal( $name, 'ic24-valves_connected', '1' )
 | 
					'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' );
 | 
					          if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach my $valve (split(',', ReadingsVal( $name, 'ic24-valves_connected', '1'))) {
 | 
					        foreach my $valve (
 | 
				
			||||||
 | 
					            split( ',', ReadingsVal( $name, 'ic24-valves_connected', '1' ) ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            $list .= ' manualDurationValve' . $valve . ':slider,1,1,90 '
 | 
					            $list .= ' manualDurationValve' . $valve . ':slider,1,1,90 '
 | 
				
			||||||
              if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
 | 
					              if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach my $valve (split(',', ReadingsVal( $name, 'ic24-valves_connected', '1'))) {
 | 
					        foreach my $valve (
 | 
				
			||||||
 | 
					            split( ',', ReadingsVal( $name, 'ic24-valves_connected', '1' ) ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            $list .= ' cancelOverrideValve' . $valve . ':noArg '
 | 
					            $list .= ' cancelOverrideValve' . $valve . ':noArg '
 | 
				
			||||||
              if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
 | 
					              if ( AttrVal( $name, 'model', 'unknown' ) eq 'ic24' );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -708,7 +723,11 @@ sub WriteReadings {
 | 
				
			|||||||
                    $hash,
 | 
					                    $hash,
 | 
				
			||||||
                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
				
			||||||
                      . $propertie->{name},
 | 
					                      . $propertie->{name},
 | 
				
			||||||
                      (defined ($propertie->{value} ) eq '') ? RigReadingsValue( $hash, 'n/a') : "".RigReadingsValue( $hash, $propertie->{value} ) # cast all data to string with ""
 | 
					                    ( defined( $propertie->{value} ) eq '' )
 | 
				
			||||||
 | 
					                    ? RigReadingsValue( $hash, 'n/a' )
 | 
				
			||||||
 | 
					                    : ""
 | 
				
			||||||
 | 
					                      . RigReadingsValue( $hash,
 | 
				
			||||||
 | 
					                        $propertie->{value} )  # cast all data to string with ""
 | 
				
			||||||
                  )
 | 
					                  )
 | 
				
			||||||
                  if ( exists( $propertie->{value} )
 | 
					                  if ( exists( $propertie->{value} )
 | 
				
			||||||
                    && $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                    && $decode_json->{abilities}[$abilities]{name} . '-'
 | 
				
			||||||
@@ -735,7 +754,9 @@ sub WriteReadings {
 | 
				
			|||||||
                    $hash,
 | 
					                    $hash,
 | 
				
			||||||
                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
				
			||||||
                      . $propertie->{name},
 | 
					                      . $propertie->{name},
 | 
				
			||||||
                    "".RigReadingsValue( $hash, $propertie->{value} )  # cast all data to string with ""
 | 
					                    ""
 | 
				
			||||||
 | 
					                      . RigReadingsValue( $hash,
 | 
				
			||||||
 | 
					                        $propertie->{value} )  # cast all data to string with ""
 | 
				
			||||||
                  )
 | 
					                  )
 | 
				
			||||||
                  if (
 | 
					                  if (
 | 
				
			||||||
                    defined( $propertie->{value} )
 | 
					                    defined( $propertie->{value} )
 | 
				
			||||||
@@ -762,7 +783,8 @@ sub WriteReadings {
 | 
				
			|||||||
                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
				
			||||||
                      . $propertie->{name}
 | 
					                      . $propertie->{name}
 | 
				
			||||||
                      . '_timestamp',
 | 
					                      . '_timestamp',
 | 
				
			||||||
                    "".Time::Piece->strptime(
 | 
					                    ""
 | 
				
			||||||
 | 
					                      . Time::Piece->strptime(
 | 
				
			||||||
                        RigReadingsValue( $hash, $propertie->{timestamp} ),
 | 
					                        RigReadingsValue( $hash, $propertie->{timestamp} ),
 | 
				
			||||||
                        "%Y-%m-%d %H:%M:%S" )->strftime('%s')
 | 
					                        "%Y-%m-%d %H:%M:%S" )->strftime('%s')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -794,61 +816,82 @@ sub WriteReadings {
 | 
				
			|||||||
                    . $propertie->{name} eq 'ic24-valves_master_config' );
 | 
					                    . $propertie->{name} eq 'ic24-valves_master_config' );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if ( ref( $propertie->{value} ) eq "HASH" ) {
 | 
					                if ( ref( $propertie->{value} ) eq "HASH" ) {
 | 
				
			||||||
                    my $sub_state = 0; my $sub_value = 0;
 | 
					                    my $sub_state = 0;
 | 
				
			||||||
 | 
					                    my $sub_value = 0;
 | 
				
			||||||
                    while ( my ( $r, $v ) = each %{ $propertie->{value} } ) {
 | 
					                    while ( my ( $r, $v ) = each %{ $propertie->{value} } ) {
 | 
				
			||||||
                        if ( ref($v) ne "HASH" ) {
 | 
					                        if ( ref($v) ne "HASH" ) {
 | 
				
			||||||
                            readingsBulkUpdateIfChanged(
 | 
					                            readingsBulkUpdateIfChanged(
 | 
				
			||||||
                                $hash,
 | 
					                                $hash,
 | 
				
			||||||
                              $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                                $decode_json->{abilities}[$abilities]{name}
 | 
				
			||||||
 | 
					                                  . '-'
 | 
				
			||||||
                                  . $propertie->{name} . '_'
 | 
					                                  . $propertie->{name} . '_'
 | 
				
			||||||
                                  . $r,
 | 
					                                  . $r,
 | 
				
			||||||
                                RigReadingsValue( $hash, $v )
 | 
					                                RigReadingsValue( $hash, $v )
 | 
				
			||||||
                            );
 | 
					                            );
 | 
				
			||||||
                        } else {
 | 
					                        }
 | 
				
			||||||
 | 
					                        else {
 | 
				
			||||||
                            while ( my ( $i_r, $i_v ) = each %{$v} ) {
 | 
					                            while ( my ( $i_r, $i_v ) = each %{$v} ) {
 | 
				
			||||||
                                readingsBulkUpdateIfChanged(
 | 
					                                readingsBulkUpdateIfChanged(
 | 
				
			||||||
                                    $hash,
 | 
					                                    $hash,
 | 
				
			||||||
                              $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                                    $decode_json->{abilities}[$abilities]{name}
 | 
				
			||||||
 | 
					                                      . '-'
 | 
				
			||||||
                                      . $propertie->{name} . '_'
 | 
					                                      . $propertie->{name} . '_'
 | 
				
			||||||
                              . $r . '_' . $i_r,
 | 
					                                      . $r . '_'
 | 
				
			||||||
 | 
					                                      . $i_r,
 | 
				
			||||||
                                    RigReadingsValue( $hash, $i_v )
 | 
					                                    RigReadingsValue( $hash, $i_v )
 | 
				
			||||||
                                );
 | 
					                                );
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # ic24 and other watering devices calc irrigation left in sec
 | 
					                # ic24 and other watering devices calc irrigation left in sec
 | 
				
			||||||
                readingsBulkUpdateIfChanged(
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
                    $hash,
 | 
					                    $hash,
 | 
				
			||||||
                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
					                    $decode_json->{abilities}[$abilities]{name} . '-'
 | 
				
			||||||
                      . $propertie->{name}
 | 
					                      . $propertie->{name}
 | 
				
			||||||
                      . '_irrigation_left',
 | 
					                      . '_irrigation_left',
 | 
				
			||||||
                      ( $propertie->{value}{duration} > 0 ) ? (Time::Piece::localtime->strptime(
 | 
					                    ( $propertie->{value}{duration} > 0 )
 | 
				
			||||||
                        RigReadingsValue($hash, $propertie->{timestamp}), "%Y-%m-%d %H:%M:%S")
 | 
					                    ? (
 | 
				
			||||||
                        + ($propertie->{value}{duration} + 3 ) - Time::Piece::localtime->new) : 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} )
 | 
					                  if ( defined( $propertie->{value} )
 | 
				
			||||||
                    && $decode_json->{abilities}[$abilities]{name} eq 'watering'
 | 
					                    && $decode_json->{abilities}[$abilities]{name} eq
 | 
				
			||||||
                  );
 | 
					                    'watering' );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $abilities--;
 | 
					        $abilities--;
 | 
				
			||||||
    } while ( $abilities >= 0 );
 | 
					    } while ( $abilities >= 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
        exists( $decode_json->{scheduled_events} )
 | 
					        exists( $decode_json->{scheduled_events} )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #  && scalar ($decode_json->{scheduled_events} ) > 0
 | 
					        #  && scalar ($decode_json->{scheduled_events} ) > 0
 | 
				
			||||||
        && ref( $decode_json->{scheduled_events} ) eq 'ARRAY'
 | 
					        && ref( $decode_json->{scheduled_events} ) eq 'ARRAY'
 | 
				
			||||||
        && AttrVal( $name, 'model', 'unknown' ) !~ /sensor.?/ ) {
 | 
					        && 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]
 | 
					        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
 | 
					        # validiere schedules
 | 
				
			||||||
        my @soll = ();my @ist=(); my @tmp_ist=();
 | 
					        my @soll    = ();
 | 
				
			||||||
 | 
					        my @ist     = ();
 | 
				
			||||||
 | 
					        my @tmp_ist = ();
 | 
				
			||||||
        for my $cloud_schedules ( @{ $decode_json->{scheduled_events} } ) {
 | 
					        for my $cloud_schedules ( @{ $decode_json->{scheduled_events} } ) {
 | 
				
			||||||
            while ( my ( $r, $v ) = each %{$cloud_schedules} ) {
 | 
					            while ( my ( $r, $v ) = each %{$cloud_schedules} ) {
 | 
				
			||||||
                push @soll, $v if $r eq 'id';    # cloud hat  SOLL
 | 
					                push @soll, $v if $r eq 'id';    # cloud hat  SOLL
 | 
				
			||||||
@@ -857,19 +900,30 @@ sub WriteReadings {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        foreach my $dev_schedules ( sort keys %{ $hash->{READINGS} } ) {
 | 
					        foreach my $dev_schedules ( sort keys %{ $hash->{READINGS} } ) {
 | 
				
			||||||
            my $dev_reading = ReadingsVal( $name, $dev_schedules, "error" );
 | 
					            my $dev_reading = ReadingsVal( $name, $dev_schedules, "error" );
 | 
				
			||||||
          push @ist, $dev_reading if $dev_schedules =~ /schedule.*\d_id/; # push reading _id
 | 
					            push @ist, $dev_reading
 | 
				
			||||||
          push @ist, $1 if $dev_schedules =~ /schedule.*_(\d)_id/; # push readigs d from x_id
 | 
					              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,
 | 
				
			||||||
          Log3 $name, 5, "[DEBUG] $name - Schedule - ID FOUND $dev_reading" if $dev_schedules =~ /schedule.*_\d_id/; # cloud hat  SOLL
 | 
					              "[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);
 | 
					   #Log3 $name, 5, "[DEBUG] Cloud:".Dumper(@soll) . "- Internal:". Dumper(@ist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ## delete only if cloud != (ist/2)
 | 
					        ## delete only if cloud != (ist/2)
 | 
				
			||||||
        if ((scalar(@soll) != scalar(@ist/2)
 | 
					        if (
 | 
				
			||||||
 | 
					            (
 | 
				
			||||||
 | 
					                   scalar(@soll) != scalar( @ist / 2 )
 | 
				
			||||||
                && scalar(@soll) > 0
 | 
					                && scalar(@soll) > 0
 | 
				
			||||||
         && scalar(@ist) > 0)
 | 
					                && scalar(@ist) > 0
 | 
				
			||||||
         || (scalar(@ist) eq 2 && scalar(@soll) eq 1 )){
 | 
					            )
 | 
				
			||||||
 | 
					            || ( scalar(@ist) eq 2 && scalar(@soll) eq 1 )
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            @tmp_ist = @ist;
 | 
					            @tmp_ist = @ist;
 | 
				
			||||||
            while ( my $element = shift(@soll) ) {
 | 
					            while ( my $element = shift(@soll) ) {
 | 
				
			||||||
                my $schedule_step_int = 0;
 | 
					                my $schedule_step_int = 0;
 | 
				
			||||||
@@ -877,48 +931,61 @@ sub WriteReadings {
 | 
				
			|||||||
                foreach my $sist (@tmp_ist) {
 | 
					                foreach my $sist (@tmp_ist) {
 | 
				
			||||||
                    my $step = scalar(@tmp_ist) > 1 ? 2 : 1;
 | 
					                    my $step = scalar(@tmp_ist) > 1 ? 2 : 1;
 | 
				
			||||||
                    if ( $element eq $sist ) {
 | 
					                    if ( $element eq $sist ) {
 | 
				
			||||||
                splice(@ist, $schedule_step_int, $step); # more than 2 items del them, otherwise 1
 | 
					                        splice( @ist, $schedule_step_int, $step )
 | 
				
			||||||
 | 
					                          ;    # more than 2 items del them, otherwise 1
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $schedule_step_int += $step;
 | 
					                    $schedule_step_int += $step;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #Log3 $name, 5, "[DEBUG] $name - Schedule - Rest  ". Dumper(@ist);
 | 
					        #Log3 $name, 5, "[DEBUG] $name - Schedule - Rest  ". Dumper(@ist);
 | 
				
			||||||
        # delete only if count soll != count ist. cos the will be overwritten
 | 
					        # delete only if count soll != count ist. cos the will be overwritten
 | 
				
			||||||
        if (   scalar(@ist) > 0
 | 
					        if (   scalar(@ist) > 0
 | 
				
			||||||
          && scalar(@soll) != scalar(@ist/2) ){
 | 
					            && scalar(@soll) != scalar( @ist / 2 ) )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            while ( my $old_schedule_id = shift(@ist) ) {
 | 
					            while ( my $old_schedule_id = shift(@ist) ) {
 | 
				
			||||||
                if ( length($old_schedule_id) == 1 ) {
 | 
					                if ( length($old_schedule_id) == 1 ) {
 | 
				
			||||||
                    foreach ( keys %{ $hash->{READINGS} } ) {
 | 
					                    foreach ( keys %{ $hash->{READINGS} } ) {
 | 
				
			||||||
                delete $hash->{READINGS}->{$_} if($_ =~ /scheduling-schedules_event_$old_schedule_id.*/);
 | 
					                        delete $hash->{READINGS}->{$_}
 | 
				
			||||||
 | 
					                          if ( $_ =~
 | 
				
			||||||
 | 
					                            /scheduling-schedules_event_$old_schedule_id.*/ );
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }    # fi
 | 
					                }    # fi
 | 
				
			||||||
            Log3 $name, 5, "[DEBUG] - $name : deletereading scheduling-schedules_event_$old_schedule_id.*"  if length($old_schedule_id) == 1;
 | 
					                Log3 $name, 5,
 | 
				
			||||||
 | 
					"[DEBUG] - $name : deletereading scheduling-schedules_event_$old_schedule_id.*"
 | 
				
			||||||
 | 
					                  if length($old_schedule_id) == 1;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        #### /validiere schedules
 | 
					        #### /validiere schedules
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for my $event_schedules ( @{ $decode_json->{scheduled_events} } ) {
 | 
					        for my $event_schedules ( @{ $decode_json->{scheduled_events} } ) {
 | 
				
			||||||
          $valve_id = $event_schedules->{valve_id} if ( exists($event_schedules->{valve_id} ) ); #ic24
 | 
					            $valve_id = $event_schedules->{valve_id}
 | 
				
			||||||
 | 
					              if ( exists( $event_schedules->{valve_id} ) );    #ic24
 | 
				
			||||||
            $event_id++;                                        # event id
 | 
					            $event_id++;                                        # event id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while ( my ( $r, $v ) = each %{$event_schedules} ) {
 | 
					            while ( my ( $r, $v ) = each %{$event_schedules} ) {
 | 
				
			||||||
            readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_event_'
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
                                              . $event_id
 | 
					                    $hash, 'scheduling-schedules_event_' . $event_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '')
 | 
					#. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '')
 | 
				
			||||||
                      . '_'
 | 
					                      . '_'
 | 
				
			||||||
                      . $r,
 | 
					                      . $r,
 | 
				
			||||||
                                              $v) if (ref($v) ne 'HASH' );
 | 
					                    $v
 | 
				
			||||||
            readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_event_'
 | 
					                ) if ( ref($v) ne 'HASH' );
 | 
				
			||||||
                                              . $event_id
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
 | 
					                    $hash, 'scheduling-schedules_event_' . $event_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '')
 | 
					#. ( ReadingsVal($name,'error-valve_error_1_valve_id','') ne '' ? "_valve_$valve_id" : '')
 | 
				
			||||||
                      . '_'
 | 
					                      . '_'
 | 
				
			||||||
                      . $v->{type},
 | 
					                      . $v->{type},
 | 
				
			||||||
                                              join(',', @ { $v->{weekdays}}) ) if (ref($v) eq 'HASH' );
 | 
					                    join( ',', @{ $v->{weekdays} } )
 | 
				
			||||||
          };
 | 
					                ) if ( ref($v) eq 'HASH' );
 | 
				
			||||||
        };
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }; # fi scheduled_events
 | 
					    }
 | 
				
			||||||
 | 
					    ;    # fi scheduled_events
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    my $winter_mode;
 | 
					    my $winter_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -934,8 +1001,10 @@ sub WriteReadings {
 | 
				
			|||||||
                || $decode_json->{settings}[$settings]{name} eq 'eco_mode'
 | 
					                || $decode_json->{settings}[$settings]{name} eq 'eco_mode'
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'winter_mode'
 | 
					                || $decode_json->{settings}[$settings]{name} eq 'winter_mode'
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'operating_mode'
 | 
					                || $decode_json->{settings}[$settings]{name} eq 'operating_mode'
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'leakage_detection' 
 | 
					                || $decode_json->{settings}[$settings]{name} eq
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'turn_on_pressure' )
 | 
					                'leakage_detection'
 | 
				
			||||||
 | 
					                || $decode_json->{settings}[$settings]{name} eq
 | 
				
			||||||
 | 
					                'turn_on_pressure' )
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if ( $hash->{helper}
 | 
					            if ( $hash->{helper}
 | 
				
			||||||
@@ -946,29 +1015,49 @@ sub WriteReadings {
 | 
				
			|||||||
                  { $decode_json->{settings}[$settings]{name} . '_id' } =
 | 
					                  { $decode_json->{settings}[$settings]{name} . '_id' } =
 | 
				
			||||||
                  $decode_json->{settings}[$settings]{id};
 | 
					                  $decode_json->{settings}[$settings]{id};
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # check watering controler single schedules pause until
 | 
					            # check watering controler single schedules pause until
 | 
				
			||||||
            if ( $decode_json->{settings}[$settings]{name} eq 'schedules_paused_until' ) {
 | 
					            if ( $decode_json->{settings}[$settings]{name} eq
 | 
				
			||||||
              readingsBulkUpdateIfChanged( $hash, 'scheduling-schedules_paused_until',
 | 
					                'schedules_paused_until' )
 | 
				
			||||||
                    $decode_json->{settings}[$settings]{value} );
 | 
					            {
 | 
				
			||||||
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
 | 
					                    $hash,
 | 
				
			||||||
 | 
					                    'scheduling-schedules_paused_until',
 | 
				
			||||||
 | 
					                    $decode_json->{settings}[$settings]{value}
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            #####
 | 
					            #####
 | 
				
			||||||
            #ic24 schedules pause until
 | 
					            #ic24 schedules pause until
 | 
				
			||||||
            if ($decode_json->{settings}[$settings]{name} =~ /schedules_paused_until_?(\d)?$/) {
 | 
					            if ( $decode_json->{settings}[$settings]{name} =~
 | 
				
			||||||
 | 
					                /schedules_paused_until_?(\d)?$/ )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 #my $ventil = substr($decode_json->{settings}[$settings]{name}, -1); # => 1 - 6
 | 
					 #my $ventil = substr($decode_json->{settings}[$settings]{name}, -1); # => 1 - 6
 | 
				
			||||||
 # check if empty, clear scheduling-scheduled_watering_next_start_x
 | 
					 # check if empty, clear scheduling-scheduled_watering_next_start_x
 | 
				
			||||||
              readingsBulkUpdateIfChanged( $hash, 'scheduling-'.$decode_json->{settings}[$settings]{name},
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
                                  $decode_json->{settings}[$settings]{value} );
 | 
					                    $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 '' )
 | 
					# CommandAttr( undef, $name . " scheduling-scheduled_watering_next_start_")  if ($decode_json->{settings}[$settings]{value} eq '' )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            #TODO: Readings und Setter ?!
 | 
					            #TODO: Readings und Setter ?!
 | 
				
			||||||
            # save electronid pressure pump settings as readings
 | 
					            # save electronid pressure pump settings as readings
 | 
				
			||||||
            if (   $decode_json->{settings}[$settings]{name} eq 'operating_mode'
 | 
					            if (   $decode_json->{settings}[$settings]{name} eq 'operating_mode'
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'leakage_detection' 
 | 
					                || $decode_json->{settings}[$settings]{name} eq
 | 
				
			||||||
                || $decode_json->{settings}[$settings]{name} eq 'turn_on_pressure' ) {
 | 
					                'leakage_detection'
 | 
				
			||||||
                readingsBulkUpdateIfChanged( $hash, $decode_json->{settings}[$settings]{name},
 | 
					                || $decode_json->{settings}[$settings]{name} eq
 | 
				
			||||||
                    $decode_json->{settings}[$settings]{value} );
 | 
					                'turn_on_pressure' )
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                readingsBulkUpdateIfChanged(
 | 
				
			||||||
 | 
					                    $hash,
 | 
				
			||||||
 | 
					                    $decode_json->{settings}[$settings]{name},
 | 
				
			||||||
 | 
					                    $decode_json->{settings}[$settings]{value}
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # save winter mode as reading
 | 
					            # save winter mode as reading
 | 
				
			||||||
            if ( $decode_json->{settings}[$settings]{name} eq 'winter_mode' ) {
 | 
					            if ( $decode_json->{settings}[$settings]{name} eq 'winter_mode' ) {
 | 
				
			||||||
                readingsBulkUpdateIfChanged( $hash, 'winter_mode',
 | 
					                readingsBulkUpdateIfChanged( $hash, 'winter_mode',
 | 
				
			||||||
@@ -980,11 +1069,14 @@ sub WriteReadings {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (   defined( $decode_json->{settings}[$settings]{name} )
 | 
					        if (   defined( $decode_json->{settings}[$settings]{name} )
 | 
				
			||||||
            && $decode_json->{settings}[$settings]{name} eq 'valve_names'
 | 
					            && $decode_json->{settings}[$settings]{name} eq 'valve_names'
 | 
				
			||||||
           && ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY" ) { # or HASH ?
 | 
					            && ref( $decode_json->{settings}[$settings]{value} ) eq "ARRAY" )
 | 
				
			||||||
 | 
					        {    # or HASH ?
 | 
				
			||||||
            my @valves = @{ $decode_json->{settings}[$settings]{value} };
 | 
					            my @valves = @{ $decode_json->{settings}[$settings]{value} };
 | 
				
			||||||
            foreach my $valve (@valves) {
 | 
					            foreach my $valve (@valves) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      #Log3 $name, 4,  "GardenaSmartDevice ($name) valve_name $valve->{'name'}";
 | 
					      #Log3 $name, 4,  "GardenaSmartDevice ($name) valve_name $valve->{'name'}";
 | 
				
			||||||
              readingsBulkUpdateIfChanged( $hash, 'valve-valve_name_'.$valve->{"id"},
 | 
					                readingsBulkUpdateIfChanged( $hash,
 | 
				
			||||||
 | 
					                    'valve-valve_name_' . $valve->{"id"},
 | 
				
			||||||
                    $valve->{"name"} );
 | 
					                    $valve->{"name"} );
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -1053,46 +1145,106 @@ sub setState {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (   AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
 | 
					    if (   AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
 | 
				
			||||||
        || AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer'
 | 
					        || AttrVal( $name, 'model', 'unknown' ) eq 'watering_computer'
 | 
				
			||||||
        ||  AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' ){
 | 
					        || AttrVal( $name, 'model', 'unknown' ) eq 'electronic_pressure_pump' )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        my @opened_valves;
 | 
					        my @opened_valves;
 | 
				
			||||||
      my $state_string = ''; my $nearst_irrigation = '2999-12-12 12:00';
 | 
					        my $state_string      = '';
 | 
				
			||||||
      my $has_schedule = 0; my $longest_duration = 0; my $processed_item = '';
 | 
					        my $nearst_irrigation = '2999-12-12 12:00';
 | 
				
			||||||
 | 
					        my $has_schedule      = 0;
 | 
				
			||||||
 | 
					        my $longest_duration  = 0;
 | 
				
			||||||
 | 
					        my $processed_item    = '';
 | 
				
			||||||
        my $error_type        = 'ok';
 | 
					        my $error_type        = 'ok';
 | 
				
			||||||
      my @valves_connected = AttrVal( $name, 'model', 'unknown' ) eq 'ic24' ? split(',', ReadingsVal( $name, 'ic24-valves_connected', '')) : '1';
 | 
					        my @valves_connected =
 | 
				
			||||||
 | 
					          AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
 | 
				
			||||||
 | 
					          ? split( ',', ReadingsVal( $name, 'ic24-valves_connected', '' ) )
 | 
				
			||||||
 | 
					          : '1';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      $has_schedule = 1 if ( ReadingsVal($name, 'scheduling-schedules_events_count', '')  ne '' );
 | 
					        $has_schedule = 1
 | 
				
			||||||
 | 
					          if ( ReadingsVal( $name, 'scheduling-schedules_events_count', '' ) ne
 | 
				
			||||||
 | 
					            '' );
 | 
				
			||||||
        for (@valves_connected) {    # valves 1 or 1..6
 | 
					        for (@valves_connected) {    # valves 1 or 1..6
 | 
				
			||||||
            ## add to opened ventils, if watering active
 | 
					            ## 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 );
 | 
					            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)
 | 
					            ## set error type (pumpe required)
 | 
				
			||||||
        $error_type = ReadingsVal( $name, 'error-valve_error_'.$_.'_type', 'error' ) if (ReadingsVal( $name, 'error-valve_error_'.$_.'_type', 'error' ) ne 'ok');
 | 
					            $error_type =
 | 
				
			||||||
 | 
					              ReadingsVal( $name, 'error-valve_error_' . $_ . '_type', 'error' )
 | 
				
			||||||
 | 
					              if (
 | 
				
			||||||
 | 
					                ReadingsVal( $name, 'error-valve_error_' . $_ . '_type',
 | 
				
			||||||
 | 
					                    'error' ) ne 'ok'
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
            ## find longest irrigation duration
 | 
					            ## find longest irrigation duration
 | 
				
			||||||
        $longest_duration = ReadingsVal( $name, "watering-watering_timer_".$_."_irrigation_left", 0 ) if ( 
 | 
					            $longest_duration =
 | 
				
			||||||
              ( ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) =~ m{\A[1-9]([0-9]+)?\z}xms 
 | 
					              ReadingsVal( $name,
 | 
				
			||||||
              && ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) > 0 
 | 
					                "watering-watering_timer_" . $_ . "_irrigation_left", 0 )
 | 
				
			||||||
              && ReadingsVal( $name, "watering-watering_timer_".$_."_duration", 0 ) > $longest_duration ) );
 | 
					              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
 | 
					            # y-m-d h:m
 | 
				
			||||||
        $processed_item = AttrVal( $name, 'model', 'unknown' ) eq 'ic24' 
 | 
					            $processed_item =
 | 
				
			||||||
                              ? RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until_'.$_, '')) 
 | 
					              AttrVal( $name, 'model', 'unknown' ) eq 'ic24'
 | 
				
			||||||
                              : RigReadingsValue($hash, ReadingsVal($name, 'scheduling-schedules_paused_until', ''));
 | 
					              ? 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] - process: $processed_item";
 | 
				
			||||||
        Log3 $name, 5, "[DEBUG] - next_start: ". ReadingsVal($name, 'scheduling-scheduled_watering_next_start', ''); # n/a  RigReadingsValue( $hash, 'n/a')
 | 
					            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_'.$_, ''))
 | 
					             # $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
 | 
					            if (
 | 
				
			||||||
            Log3 $name, 5, "[DEBUG] - next_start: empty ";
 | 
					                ReadingsVal( $name, 'scheduling-scheduled_watering_next_start',
 | 
				
			||||||
            Log3 $name, 5, "[DEBUG] - empty pro item ".Time::Piece->strptime( $processed_item, "%Y-%m-%d %H:%M:%S");
 | 
					                    '' ) eq RigReadingsValue( $hash, 'n/a' )
 | 
				
			||||||
            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 {
 | 
					            { # non next start, schedules paused permanently or next schedule > 1 year; get nearst paused_until
 | 
				
			||||||
             $nearst_irrigation = ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '');
 | 
					                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";
 | 
					            Log3 $name, 5, "[DEBUG] - choosed nearst: $nearst_irrigation";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1102,47 +1254,110 @@ sub setState {
 | 
				
			|||||||
            if ( scalar(@opened_valves) > 0 ) {
 | 
					            if ( scalar(@opened_valves) > 0 ) {
 | 
				
			||||||
                ## valve 1 will be ir.. 23 minutes remaining
 | 
					                ## valve 1 will be ir.. 23 minutes remaining
 | 
				
			||||||
                for (@valves_connected) {
 | 
					                for (@valves_connected) {
 | 
				
			||||||
            $state_string .= sprintf(RigReadingsValue($hash,'valve').' '.$_.' '.(RigReadingsValue($hash, 'watering. %.f minutes left') .'</br>'), (ReadingsVal( $name, 'watering-watering_timer_'.$_.'_duration', 0 )/60));
 | 
					                    $state_string .= sprintf(
 | 
				
			||||||
 | 
					                        RigReadingsValue( $hash, 'valve' ) . ' '
 | 
				
			||||||
 | 
					                          . $_ . ' '
 | 
				
			||||||
 | 
					                          . (
 | 
				
			||||||
 | 
					                            RigReadingsValue( $hash,
 | 
				
			||||||
 | 
					                                'watering. %.f minutes left' )
 | 
				
			||||||
 | 
					                              . '</br>'
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        (
 | 
				
			||||||
 | 
					                            ReadingsVal( $name,
 | 
				
			||||||
 | 
					                                'watering-watering_timer_' . $_ . '_duration',
 | 
				
			||||||
 | 
					                                0 ) / 60
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
                }    # /for
 | 
					                }    # /for
 | 
				
			||||||
        } else {
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
                $state_string .= RigReadingsValue( $hash, 'closed' );
 | 
					                $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); 
 | 
					            $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 ?
 | 
					            #TODO: Write state format for ventil 1-@valces_connected  -> map ?
 | 
				
			||||||
        CommandAttr( undef, $name . ' stateFormat 
 | 
					            CommandAttr(
 | 
				
			||||||
 | 
					                undef, $name . ' stateFormat 
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            ' )
 | 
					            '
 | 
				
			||||||
            if ( AttrVal( $name, 'stateFormat', 'none' ) eq 'none' );
 | 
					            ) 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";
 | 
					        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
 | 
					            $state_string = scalar(@opened_valves) > 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              # offen
 | 
					              # offen
 | 
				
			||||||
          ? sprintf( (RigReadingsValue($hash, 'watering. %.f minutes left')), $longest_duration/60) 
 | 
					              ? sprintf(
 | 
				
			||||||
 | 
					                ( RigReadingsValue( $hash, 'watering. %.f minutes left' ) ),
 | 
				
			||||||
 | 
					                $longest_duration / 60
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              # zu
 | 
					              # zu
 | 
				
			||||||
          :
 | 
					              : (    $has_schedule
 | 
				
			||||||
            ( $has_schedule 
 | 
					 | 
				
			||||||
                  && $nearst_irrigation ne '2999-12-12 12:00' )
 | 
					                  && $nearst_irrigation ne '2999-12-12 12:00' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# zeitplan aktiv
 | 
					# zeitplan aktiv
 | 
				
			||||||
# ? ( $nearst_irrigation eq '2038-01-18 00:00')   sprintf( RigReadingsValue($hash, 'paused until %s') , $nearst_irrigation)
 | 
					# ? ( $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.*') 
 | 
					              ? (    $nearst_irrigation eq RigReadingsValue( $hash, 'n/a' )
 | 
				
			||||||
 | 
					                  || $nearst_irrigation =~ '2038-01-18.*' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              # dauerhaft pausiert
 | 
					              # dauerhaft pausiert
 | 
				
			||||||
                ? sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash , 'schedule permanently paused'))  )
 | 
					                  ? sprintf(
 | 
				
			||||||
 | 
					                      (
 | 
				
			||||||
 | 
					                          RigReadingsValue( $hash, 'closed' ) . '. '
 | 
				
			||||||
 | 
					                            . RigReadingsValue(
 | 
				
			||||||
 | 
					                              $hash, 'schedule permanently paused'
 | 
				
			||||||
 | 
					                            )
 | 
				
			||||||
 | 
					                      )
 | 
				
			||||||
 | 
					                  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                  # naechster zeutplan
 | 
					                  # naechster zeutplan
 | 
				
			||||||
                : (ReadingsVal($name, 'scheduling-scheduled_watering_next_start', '') eq RigReadingsValue($hash, 'n/a')) 
 | 
					                  : (
 | 
				
			||||||
                  ? sprintf( RigReadingsValue($hash, 'paused until %s') , $nearst_irrigation) 
 | 
					                      ReadingsVal( $name,
 | 
				
			||||||
                  : sprintf( (RigReadingsValue($hash, 'closed') .'. '.RigReadingsValue($hash, 'next watering: %s')), $nearst_irrigation )
 | 
					                          '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
 | 
					                  # zeitplan pausiert
 | 
				
			||||||
              : RigReadingsValue($hash, 'closed')
 | 
					              : RigReadingsValue( $hash, 'closed' );
 | 
				
			||||||
        ;
 | 
					
 | 
				
			||||||
            # state offline | override
 | 
					            # state offline | override
 | 
				
			||||||
            $state_string = 'offline' if ( $online_state eq 'offline' );
 | 
					            $state_string = 'offline' if ( $online_state eq 'offline' );
 | 
				
			||||||
      $state_string = ( $error_type ne 'ok' ) ? $error_type : $state_string;
 | 
					            $state_string =
 | 
				
			||||||
 | 
					              ( $error_type ne 'ok' ) ? $error_type : $state_string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      readingsBulkUpdate(
 | 
					        readingsBulkUpdate( $hash, 'state',
 | 
				
			||||||
        $hash, 'state',  RigReadingsValue( $hash, $state_string ) );
 | 
					            RigReadingsValue( $hash, $state_string ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Sensor / Sensor 2
 | 
					    # Sensor / Sensor 2
 | 
				
			||||||
@@ -1167,7 +1382,9 @@ sub setState {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        #online state sensor I II
 | 
					        #online state sensor I II
 | 
				
			||||||
        readingsBulkUpdate( $hash, 'state',
 | 
					        readingsBulkUpdate( $hash, 'state',
 | 
				
			||||||
            $online_state eq 'online' ? RigReadingsValue( $hash, $state_string) : RigReadingsValue( $hash, 'offline') );
 | 
					            $online_state eq 'online'
 | 
				
			||||||
 | 
					            ? RigReadingsValue( $hash, $state_string )
 | 
				
			||||||
 | 
					            : RigReadingsValue( $hash, 'offline' ) );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    readingsBulkUpdate( $hash, 'state',
 | 
					    readingsBulkUpdate( $hash, 'state',
 | 
				
			||||||
@@ -1197,7 +1414,8 @@ sub ReadingLangGerman {
 | 
				
			|||||||
        'parked_timer'         => 'geparkt nach Zeitplan',
 | 
					        'parked_timer'         => 'geparkt nach Zeitplan',
 | 
				
			||||||
        'parked_park_selected' => 'geparkt',
 | 
					        'parked_park_selected' => 'geparkt',
 | 
				
			||||||
        'off_disabled'         => 'der Mäher ist ausgeschaltet',
 | 
					        'off_disabled'         => 'der Mäher ist ausgeschaltet',
 | 
				
			||||||
        'off_hatch_open'                 => 'deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich',
 | 
					        'off_hatch_open'       =>
 | 
				
			||||||
 | 
					          'deaktiviert. Abdeckung ist offen oder PIN-Code erforderlich',
 | 
				
			||||||
        'unknown'           => 'unbekannter Status',
 | 
					        'unknown'           => 'unbekannter Status',
 | 
				
			||||||
        'error'             => 'Fehler',
 | 
					        'error'             => 'Fehler',
 | 
				
			||||||
        'error_at_power_up' => 'Neustart ...',
 | 
					        'error_at_power_up' => 'Neustart ...',
 | 
				
			||||||
@@ -1239,8 +1457,10 @@ sub ReadingLangGerman {
 | 
				
			|||||||
        'guide_2_not_found'              => 'SK 2 nicht gefunden',
 | 
					        'guide_2_not_found'              => 'SK 2 nicht gefunden',
 | 
				
			||||||
        'guide_3_not_found'              => 'SK 3 nicht gefunden',
 | 
					        'guide_3_not_found'              => 'SK 3 nicht gefunden',
 | 
				
			||||||
        'difficult_finding_home'         => 'Problem die Ladestation zu finden',
 | 
					        'difficult_finding_home'         => 'Problem die Ladestation zu finden',
 | 
				
			||||||
        'guide_calibration_accomplished' => 'Kalibrierung des Suchkabels beendet',
 | 
					        'guide_calibration_accomplished' =>
 | 
				
			||||||
        'guide_calibration_failed'       => 'Kalibrierung des Suchkabels fehlgeschlagen',
 | 
					          'Kalibrierung des Suchkabels beendet',
 | 
				
			||||||
 | 
					        'guide_calibration_failed' =>
 | 
				
			||||||
 | 
					          'Kalibrierung des Suchkabels fehlgeschlagen',
 | 
				
			||||||
        'temporary_battery_problem' => 'kurzzeitiges Batterieproblem',
 | 
					        'temporary_battery_problem' => 'kurzzeitiges Batterieproblem',
 | 
				
			||||||
        'battery_problem'           => 'Batterieproblem',
 | 
					        'battery_problem'           => 'Batterieproblem',
 | 
				
			||||||
        'alarm_mower_switched_off'  => 'Alarm! Mäher ausgeschalten',
 | 
					        'alarm_mower_switched_off'  => 'Alarm! Mäher ausgeschalten',
 | 
				
			||||||
@@ -1285,13 +1505,16 @@ sub ReadingLangGerman {
 | 
				
			|||||||
        'awake'                       => 'Aufgewacht',
 | 
					        'awake'                       => 'Aufgewacht',
 | 
				
			||||||
        'schedule permanently paused' => 'Zeitplan dauerhaft pausiert',
 | 
					        'schedule permanently paused' => 'Zeitplan dauerhaft pausiert',
 | 
				
			||||||
        'paused until %s'             => 'pausiert bis %s',
 | 
					        'paused until %s'             => 'pausiert bis %s',
 | 
				
			||||||
        'watering. %.f minutes left'     => 'Wird bewässert. %.f Minuten verbleibend.',
 | 
					        'watering. %.f minutes left'  =>
 | 
				
			||||||
 | 
					          'Wird bewässert. %.f Minuten verbleibend.',
 | 
				
			||||||
        'next watering: %s'        => 'Nächste Bewässerung: %s',
 | 
					        'next watering: %s'        => 'Nächste Bewässerung: %s',
 | 
				
			||||||
        'n/a'                      => 'nicht verfügbar',
 | 
					        'n/a'                      => 'nicht verfügbar',
 | 
				
			||||||
        'pump_not_filled'          => 'Pumpe nicht gefüllt',
 | 
					        'pump_not_filled'          => 'Pumpe nicht gefüllt',
 | 
				
			||||||
        'clean_fine_filter'        => 'Filter reinigen',
 | 
					        'clean_fine_filter'        => 'Filter reinigen',
 | 
				
			||||||
        'concurrent_limit_reached'       => 'Grenze gleichzeitig geöffneter Ventile erreicht',
 | 
					        'concurrent_limit_reached' =>
 | 
				
			||||||
        'low_battery_prevents_starting'  => 'Niedrieger Batteriestand verhindert Bewässerung',
 | 
					          'Grenze gleichzeitig geöffneter Ventile erreicht',
 | 
				
			||||||
 | 
					        'low_battery_prevents_starting' =>
 | 
				
			||||||
 | 
					          'Niedrieger Batteriestand verhindert Bewässerung',
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
@@ -2455,7 +2678,7 @@ sub SetPredefinedStartPoints {
 | 
				
			|||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "release_status": "stable",
 | 
					  "release_status": "stable",
 | 
				
			||||||
  "license": "GPL_2",
 | 
					  "license": "GPL_2",
 | 
				
			||||||
  "version": "v2.5.7",
 | 
					  "version": "v2.6.0",
 | 
				
			||||||
  "author": [
 | 
					  "author": [
 | 
				
			||||||
    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
					    "Marko Oldenburg <fhemdevelopment@cooltux.net>"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
UPD 2022-07-21_19:43:48 49634 FHEM/73_GardenaSmartBridge.pm
 | 
					UPD 2023-01-10_09:49:28 49646 FHEM/73_GardenaSmartBridge.pm
 | 
				
			||||||
UPD 2022-09-18_08:52:23 122934 FHEM/74_GardenaSmartDevice.pm
 | 
					UPD 2023-01-10_09:49:45 126305 FHEM/74_GardenaSmartDevice.pm
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								hooks/commit-msg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								hooks/commit-msg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# An example hook script to check the commit log message.
 | 
				
			||||||
 | 
					# Called by "git commit" with one argument, the name of the file
 | 
				
			||||||
 | 
					# that has the commit message.  The hook should exit with non-zero
 | 
				
			||||||
 | 
					# status after issuing an appropriate message if it wants to stop the
 | 
				
			||||||
 | 
					# commit.  The hook is allowed to edit the commit message file.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# To enable this hook, rename this file to "commit-msg".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Uncomment the below to add a Signed-off-by line to the message.
 | 
				
			||||||
 | 
					# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
 | 
				
			||||||
 | 
					# hook is more suited to it.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
 | 
				
			||||||
 | 
					# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This example catches duplicate Signed-off-by lines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					commit_msg=$(cat "${1:?Missing commit message file}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "" = "$(grep '^Signed-off-by: ' "$1" |
 | 
				
			||||||
 | 
						 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
 | 
				
			||||||
 | 
						echo >&2 Duplicate Signed-off-by lines.
 | 
				
			||||||
 | 
						exit 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ! echo "$commit_msg" | grep -Eq "^(build|chore|ci|docs|feat|feat!|fix|perf|refactor|revert|style|test)(\(.+\))?: .*$" ; then 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  echo "Invalid commit message" 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    exit 1 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fi 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo "Commit message is valid!"
 | 
				
			||||||
							
								
								
									
										18
									
								
								hooks/post-commit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								hooks/post-commit
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					set -eu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# destination of the final changelog file
 | 
				
			||||||
 | 
					OUTPUT_FILE=CHANGELOG.md
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# generate the changelog
 | 
				
			||||||
 | 
					git --no-pager log --no-merges --format="### %s%d%n>%aD%n%n>Author: %aN (%aE)%n%n>Commiter: %cN (%cE)%n%n%b%n%N%n" > $OUTPUT_FILE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# prevent recursion!
 | 
				
			||||||
 | 
					# since a 'commit --amend' will trigger the post-commit script again
 | 
				
			||||||
 | 
					# we have to check if the changelog file has changed or not
 | 
				
			||||||
 | 
					res=$(git status --porcelain | grep -c ".\$OUTPUT_FILE$")
 | 
				
			||||||
 | 
					if [ "$res" -gt 0 ]; then
 | 
				
			||||||
 | 
					  git add $OUTPUT_FILE
 | 
				
			||||||
 | 
					  git commit --amend
 | 
				
			||||||
 | 
					  echo "Populated Changelog in $OUTPUT_FILE"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
		Reference in New Issue
	
	Block a user