Find My iPhone / Wo Ist? / iPhone / iCloud / aktuellen Ort per WebAPI abfragen

Begonnen von Torxgewinde, 10 April 2022, 16:06:02

Vorheriges Thema - Nächstes Thema

Torxgewinde

Hallo,
Es ist recht einfach den Ort eines iCloud Gerätes abzufragen. Hier ein BASH Script wie das geht:

ICLOUD_USERNAME="bla@blubb.de"
ICLOUD_PASSWORD="passwort123"
ICLOUD_DEVICE="Bla iPhone"

#urlencode the USERNAME, its part of the URL below
URL_CODED_USERNAME="$(echo $ICLOUD_USERNAME | sed -e "s/@/%40/g" -e "s/\ /%20/g")"

RESPONSE="$(curl -s --dump-header /dev/null -X POST -L -u $ICLOUD_USERNAME:$ICLOUD_PASSWORD -H 'Content-Type: application/json; charset=utf-8' -H 'X-Apple-Find-Api-Ver: 2.0' -H 'X-Apple-Authscheme: UserIdGuest' -H 'X-Apple-Realm-Support: 1.0' -H 'User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)' -H 'X-Client-Name: iPad' -H 'X-Client-UUID: 0cf3dc501ff813adb0b202baed4f37274b210843' -H 'Accept-Language: de-de' -H 'Connection: keep-alive' --cacert fmipmobile-icloud-com.pem https://fmipmobile.icloud.com/fmipservice/device/$URL_CODED_USERNAME/initClient)"

LONGITUDE="$(echo "$RESPONSE" | jq .[] | jq ".[] | select(.name==\"$ICLOUD_DEVICE\") | .location | .longitude" 2>/dev/null)"
LATITUDE="$(echo "$RESPONSE" | jq .[] | jq ".[] | select(.name==\"$ICLOUD_DEVICE\") | .location | .latitude" 2>/dev/null)"

echo "LONG: $LONGITUDE"
echo "LAT:  $LATITUDE"

#convert to human readable adress
# !!! perhaps you do not want to use this everytime, as it needs to tell the queried server the location !!!
curl -o- "https://nominatim.openstreetmap.org/reverse?lat=$LATITUDE&lon=$LONGITUDE&format=json" 2>/dev/null | jq '.display_name'


Das Script setzt die Programme jq und curl vorraus. Ggf. muss man diese noch installieren.

Damit curl das Zertifikat von Apples eigener PKI akzeptiert, kann man dieses runterladen und in der Datei fmipmobile-icloud-com.pem speichern. Hier der Inhalt der Datei:
-----BEGIN CERTIFICATE-----
MIID+DCCAuCgAwIBAgIII2l0BK3LgxQwDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxlIENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENBMB4XDTE0
MDMwODAxNTMwNFoXDTI5MDMwODAxNTMwNFowbTEnMCUGA1UEAwweQXBwbGUgU2Vy
dmVyIEF1dGhlbnRpY2F0aW9uIENBMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1
dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5Jhawy4ercRWSjt+qPuGA11O6pGDM
fIVy9zB8CU9XDUr/4V7JS1ATAmSxvTk10dcEUcEY+iL6rt+YGNa/Tk1DEPoliJ/T
QIV25SKBtlRFc5qL45xIGoZ6w1Hi2pX4pH3bMN5sDsTF9WyY56b6VyAdGXN6Ds1j
D7cniC7hmmiCuEBsYxYkZivnsuJUfeeIOaIbgT4C0znYl3dKMgzWCgqzBJvxcm9j
qBUebDfoD9tTkNYpXLxqV5tGeAo+JOqaP6HYP/XbbqhsgrXdmTjsklaUpsVzJtGu
CLLGUueOdkuJuFQPbuDZQtsqZYdGFLuWuFe7UeaEE/cNobaJrHzRIXSrAgMBAAGj
gaYwgaMwHQYDVR0OBBYEFCzFbVLdMe+M7AiB7d/cykMARQHQMA8GA1UdEwEB/wQF
MAMBAf8wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wLgYDVR0fBCcw
JTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5jcmwwDgYDVR0PAQH/
BAQDAgEGMBAGCiqGSIb3Y2QGAgwEAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQAj8QZ+
UEGBol7TcKRJka/YzGeMoSV9xJqTOS/YafsbQVtE19lryzslCRry9OPHnOiwW/Df
3SIlERWTuUle2gxmel7Xb/Bj1GWMxHpUfVZPZZr92sSyyLC4oct94EeoQBW4Fhnt
W2GO36rQzdI6wH46nyJO39/0ThrNk//Q8EVVZDM+1OXaaKATinYwJ9S/+B529vnD
AO+xg+pTbVw1xw0HAbr4Ybn+xZprQ2GBA+u6X3Cd6G+UJEvczpKoLqI1PONJ4BZ3
otxruY0YQrk2lkMyxst2mTU22FbGmF3Db6V+lcLVegoCIGZ4kvJnpCMN6Am9zCEx
EKC9vrXdTN1GA5mZ
-----END CERTIFICATE-----


