könnte man nicht hier reinschauen, wie das bei ha gemacht wird?
https://github.com/gcobb321/icloud3_v3/blob/a3f302b132dc68beadd4ad9c303d13e3c22c5d9e/custom_components/icloud3/support/pyicloud_ic3.py#L1549
nur diesen Teil hat chatgpt wie folgt übersetzt
klar, das ist nur ein Teil und da muss man sich etwas tiefer reinknien.
evtl könnte jemand mit python kenntnissen und einer ha installation da an bestimmten stellen noch sowas wie console.log einbauen um die request reihenfolge herauszufinden.
aber machbar müsste das schon sein
class FindMyFriendsService {
constructor(PyiCloud, serviceRoot, Session, params) {
this.Session = Session;
this.PyiCloud = PyiCloud;
this.params = params;
this._serviceRoot = serviceRoot;
this.refreshAlways = false;
this.response = {};
this.isServiceAvailable = true;
this.isServiceNotAvailable = false;
this.setServiceAvailable(serviceRoot !== null);
this.deviceIdByFmfEmail = {};
this.fmfEmailByDeviceId = {};
this.deviceInfoByFmfEmail = {};
this.deviceFormIcloudFmfList = [];
this.devicesWithoutLocationData = [];
this._contactsEndpoint = `${this._serviceRoot}/co`;
this._contactsRefreshUrl = `${this._contactsEndpoint}/startup`;
this._contactsNextUrl = `${this._contactsEndpoint}/contacts`;
this._contactsChangesetUrl = `${this._contactsEndpoint}/changeset`;
this.refreshClient();
}
setServiceAvailable(available) {
this.isServiceAvailable = available;
this.isServiceNotAvailable = !available;
}
refreshClient() {
if (this.isServiceNotAvailable) return;
let paramsContacts = {...this.params, clientVersion: "2.1", locale: "en_US", order: "last,first"};
this.Session.get(this._contactsRefreshUrl, { params: paramsContacts })
.then(response => {
this.response = response.data;
let paramsNext = {
...paramsContacts,
prefToken: this.response.prefToken,
syncToken: this.response.syncToken,
limit: "0",
offset: "0",
};
return this.Session.get(this._contactsNextUrl, { params: paramsNext });
})
.then(response => {
this.response = response.data;
})
.catch(error => {
console.error(error);
this.response = {};
});
}
contactsAll() {
this.refreshClient();
return this.response.contacts;
}
_confFmfDevicesNotSetUp() {
const devicesNotSetUp = Gb.confDevices
.filter(confDevice => confDevice[CONF_FMF_EMAIL] !== NONE_FNAME && !this.deviceIdByFmfEmail[confDevice[CONF_FMF_EMAIL]])
.map(confDevice => `${confDevice[CONF_IC3_DEVICENAME]} (${confDevice[CONF_FMF_EMAIL]})`);
return devicesNotSetUp.length ? devicesNotSetUp.join("\n") : "";
}
get timestampField() {
return 'timestamp';
}
get dataSource() {
return FMF_FNAME;
}
// ... Weitere Methoden hier ...
contactIdFor(identifier, defaultValue = null) {
const lookupKey = identifier.includes("@") ? "emails" : "phones";
const matcher = item => {
const hit = item[lookupKey];
if (!Array.isArray(hit)) {
return hit === identifier;
}
return hit.includes(identifier);
};
const candidates = this.contactDetails
.filter(matcher)
.map(item => item.id);
return candidates.length ? candidates[0] : defaultValue;
}
locationOf(contactId, defaultValue = null) {
const candidates = this.locations
.filter(item => item.id === contactId)
.map(item => item.location);
return candidates.length ? candidates[0] : defaultValue;
}
get data() {
if (!this.response) {
this.refreshClient();
}
return this.response;
}
get locations() {
return this.response.locations || [];
}
get followers() {
return this.response.followers || [];
}
get following() {
return this.response.following || [];
}
get contactDetails() {
return this.response.contactDetails || [];
}
get myPrefs() {
return this.response.myPrefs || [];
}
get deviceIdentifier() {
return `${this.response.firstName || ''} ${this.response.lastName || ''}`.trim();
}
toString() {
try {
return `<FindMyFriendsService: ${this.PyiCloud.apple_id}>`;
} catch {
return "<FindMyFriendsService: NotSetUp>";
}
}
}