mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-24 02:59:22 +00:00
98_TRAFFIC: v1.3.4, fixed DbLog_SplitFn, misc improvements
git-svn-id: https://svn.fhem.de/fhem/trunk@16003 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
3ef5f2823b
commit
26be5b2095
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- bugfix: 98_TRAFFIC: v1.3.4, fixed DbLog_SplitFn, misc improvements
|
||||||
- change: 72_FB_CALLMONITOR: reverse search provider klicktel.de is
|
- change: 72_FB_CALLMONITOR: reverse search provider klicktel.de is
|
||||||
DEPRECATED and will be removed in a future
|
DEPRECATED and will be removed in a future
|
||||||
release. please use dasoertliche.de instead.
|
release. please use dasoertliche.de instead.
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
# 2017-04-21 added buttons to save current map settings, renamed attribute GoogleMapsLocation to GoogleMapsCenter
|
# 2017-04-21 added buttons to save current map settings, renamed attribute GoogleMapsLocation to GoogleMapsCenter
|
||||||
# 2017-04-22 v1.3.2 stroke supports weight and opacity, minor fixes
|
# 2017-04-22 v1.3.2 stroke supports weight and opacity, minor fixes
|
||||||
# 2017-12-51 v1.3.3 catch JSON decode issue, addedn Dbog_splitFn, added reading summary, new attr GoogleMapsFixedMap, net attr alternatives, new reading alternatives, alternatives, lighter&thinner on map
|
# 2017-12-51 v1.3.3 catch JSON decode issue, addedn Dbog_splitFn, added reading summary, new attr GoogleMapsFixedMap, net attr alternatives, new reading alternatives, alternatives, lighter&thinner on map
|
||||||
|
# 2018-01-26 v1.3.4 fixed Dbog_splitFn, improved exception handling
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
@ -59,18 +60,18 @@ use JSON;
|
|||||||
die "MIME::Base64 missing!" unless(eval{require MIME::Base64});
|
die "MIME::Base64 missing!" unless(eval{require MIME::Base64});
|
||||||
die "JSON missing!" unless(eval{require JSON});
|
die "JSON missing!" unless(eval{require JSON});
|
||||||
|
|
||||||
|
|
||||||
sub TRAFFIC_Initialize($);
|
sub TRAFFIC_Initialize($);
|
||||||
sub TRAFFIC_Define($$);
|
sub TRAFFIC_Define($$);
|
||||||
sub TRAFFIC_Undef($$);
|
sub TRAFFIC_Undef($$);
|
||||||
sub TRAFFIC_Set($@);
|
sub TRAFFIC_Set($@);
|
||||||
sub TRAFFIC_Attr(@);
|
sub TRAFFIC_Attr(@);
|
||||||
sub TRAFFIC_GetUpdate($);
|
sub TRAFFIC_GetUpdate($);
|
||||||
|
sub TRAFFIC_DbLog_split;
|
||||||
|
|
||||||
my %TRcmds = (
|
my %TRcmds = (
|
||||||
'update' => 'noArg',
|
'update' => 'noArg',
|
||||||
);
|
);
|
||||||
my $TRVersion = '1.3.3';
|
my $TRVersion = '1.3.4';
|
||||||
|
|
||||||
sub TRAFFIC_Initialize($){
|
sub TRAFFIC_Initialize($){
|
||||||
|
|
||||||
@ -88,8 +89,8 @@ sub TRAFFIC_Initialize($){
|
|||||||
$data{FWEXT}{"/TRAFFIC"}{FUNC} = "TRAFFIC";
|
$data{FWEXT}{"/TRAFFIC"}{FUNC} = "TRAFFIC";
|
||||||
$data{FWEXT}{"/TRAFFIC"}{FORKABLE} = 1;
|
$data{FWEXT}{"/TRAFFIC"}{FORKABLE} = 1;
|
||||||
|
|
||||||
$hash->{FW_detailFn} = "TRAFFIC_fhemwebFn";
|
$hash->{FW_detailFn} = "TRAFFIC_fhemwebFn";
|
||||||
$hash->{DbLog_splitFn} = "X_DbLog_split";
|
$hash->{DbLog_splitFn} = "TRAFFIC_DbLog_split";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,14 +521,14 @@ sub TRAFFIC_DoUpdate(){
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my ($sec,$min,$hour,$dayn,$month,$year,$wday,$yday,$isdst) = localtime(time);
|
my ($sec,$min,$hour,$dayn,$month,$year,$wday,$yday,$isdst) = localtime(time);
|
||||||
|
|
||||||
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_DoUpdate start";
|
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC DoUpdate start";
|
||||||
|
|
||||||
if ( $hash->{INTERVAL}) {
|
if ( $hash->{INTERVAL}) {
|
||||||
RemoveInternalTimer ($hash);
|
RemoveInternalTimer ($hash);
|
||||||
my $nextTrigger = gettimeofday() + $hash->{INTERVAL};
|
my $nextTrigger = gettimeofday() + $hash->{INTERVAL};
|
||||||
$hash->{TRIGGERTIME} = $nextTrigger;
|
$hash->{TRIGGERTIME} = $nextTrigger;
|
||||||
$hash->{TRIGGERTIME_FMT} = FmtDateTime($nextTrigger);
|
$hash->{TRIGGERTIME_FMT} = FmtDateTime($nextTrigger);
|
||||||
InternalTimer($nextTrigger, "TRAFFIC_DoUpdate", $hash, 0);
|
InternalTimer($nextTrigger, "TRAFFIC_StartUpdate", $hash, 0);
|
||||||
Log3 $hash, 4, "TRAFFIC: ($name) internal interval timer set to call GetUpdate again in " . int($hash->{INTERVAL}). " seconds";
|
Log3 $hash, 4, "TRAFFIC: ($name) internal interval timer set to call GetUpdate again in " . int($hash->{INTERVAL}). " seconds";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,7 +590,6 @@ sub TRAFFIC_DoUpdate(){
|
|||||||
Log3 $hash, 1, "TRAFFIC: ($name) decode_json on googles return failed, cant continue";
|
Log3 $hash, 1, "TRAFFIC: ($name) decode_json on googles return failed, cant continue";
|
||||||
Log3 $hash, 5, "TRAFFIC: ($name) received: ".Dumper($body->decoded_content);
|
Log3 $hash, 5, "TRAFFIC: ($name) received: ".Dumper($body->decoded_content);
|
||||||
my %errorReturn = ('status' => 'API error','action' => 'retry');
|
my %errorReturn = ('status' => 'API error','action' => 'retry');
|
||||||
#fixme: handle this and schedule a retry
|
|
||||||
return "$name;;;$direction;;;".encode_json(\%errorReturn);
|
return "$name;;;$direction;;;".encode_json(\%errorReturn);
|
||||||
};
|
};
|
||||||
my $json = decode_json($body->decoded_content);
|
my $json = decode_json($body->decoded_content);
|
||||||
@ -658,8 +658,8 @@ sub TRAFFIC_DoUpdate(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Log3 $hash, 5, "TRAFFIC: ($name) returning from TRAFFIC_DoUpdate: ".encode_json($returnJSON);
|
Log3 $hash, 5, "TRAFFIC: ($name) returning from TRAFFIC DoUpdate: ".encode_json($returnJSON);
|
||||||
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_DoUpdate done";
|
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC DoUpdate done";
|
||||||
return "$name;;;$direction;;;".encode_json($returnJSON);
|
return "$name;;;$direction;;;".encode_json($returnJSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,18 +673,19 @@ sub TRAFFIC_FinishUpdate($){
|
|||||||
my $json = decode_json($rawJson);
|
my $json = decode_json($rawJson);
|
||||||
|
|
||||||
# before we update anything, check if the status contains error, if yes -> retry
|
# before we update anything, check if the status contains error, if yes -> retry
|
||||||
if(defined($json->{'status'}) && $json->{'status'} =~ m/error/){
|
if(defined($json->{'status'}) && $json->{'status'} =~ m/error/i){ # this handles potential JSON decode issues and retries
|
||||||
if ($json->{'action'} eq 'retry'){
|
if ($json->{'action'} eq 'retry'){
|
||||||
Log3 $hash, 1, "TRAFFIC: ($name) TRAFFIC_doUpdate returned an error \"".$json->{'status'}. "\" will schedule a retry in 5 seconds";
|
Log3 $hash, 1, "TRAFFIC: ($name) TRAFFIC doUpdate returned an error \"".$json->{'status'}. "\" will schedule a retry in 5 seconds";
|
||||||
RemoveInternalTimer ($hash);
|
RemoveInternalTimer ($hash);
|
||||||
my $nextTrigger = gettimeofday() + 5;
|
my $nextTrigger = gettimeofday() + 5;
|
||||||
$hash->{TRIGGERTIME} = $nextTrigger;
|
$hash->{TRIGGERTIME} = $nextTrigger;
|
||||||
$hash->{TRIGGERTIME_FMT} = FmtDateTime($nextTrigger);
|
$hash->{TRIGGERTIME_FMT} = FmtDateTime($nextTrigger);
|
||||||
InternalTimer($nextTrigger, "TRAFFIC_DoUpdate", $hash, 0);
|
InternalTimer($nextTrigger, "TRAFFIC_StartUpdate", $hash, 0);
|
||||||
}else{
|
}else{
|
||||||
Log3 $hash, 1, "TRAFFIC: ($name) TRAFFIC_doUpdate returned an error: ".$json->{'status'};
|
Log3 $hash, 1, "TRAFFIC: ($name) TRAFFIC doUpdate returned an error: ".$json->{'status'};
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
|
}else{ #JSON decode did not return an error, lets update the device
|
||||||
|
|
||||||
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_FinishUpdate start";
|
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_FinishUpdate start";
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
@ -710,10 +711,6 @@ sub TRAFFIC_FinishUpdate($){
|
|||||||
readingsBulkUpdate($hash,$readingName,$readings->{$readingName});
|
readingsBulkUpdate($hash,$readingName,$readings->{$readingName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defined($json->{'READINGS'}->{'status'}) && $json->{'READINGS'}->{'status'} eq 'UNKNOWN_ERROR'){ # UNKNOWN_ERROR indicates a directions request could not be processed due to a server error. The request may succeed if you try again.
|
|
||||||
InternalTimer(gettimeofday() + 3, "TRAFFIC_StartUpdate", $hash, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(my $stateReading = AttrVal($name,"stateReading",undef)){
|
if(my $stateReading = AttrVal($name,"stateReading",undef)){
|
||||||
Log3 $hash, 5, "TRAFFIC: ($name) stateReading defined, override state";
|
Log3 $hash, 5, "TRAFFIC: ($name) stateReading defined, override state";
|
||||||
@ -724,6 +721,15 @@ sub TRAFFIC_FinishUpdate($){
|
|||||||
Log3 $hash, 1, "TRAFFIC: ($name) stateReading $stateReading not found";
|
Log3 $hash, 1, "TRAFFIC: ($name) stateReading $stateReading not found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# if Google returned an error, we gonna try again in 3 seconds
|
||||||
|
if(defined($json->{'READINGS'}->{'status'}) && $json->{'READINGS'}->{'status'} =~ m/error/i){ # UNKNOWN_ERROR indicates a directions request could not be processed due to a server error. The request may succeed if you try again.
|
||||||
|
Log3 $hash, 1, "TRAFFIC: ($name) auto-retry as Google returned an error: ".$json->{'READINGS'}->{'status'};
|
||||||
|
InternalTimer(gettimeofday() + 3, "TRAFFIC_StartUpdate", $hash, 0);
|
||||||
|
}elsif(defined($hash->{READINGS}->{'error_message'})){
|
||||||
|
Log3 $hash, 3, "TRAFFIC: ($name) removing reading error_message, status: ".$json->{'READINGS'}->{'status'};
|
||||||
|
fhem("deletereading $name error_message");
|
||||||
|
}
|
||||||
|
|
||||||
readingsEndUpdate($hash, $dotrigger);
|
readingsEndUpdate($hash, $dotrigger);
|
||||||
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_FinishUpdate done";
|
Log3 $hash, 4, "TRAFFIC: ($name) TRAFFIC_FinishUpdate done";
|
||||||
Log3 $hash, 5, "TRAFFIC: ($name) Helper: ".Dumper($hash->{helper});
|
Log3 $hash, 5, "TRAFFIC: ($name) Helper: ".Dumper($hash->{helper});
|
||||||
@ -748,6 +754,58 @@ sub TRAFFIC(){
|
|||||||
return ($FW_RETTYPE, $FW_RET);
|
return ($FW_RETTYPE, $FW_RET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub TRAFFIC_DbLog_split($) {
|
||||||
|
my ($event, $device) = @_;
|
||||||
|
my $hash = $defs{$device};
|
||||||
|
Log3 $hash, 5, "TRAFFIC: ($device) TRAFFIC_DbLog_split received event $event on device $device";
|
||||||
|
|
||||||
|
my $readings; # this holds all possible readings and their units
|
||||||
|
$readings->{'update'} = 'text';
|
||||||
|
$readings->{'duration'} = 'text';
|
||||||
|
$readings->{'duration_in_traffic'} = 'text';
|
||||||
|
$readings->{'distance'} = 'text';
|
||||||
|
$readings->{'state'} = 'text';
|
||||||
|
$readings->{'status'} = 'text';
|
||||||
|
$readings->{'eta'} = 'time';
|
||||||
|
$readings->{'summary'} = 'text';
|
||||||
|
$readings->{'alternatives'} = 'text';
|
||||||
|
$readings->{'delay'} = 'text';
|
||||||
|
$readings->{'delay_min'} = 'min';
|
||||||
|
$readings->{'error_message'} = 'text';
|
||||||
|
$readings->{'duration_min'} = 'min';
|
||||||
|
$readings->{'duration_in_traffic_min'} = 'min';
|
||||||
|
$readings->{'duration_sec'} = 'sec';
|
||||||
|
$readings->{'duration_in_traffic_sec'} = 'sec';
|
||||||
|
$readings->{'distance'} = 'km';
|
||||||
|
$readings->{'average_duration_min'} = 'min';
|
||||||
|
$readings->{'average_duration_in_traffic_min'} = 'min';
|
||||||
|
$readings->{'average_delay_min'} = 'min';
|
||||||
|
$readings->{'average_duration_min'} = 'min';
|
||||||
|
$readings->{'average_duration_in_traffic_min'} = 'min';
|
||||||
|
$readings->{'average_delay_min'} = 'min';
|
||||||
|
|
||||||
|
my ($reading, $value, $unit) = "";
|
||||||
|
|
||||||
|
my @parts = split(/ /,$event);
|
||||||
|
$reading = shift @parts;
|
||||||
|
$reading =~ tr/://d;
|
||||||
|
$reading =~ s/^return_//;
|
||||||
|
$value = join(" ",@parts);
|
||||||
|
|
||||||
|
if($readings->{$reading}){
|
||||||
|
$unit = $readings->{$reading};
|
||||||
|
$value =~ s/$unit$//; #try to remove the unit from the value
|
||||||
|
}else{
|
||||||
|
Log3 $hash, 5, "TRAFFIC: ($device) TRAFFIC_DbLog_split auto detect unit for reading $reading value $value";
|
||||||
|
$unit = 'min' if ($reading) =~ m/_min$/;
|
||||||
|
$unit = 'sec' if ($reading) =~ m/_sec$/;
|
||||||
|
$unit = 'km' if ($reading) =~ m/_km$/;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log3 $hash, 5, "TRAFFIC: ($device) TRAFFIC_DbLog_split returning $reading, $value, $unit";
|
||||||
|
return ($reading, $value, $unit);
|
||||||
|
}
|
||||||
|
|
||||||
sub prettySeconds {
|
sub prettySeconds {
|
||||||
my $time = shift;
|
my $time = shift;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user