Dieses kleine Perl-Programm macht einen nicht-blockierenden Http-GET-Call zu einem OpenStreetMap-Server, der aus Geodaten die Adresse bestimmt.
Achtung: Maximal 1 Anfrage pro Sekunde zulässig.
###############################################################################
#
# OpenStreetMap reverse geocoding
# Parameter: dev=Device-Name, dessen Reading auf die Adresse gesetzt werden soll
# lat,lon=Geokoordinaten im WGS84-System, Dezimalgrad
#
###############################################################################
sub OSM_address($$$) {
my ($dev, $lat, $lon) = @_;
my $url = sprintf(
"https://nominatim.openstreetmap.org/reverse?lat=%s&lon=%s&format=json&addressdetails=1&accept-language=de",
$lat, $lon
);
HttpUtils_NonblockingGet({
url => $url,
timeout => 10,
method => "GET",
header => "User-Agent: FHEM-Geocoder/1.0 (private home automation)",
callback => \&OSM_address_callback,
dev => $dev
});
return 1;
}
sub OSM_address_callback($$$) {
my ($param, $err, $data) = @_;
my $dev = $param->{dev};
if ($err ne "") {
Log3($dev, 2, "OSM_address: $err");
return;
}
my $json = eval { decode_json($data) };
if ($@ || !defined($json)) {
Log3($dev, 2, "OSM_address: JSON error");
return;
}
my $addr = $json->{address} // {};
my $street = $addr->{road} // "";
my $number = $addr->{house_number} // "";
my $zip = $addr->{postcode} // "";
my $city = $addr->{city}
// $addr->{town}
// $addr->{village}
// "";
my $address = "$street $number, $zip $city";
$address =~ s/^\s+|\s+$//g;
fhem("setreading $dev address $address");
}
LG
pah
Danke, aber daraus werd ich nicht schlau.
Wo trage ich das Device für readings ein?
wenn ich hier dev => $dev das def ersetze kommt als Fehlermeldung:
Not enough arguments for main::OSM_address at (eval 29685394) line 1, near "$$)"
Aufruf in Fhem erfolgt mit: { OSM_address("DummyDevice", 50.835894930948754, 12.923236802730305) }
... Danke an pah