Vielleicht findet sich ja jemand, der dies nach PERL & FHEM bringt. Das wäre praktisch.

gestein

Hallo,

Das klingt echt toll.
Könnte man damit auch das Gerät klingeln lassen?

Lg, Gerhard

betateilchen

Zitat von: Torxgewinde am 10 April 2022, 16:06:02
Das Script setzt die Programme jq und curl vorraus. Ggf. muss man diese noch installieren.
...
Vielleicht findet sich ja jemand, der dies nach PERL & FHEM bringt. Das wäre praktisch.

jq zum Extrahieren von JSON und curl zum Aufruf einer URL?
Dafür gibt es ein fertiges Modul in FHEM: 98_JsonMod.pm

Alternativ kann man die Aufbereitung der URL auch in der 99_myUtils.pm umsetzen und dort mit HttpUtils.pm und den FHEM eigenen JSON Funktionen arbeiten.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CQuadrat

Hallo,

ich würde das Script gerne mal ausprobieren. Aber ich muss doch bestimmt eine eigene X-Client-UUID übergeben. Wo bekomme ich die denn her?

Danke und Gruß

Christoph
FHEM auf Mini-ITX-Server mit Intel Quad-Core J1900:
+ HM: HM-LAN, HM-USB, HM-MOD-UART mit div. HM-Komponenten
+ RFXtrx: Funkwetterstation Bresser mit ext. Thermometer, Regenmesser und Windmesser
+ TUL (KNX-Anbindung), KM271 (per ser2net), SONOS (div. Gimmicks), OneWire, Hue

Torxgewinde

Moin!

@gestein: Ja, die API bietet die Möglichkeiten. Einige Bibliotheken, vor allem in Python und Node, haben da bereits gut vorgearbeitet. Interessant wäre zum Beispiel dieses Projekt https://github.com/picklepete/pyicloud. Ich hätte es lieber mit FHEM und damit vorzugsweise in PERL, allerdings habe ich da noch nichts fertiges gefunden. Bei NPM, PIP und Docker bin ich zurückhaltend, da die Qualität durchaus "durchwachsen" sein kann - da ist viel Licht, aber auch einige Schatten. Pakete aus den Distributionen sind da IMHO deutlich unkritischer.

@betateilchen: Ich hoffe mit dem Codeschnipsel jemanden aus dem FHEM Umfeld zu inspirieren. Wenn ich es für mich selbst zusammenfrickel, wähle ich lieber BASH und melde es mir mit MQTT an FHEM.

@CQuadrat / Christoph: Die UUID wird scheinbar nicht geprüft, ich habe die URL auch aus zusammengesuchten Fragmenten zusammengebaut, bis es funktionierte. Da ist keine exakte UUID hinterlegt. Vielleicht kann man diesen Header sogar komplett weglassen, das müsste man mal ausprobieren.

CQuadrat

Ich habe es zum Laufen bekommen. Allerdings muss ich bei curl noch die Option ,,-k" verwenden. Irgendwie habe ich da wohl noch Probleme mit der Überprüfung des Zertifikates - mal schauen.

Mal sehen, wie ich das in FHEM integriert bekomme. Damit könnte mindestens mal so etwas wie eine Anwesenheitsprüfung gut realisieren.
FHEM auf Mini-ITX-Server mit Intel Quad-Core J1900:
+ HM: HM-LAN, HM-USB, HM-MOD-UART mit div. HM-Komponenten
+ RFXtrx: Funkwetterstation Bresser mit ext. Thermometer, Regenmesser und Windmesser
+ TUL (KNX-Anbindung), KM271 (per ser2net), SONOS (div. Gimmicks), OneWire, Hue

kalleknx

Die Anwesenheitserkennung mittels Apple bzw. HomeKit kannst Du auch einfacher gestalten (Voraussetzung homebridge läuft):
- definiere dir einen dummy Schalter in FHEM und integriere ihn in homebridge
- in der Apple Home App kannst Du einfache Automatisierungen erstellen, zB Wenn ich das Haus verlasse, dann schalte <Dummy Schalter> ein

Das wiederum kannst Du einfach in FHEM auswerten. Ich hatte früher geofancy laufen, welches jetzt nicht mehr notwendig ist.

CQuadrat

Danke. Mit homebridge hatte ich bisher noch nichts am Hut. Ich schaue es mir mal an.
FHEM auf Mini-ITX-Server mit Intel Quad-Core J1900:
+ HM: HM-LAN, HM-USB, HM-MOD-UART mit div. HM-Komponenten
+ RFXtrx: Funkwetterstation Bresser mit ext. Thermometer, Regenmesser und Windmesser
+ TUL (KNX-Anbindung), KM271 (per ser2net), SONOS (div. Gimmicks), OneWire, Hue

erwin

