114 lines
3.0 KiB
Perl
114 lines
3.0 KiB
Perl
package FHEM::BlueLinkVehicle;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use JSON;
|
|
use Time::Piece;
|
|
|
|
sub Initialize {
|
|
my ($hash) = @_;
|
|
|
|
$hash->{DefFn} = "BlueLinkVehicle_Define";
|
|
$hash->{SetFn} = "BlueLinkVehicle_Set";
|
|
$hash->{GetFn} = "BlueLinkVehicle_Get";
|
|
$hash->{AttrList} = "vin IODev";
|
|
}
|
|
|
|
sub BlueLinkVehicle_Define {
|
|
my ($hash, $def) = @_;
|
|
my @args = split("[ \t]+", $def);
|
|
|
|
return "Usage: define <name> BlueLinkVehicle <VIN> <IODev>" if (@args < 4);
|
|
|
|
$hash->{VIN} = $args[2];
|
|
my $parent = $args[3];
|
|
$hash->{IODev} = $defs{$parent};
|
|
|
|
return "Parent device $parent not found" unless defined $hash->{IODev};
|
|
|
|
return;
|
|
}
|
|
|
|
sub BlueLinkVehicle_Set {
|
|
my ($hash, $name, $cmd, @args) = @_;
|
|
|
|
return "\"set $name\" needs at least one argument" unless defined $cmd;
|
|
|
|
if ($cmd eq "update") {
|
|
return BlueLinkVehicle_Update($hash);
|
|
}
|
|
|
|
return "Unknown argument $cmd, choose one of update";
|
|
}
|
|
|
|
sub BlueLinkVehicle_Get {
|
|
my ($hash, $name, $cmd, @args) = @_;
|
|
|
|
return "\"get $name\" needs at least one argument" unless defined $cmd;
|
|
|
|
if ($cmd eq "soc") {
|
|
return ReadingsVal($name, "SoC", "Unknown") . " %";
|
|
} elsif ($cmd eq "range") {
|
|
return ReadingsVal($name, "Range", "Unknown") . " km";
|
|
} elsif ($cmd eq "status") {
|
|
return ReadingsVal($name, "Status", "Unknown");
|
|
}
|
|
|
|
return "Unknown argument $cmd, choose one of soc range status";
|
|
}
|
|
|
|
sub BlueLinkVehicle_Update {
|
|
my ($hash) = @_;
|
|
my $name = $hash->{NAME};
|
|
my $parent = $hash->{IODev};
|
|
my $vin = $hash->{VIN};
|
|
|
|
return "Parent module not found" unless $parent;
|
|
return "VIN not defined" unless $vin;
|
|
|
|
# Anfrage an das Hauptmodul senden (IOWrite)
|
|
IOWrite($parent, "getVehicleStatus", $vin);
|
|
return "Request sent to parent module.";
|
|
}
|
|
|
|
sub BlueLinkVehicle_ParseTime {
|
|
my ($time_string) = @_;
|
|
return unless $time_string;
|
|
|
|
my $format = "%Y%m%d%H%M%S %z";
|
|
my $t = Time::Piece->strptime($time_string . " +0100", $format);
|
|
|
|
return $t->strftime("%Y-%m-%d %H:%M:%S");
|
|
}
|
|
|
|
sub BlueLinkVehicle_Receive {
|
|
my ($hash, $data) = @_;
|
|
my $name = $hash->{NAME};
|
|
|
|
my $json = eval { decode_json($data) };
|
|
return "Invalid JSON data received" if $@;
|
|
|
|
if ($json->{vin} && $json->{vin} eq $hash->{VIN}) {
|
|
my $status = $json->{status};
|
|
|
|
my $soc = $status->{EvStatus}->{BatteryStatus} // "Unknown";
|
|
my $range = $status->{EvStatus}->{DrvDistance}->[0]->{RangeByFuel}->{EvModeRange}->{Value} // "Unknown";
|
|
my $charging = $status->{EvStatus}->{BatteryCharge} ? "Charging" : "Not Charging";
|
|
my $updated = BlueLinkVehicle_ParseTime($status->{Time}) // "Unknown";
|
|
|
|
readingsBeginUpdate($hash);
|
|
readingsBulkUpdate($hash, "SoC", $soc);
|
|
readingsBulkUpdate($hash, "Range", $range);
|
|
readingsBulkUpdate($hash, "Status", $charging);
|
|
readingsBulkUpdate($hash, "LastUpdate", $updated);
|
|
readingsEndUpdate($hash, 1);
|
|
|
|
return "Vehicle data updated.";
|
|
}
|
|
|
|
return "VIN mismatch - ignoring data.";
|
|
}
|
|
|
|
1;
|
|
|