J'ai commencé a me pencher sur l'idée d'un magicmirror ou un dashboard qui m'afficherai quelques informations. Notamment mon calendrier icloud. Je cherche un moyen de récupérer les informations, et en traînant un peu je suis tomber par hasard sur un script de récupération de la localisation d'un iphone.
Comme je souhaite aussi toujours améliorer ma détection de présence je me suis penché un peu dessus. Je n'ai pas trop trouvé de tuto. Quelques utilisateurs par-ci par-la utilisent leur script. Et je viens même d'en recevoir un qui à l'air très complet.
Je n'ai pas encore commencé a regardé, mais sur le forum officiel, je suis tombé sur un petit script très suffisant pour beaucoup d'entre nous qui ont un iphone.
Il permet de récupérer la distance, l'adresse, le pourcentage de batterie et d'avoir une notification ainsi que de switcher un interrupteur en cas de localisation sur le domicile, en multi-user.
Exemple dans mes log (j'ai un problème avec le pourcentage de la batterie lol il faudra que je vois ca):
Vous n'avez qu'a activer le findmyiphone d'icloud (localisation), renseigner vos paramètres et créer les devices nécessaire.2017-12-01 22:52:02.326 LUA: iPhone Benjamin: 0.02 km from home, 86.000001430511% battery remaining. PowerState: NotCharging
2017-12-01 22:52:04.161 LUA: iPhone Celine: 4 km from home, 14% battery remaining. PowerState: NotCharging
[EDIT] J’édite le poste car j'ai agrémenté le script.
Afin de gagner un peu en batterie je ne fais plus les recherche toutes les 5 minutes.
Je stock une date suivant le besoin dans une variable.
Si le portable est au domicile j’exécute le script toutes les heures.
Si il est a l’extérieur, je récupère le temps de trajet, et j’exécute le script en fonction de ce temps de trajet (Si j'ai 10 minute de route j’exécute le script dans 8 min ect...)
Si il y a une erreur dans le script (pas de réponse icloud ou autre) je relance le script une minute plus tard.
J'ai du coup créer des variables en plus.
Voici la liste des devices et variable a creer
Ou le nom User est le nom du deviceDummy switch "Presence User"
Dummy text "Adresse User"
Dummy text "Trajet User"
Dummy % "Batterie User"
Variable chaine "GPS User" avec la position gps au format: 47.4533,0.2453453
Variable chaine "updateGeoloc"="reload"
Le script:
Code : Tout sélectionner
commandArray={}
-- ****************************************************** - Ouverture - ****************************************************** --
local d,m,y,H,M=uservariables['updateGeoloc']:match("(%d+)/(%d+)/(%d+) (%d+):(%d+)")
if uservariables['updateGeoloc'] == 'reload' or os.time({day=d,month=m,year=y,hour=H,min=M})<=os.time() then
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()
--################################################################################################################################--
--################## DEVICE a CREER ##################--
--################################################################################################################################--
--[[
*/Device a creer:
Dummy switch "Presence User"
Dummy text "Adresse User"
Dummy text "Trajet User"
Dummy % "Batterie User"
Variable chaine "GPS User"
Variable chaine "updateGeoloc"
]]--
--################################################################################################################################--
--################## CONFIGURATION ##################--
--################################################################################################################################--
-- Utilisateurs a detecter
users = {
apple = {
Utilisateur1 = {username = "adresse1@email.fr" ; password = "motdepasseicloud" ; devicename = "iPhone de Utilisateur1" ; UDID = "d98c8ae0db3311e687b92890643032df"};
Utilisateur2 = {username = "adresse2@email.fr" ; password = "motdepasseicloud" ; devicename = "iPhone de Utilisateur2" ; UDID = "d98c8ae0db3311e687b92890643032df"};
--UDID Non obligatoire
};
}
-- Latitude et Longitude du domicile:
local latitudeHome=""
local longitudeHome=""
-- Clef d'API
local googleapikey=""
-- Radius (en km) de detection de position au domicile ou de changement de position
local radius=0.5
local delai = {}
--################################################################################################################################--
--################## FONCTION ##################--
--################################################################################################################################--
-- Fonction de recuperation des informations icloud
-- Renvoi les informations du telephone (GPS, Batterie, Status...)
function icloud(username,password,devicename,UDID)
local url = 'curl -s -X POST -L -k -u "' .. username .. ':' .. 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: '..UDID..'" '
.. '-H "Accept-Language: en-us" '
.. '-H "Connection: keep-alive" https://p43-fmipmobile.icloud.com/fmipservice/device/' .. username ..'/initClient'
local handle = assert(io.popen(url))
local result = handle:read("*a")
handle:close()
output = json:decode(result)
--On recherche le device associé au devicename de l'utilisateur
for key,value in pairs(output.content) do
if value.name == devicename then
--On verifie que le device est localisé depuis peu pour recuperer les valeurs importantes
if value.isLocating == true and value.location ~= nil and value.location.isInaccurate ~= true and value.location.isOld ~= true then
device = {
batlvl = math.floor(value.batteryLevel * 100 / 1);
batstat = value.batteryStatus;
accuracy = value.location.isInaccurate;
latitudeGPS = value.location.latitude;
longitudeGPS = value.location.longitude;
positionType = value.location.positionType;
timestampupdate = value.location.timeStamp;
horizontalAccuracy = value.location.horizontalAccuracy
}
return device
elseif value.isLocating == false or value.location == nil or value.location.isInaccurate == true or value.location.isOld == true or value.location.locationFinished == false then
print(script..'Retour icloud: probleme')
return nil
else
print(script..'Retour icloud: probleme')
return nil
end
end
end
end
-- Fonction de traduction de coordonées GPS en adresse postale
-- Renvoi l'adresse postale suivant des coordonées GPS
function google(latitude,longitude)
local url = 'curl -s https://maps.googleapis.com/maps/api/geocode/json?latlng='.. latitude .. ',' .. longitude .. '&language=FR&location_type=ROOFTOP&key=' .. googleapikey
local handle = io.popen(url)
local result = handle:read("*a")
handle:close()
output = json:decode(result)
for key,value in pairs(output) do
if output.results[1] ~= nil or output.status == nil then
adresse = output.results[1].formatted_address
return adresse
elseif output.status == "OVER_QUERY_LIMIT" then
print(script..'Retour Google: OVER_QUERY_LIMIT',debug)
return nil
else
print(script..'Retour Google: autre probleme'..result)
return nil
end
end
end
-- Fonction de calcule d'itineraire
-- Renvoi dans une table le temps en metre et la distance en metre de trajet entre deux coordonées GPS
function waze(latitudeDepart,longitudeDepart,latitudeArrivee,longitudeArrivee)
local url = 'curl --referer https://www.waze.com "https://www.waze.com/row-RoutingManager/routingRequest?from=x%3A'..longitudeDepart..'+y%3A'..latitudeDepart..'&to=x%3A'..longitudeArrivee..'+y%3A'..latitudeArrivee..'&returnJSON=true&timeout=6000&nPaths=1&options=AVOID_TRAILS%3At%2CALLOW_UTURNS"'
local handle = io.popen(url)
local result = handle:read('*all')
handle:close()
output = json:decode(result)
local routeTotalDistm = 0
for key,value in pairs(output.response.results) do
routeTotalDistm = routeTotalDistm + value.length
end
if routeTotalDistm ~= nil and output.response.totalRouteTime ~= nil then
trajet = { temps = output.response.totalRouteTime ; distance = routeTotalDistm }
return trajet
else
print(script..'Retour Waze probleme ')
return nil
end
end
-- Fonction de calcul de distance
-- Renvoi la distance en kilometre a une decimale entre deux coordonées GPS
function distancekm(latitude1, longitude1, latitude2, longitude2)
local rayonTerre = 6378137; -- Rayon équatorial de la terre en metre
local radlatx = math.rad(latitude1);
local radlonx = math.rad(longitude1);
local radlaty = math.rad(latitude2);
local radlony = math.rad(longitude2);
local calculLatitude = (radlaty - radlatx) / 2;
local calculLongitude = (radlony - radlonx) / 2;
local detail = (math.sin(calculLatitude))^2 + math.cos(radlatx) * math.cos(radlaty) * (math.sin(calculLongitude))^2;
local calcul = 2 * math.atan(math.sqrt(detail), math.sqrt(1 - detail));
output = math.floor((rayonTerre * calcul)/100)/10
return output
end
--################################################################################################################################--
--################## SCRIPT ##################--
--################################################################################################################################--
for user,compte in pairs(users.apple) do
-- Ancienne position:
local latitudeOld, longitudeOld = string.match(uservariables['GPS '..user], '(.*)%,'), string.match(uservariables['GPS '..user], '%,(.*)')
-- Ancienne distance [position-domicile]:
local radiusHomePrecedent = distancekm(latitudeOld, longitudeOld, latitudeHome, longitudeHome)
if icloud(compte.username,compte.password,compte.devicename,compte.UDID) ~= nil then
-- Distance [nouvelle position-ancienne position]:
local radiusPrecedent = distancekm(device.latitudeGPS, device.longitudeGPS,latitudeOld, longitudeOld)
-- Distance [nouvelle position-domicile]:
radiusHome = distancekm(device.latitudeGPS, device.longitudeGPS, latitudeHome, longitudeHome)
-- Distance [nouvelle position-travail]:
--radiusWork = distancekm(device.latitudeGPS, device.longitudeGPS, latitudeWork, longitudeWork)
---------------------------Presence: si la distance avec le domicile est inferieur au radius minium alors le smartphone est present au domicile
if radiusHome < radius then --Presence
if otherdevices['Presence ' .. user] == 'Off' then --Arrivée
commandArray['Presence ' .. user] = 'On'
end
radiusSmartphone = '0.0'
else
if otherdevices['Presence ' .. user] == 'On' then
commandArray['Presence ' .. user] = 'Off'
end
radiusSmartphone = radiusHome
end
---------------------------Deplacement: si la distance avec l'ancienne position est superieur au radius minimum alors le smartphone n'est plus au meme endroit et se deplace
if radiusPrecedent > radius then
deplacement = true
else
deplacement = false
end
---------------------------Direction: si la distance avec le domicile est superieur a la distance de l'ancienne position au domicile alors le smartphone s'eloigne du domicile
if radiusHome > radiusHomePrecedent and deplacement == true then --S'eloigne du domicile
eloignement = true
elseif radiusHome < radiusHomePrecedent and deplacement == true then
eloignement = false
else
eloignement = nil
end
table.insert(commandArray,{['UpdateDevice']=otherdevices_idx['Batterie '..user]..'|0|'..device.batlvl})
print(script..'iCloud: '..user..': '..radiusSmartphone..' km du domicile, '..device.batlvl..'% de batterie restante. Statut: "'..device.batstat..'". Precision: '..device.horizontalAccuracy)
else
local incident = true
end
---------------------------Si le smartphone se rapproche je recupere le trajet vers le domicile
if radiusHome > radius or radiusHomePrecedent > radius then
if waze(latitudeHome,longitudeHome,device.latitudeGPS,device.longitudeGPS) ~= nil then
--Fonction waze retourne pour le trajet entre deux coordonées une table avec le temps en seconde et la distance en metre
local heures=math.floor(trajet.temps / 3600)
local minutes=math.floor((trajet.temps % 3600) / 60)
local secondes=math.floor((trajet.temps % 3600) % 60)
ETA=os.date("%Hh%M",os.time()+trajet.temps)
duree=heures..'h'..minutes..'min'
table.insert(delai,trajet.temps)
trafic='Heure d\'arrivée: '..ETA..' - '..tostring(((math.floor(trajet.distance/100))/10))..'Km, '..duree
print(script..'Trajet: ' .. user .. ': '..trafic)
table.insert(commandArray,{['UpdateDevice']=otherdevices_idx['Trajet '..user]..'|0|'..trafic})
else
local incident = true
end
else
table.insert(delai,0)
end
---------------------------Si le smartphone se deplace je l'indique en deplacement dans l'adresse
if deplacement == true then
position='En deplacement'
print(script..'Adresse: '..user.. ': '..position)
---------------------------Sinon si il ne se deplace pas et qu'il etait en deplacement juste avant je recupere l'adresse
elseif deplacement == false and otherdevices['Adresse '..user]=='En deplacement' then
if google(device.latitudeGPS,device.longitudeGPS) ~= nil then
position=adresse..' ('..radiusSmartphone..' km)'
print(script..'Adresse: '..user..': '..position)
table.insert(commandArray,{['UpdateDevice']=otherdevices_idx['Adresse '..user]..'|0|'..position})
else
position=otherdevices['Adresse '..user]
local incident = true
end
end
--Mise a jour des informations
commandArray['Variable:GPS '..user] = device.latitudeGPS..","..device.longitudeGPS
end
table.sort(delai)
local intervale=math.floor(delai[1]*0.85)
if incident~=nil then
commandArray['Variable:updateGeoloc']='reload'
else
if intervale==0 or intervale>3600 then
intervale=3600
elseif intervale<120 then
intervale=120
end
local intervale=os.time()+intervale
local updateGeoloc=os.date('%d/%m/%Y %R',intervale)
commandArray['Variable:updateGeoloc']=tostring(updateGeoloc)
print(script..'Delai: '..tostring(updateGeoloc))
end
end
return commandArrayJ'ai eu un peu de mal a trouver une version avec explication. Donc voila le script en enregistrer en time dans vos événement.
J’espère vraiment avoir les capacités d’agrémenter ce script notamment avec celui de lestatcrog qu'il m'a gentiment envoyé pour ajouter d'autre fonctionnalité.
Evidemment si vous avez d'autre ajout a apporter !!!!