Hi,
Ich habe es am Laufen, mittels JsonMod Modul. Allerdings ist ein Patch für das Modul erforderlich, siehe: https://forum.fhem.de/index.php/topic,127428.0.html
Client Certifikat ist bei mir nicht erforderlich.
Sobald der support offiziell ist, kann ich gerne die Details zur definition liefern.
l.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

erwin

Hi nochmal !
..nachdem sich beim Jsonmod-Thread nix tut, hier mal die raw-definition:

defmod jtestM JsonMod https://[uid]:[pwd]@fmipmobile.icloud.com/fmipservice/device/[uid]/initClient\

attr jtestM httpHeader Accept: */*\
Content-Type: application/json;; charset=utf-8\
X-Apple-Find-Api-Ver: 2.0\
X-Apple-Authscheme: UserIdGuest\
X-Apple-Realm-Support: 1.0\
User-agent: Find iPhone/1.3 MeKit (iPad: iPhone OS/4.2.1)\
X-Client-Name: iPadM\
X-Client-UUID: 0cf3dc501ff813adb0b202baed4f37274b210843\
Accept-Language: de-de\
Connection: keep-alive\

attr jtestM interval 1/15 * * * *
attr jtestM readingList #single(jsonPath('content.2.location.latitude'),'lat',0);;\
#single(jsonPath('content.2.location.longitude'),'lon',0);;\
single(jsonPath('content.2.location.horizontalAccuracy'),'acc',0);;\
single(jsonPathf('content.2.batteryLevel','%0.2f'),'Battlevel',0);;\
single(jsonPath('serverContext.serverTimestamp'),'ServerTS',0);;\
single(jsonPath('content.2.location.timeStamp'),'ts',0);;\
multi(jsonPath('$.content.2.location'), 'location', concat(propertyf('latitude', 0, '%02.6f'), ',', propertyf('longitude', 0, '%03.6f')));;\
#complete();;\

attr jtestM userReadings TS:ts.* {my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(ReadingsVal($name,'ts',0)/1000 );; sprintf("%02d:%02d:%02d %02d/%02d/%04d ", $hour,$min,$sec,$mday,$mon + 1,$year + 1900)}, \
#location:lon.* {sprintf('%.6f,%.6f',ReadingsNum($name,'lat',0), ReadingsNum($name,'lon',0)) }

Funktioniert allerdings nur mit dem JsonMod-patch aus dem vorigem post !
entweder die ersten beiden "single(..." verwenden, für lat und lon,
oder das "multi(..." , das ein kombiniertes reading erzeugt.
ob "content.2.location oder "content.1.location" der richtige json-path ist, hängt von der Anzahl der definierten Geräte im Apple-ID ab!

Als secret zu setzen: uid <apple userID> und pwd <apple-passwort>
l.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

gestein

Hallo Erwin,

ich habe mich gerade an Deinem Code versucht und wollte das diff manuell eingeben.
Allerdings scheint meine "98_JsonMod.pm" neuer zu sein.
SVN24783 2021-07-21 22:37:12 UTC

Die erste Zeile ist noch klar:
46                @attrList = qw(
47                        httpHeader:textField-long
->+                      httpMethod:GET,POST
48                        httpTimeout
49                        update-on-start:0,1


Aber wo muss ich die zweite Zeile dazugeben?

Danke im Voraus
lg, Gerhard

erwin

Hi, Sorry bitte um Geduld bis nächste Woche, ich bin mit einem Sozialprojekt
in der Adria Segeln, hab keinen Zugriff aufs System.
L.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...

binford6000

Zitat von: gestein am 21 September 2022, 13:00:05
Hallo Erwin,

ich habe mich gerade an Deinem Code versucht und wollte das diff manuell eingeben.
Allerdings scheint meine "98_JsonMod.pm" neuer zu sein.
SVN24783 2021-07-21 22:37:12 UTC

Die erste Zeile ist noch klar:
46                @attrList = qw(
47                        httpHeader:textField-long
->+                      httpMethod:GET,POST
48                        httpTimeout
49                        update-on-start:0,1


Aber wo muss ich die zweite Zeile dazugeben?

Danke im Voraus
lg, Gerhard

Hallo Gerhard,
das klappt auch mit deiner Version. Gerade getestet:
patch 98_JsonMod.pm 98_JsonMod.diff

VG Sebastian

gestein

Hallo Sebastian,

Vielen Dank. Wieder was dazu gelernt.
Hat geklappt.
Man muss nur noch das Attribut ,,httpMethod" auf ,,POST" umstellen und schon sind die Parameter da.

Wenn ich mehrere Geräte im ,,Wo ist?" habe, muss ich alle einzeln mit einem entsprechenden ,,Single"-Eintrag in der readingList eintragen.
Oder gibt es eine Art ,,for"-Schleife mit der man das lösen könnte?

Vielen Dank auf alle Fälle.
Lg, Gerhard

gestein

Und noch eine Frage bitte:
Mit dem aktuellen Code werden die Geräte angezeigt.
Kann man auch auf die Objekte zugreifen (also AirTags etc.)?

Danke, lg, Gerhard