Geolocalisation et info Iphone

Vous avez crée un script lua dont vous êtes fier, un .sh génial, un programme python hors du commun, un tuto , c'est ici que vous pouvez les partager.
Soyez précis quant aux prérequis, les manips à faire pour que votre bijou fonctionne (des chmod ?, un apt-get à faire ...)
Décrivez précisément son fonctionnement
Placez votre code entre [Quote] et {/Quote]
Répondre
landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Geolocalisation et info Iphone

Message par landaisbenj » 01 déc. 2017, 22:58

Bonjour.

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):
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
Vous n'avez qu'a activer le findmyiphone d'icloud (localisation), renseigner vos paramètres et créer les devices nécessaire.



[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
Dummy 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"
Ou le nom User est le nom du device


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 commandArray
Vous pourrez donc avoir l'adresse de localisation, le temps de trajet pour revenir au domicile, le niveau de votre batterie (bienvenu les logs afin de connaitre la durée de charge) et donc contrôler votre entrée dans la maison.

J'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 !!!!
Modifié en dernier par landaisbenj le 07 mars 2019, 10:57, modifié 6 fois.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Re: Geolocalisation et info Iphone

Message par landaisbenj » 01 déc. 2017, 23:13

Pour la suite, j'aimerai gérer l'intervalle par rapport a la distance. Aucun interet de localiser le telephone lorsqu'il est a plus de 100km mais doit etre de plus en plus precis une fois qu'il se rapproche (1h au dela de 100km, 30min entre 100 et 50km, 10minute entre 30 et 20 ect... mais a moins de 5 km le faire toute les minutes).

Ensuite je pourrais peut être plutôt trouver un moyen d'indiquer si je me rapproche ou si je m’éloigne... (Si je m’éloigne aucun intérêt de localiser tout cours...).

[EDIT] Bon a force de chercher je pense qu'il est impossible de ne pas localiser même pour X raison. Donc je me cantonnerai a localiser tous les x temps en rapport avec mon temps de retour. Je pense faire 2 appels obligatoires pour éviter le soucis de la requête dans le vide (si le tel n'est pas encore localiser) et séparer ces deux appels par le temps de trajet moins 15%


Je crois que le script que j'ai recu à l'air d'etre codé pour cela je pense. Donc tout ca pourras aider.
Modifié en dernier par landaisbenj le 29 janv. 2018, 11:17, modifié 1 fois.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

le belge
Messages : 346
Enregistré le : 12 déc. 2016, 19:02

Re: Geolocalisation et info Iphone

Message par le belge » 03 déc. 2017, 14:48

Bonjour ,

après quelques soucis avec les users et le mot de passe (bien respecter l'écriture)
ça fonctionne !

va falloir que je fasse des tests en déplacement mais pour l'instant mon iphone est bien vu dans domoticz avec le % batterie

merci à toi pour ce script

Mike

le belge
Messages : 346
Enregistré le : 12 déc. 2016, 19:02

Re: Geolocalisation et info Iphone

Message par le belge » 07 déc. 2017, 18:42

'soir ,

j'ai une erreur dans les logs , pourtant le script fonctionne parfaitement ??

Code : Tout sélectionner

Error: EventSystem: in test2 : [string "-- Script to check the location of multiple i..."]:28: attempt to index field '?' (a nil value)
la ligne 28 :

Code : Tout sélectionner

return output.results[1].formatted_address

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Re: Geolocalisation et info Iphone

Message par landaisbenj » 08 déc. 2017, 17:40

Oui j'ai eu un probleme similaire. Je crois que c'est la fonction qui renvoi l'adresse via google. Sauf qu'a mon avis y a un timer, du coup de temps en temps il n'a pas de retour de google donc tu as une valeur nil en return de fonction.

Perso je l'ai viré car je n'avais pas besoin de l'adresse postal mais juste du km.

A mon avis tu fais des requetes trop souvent non ? Tu as du réduire l'intervale je pense.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

le belge
Messages : 346
Enregistré le : 12 déc. 2016, 19:02

Re: Geolocalisation et info Iphone

Message par le belge » 08 déc. 2017, 17:57

Salut ,

c'est bizarre ; je fais des requêtes toutes les 5 min ... pour l'instant, je pense passer à 10 min

sinon le script fonctionne nickel

merci à toi

landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Re: Geolocalisation et info Iphone

Message par landaisbenj » 08 déc. 2017, 18:01

Si tu fais un print de ce que retour la fonction google, tu verras quand ca fonctionne ca renvoi toutes les données, quand ca fonctionne pas ca te renvoi un status. Moi c'etait TIMEOUT a chaques fois...
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

le belge
Messages : 346
Enregistré le : 12 déc. 2016, 19:02

Re: Geolocalisation et info Iphone

Message par le belge » 08 déc. 2017, 18:12

j'ai encore du mal avec les print , je ne sais jamais ce que je dois mettre en parenthèse !!!

landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Re: Geolocalisation et info Iphone

Message par landaisbenj » 08 déc. 2017, 18:20

Tu t'en fiche. Tu met n'importe quoi tant que c'est reconnaissable.

Moi par exemple quand je fais un script je fait ca:

Code : Tout sélectionner

test=0
Et je colle ca partout:

Code : Tout sélectionner

test=test+ 1
print('Passage test: "..test)
Comme ca tu identifie direct ou ca coince.

Mais dans ton cas je sais que ca bloque dans la fonction de google du coup il suffit de print le resultat de la requete sur le site de google:

Code : Tout sélectionner

  function address(longitude, latitude)
  --variable de l'adresse:
    command = "curl -s https://maps.googleapis.com/maps/api/geocode/json?latlng=" .. latitude .. "," .. longitude .. "&sensor=false"
  --variable de la commande d'interrogation a l'adresse
    local handle = io.popen(command)
  --variable du resultat de l'interrogation
    local result = handle:read("*a")
  --fermeture de l'interrogation
    handle:close()
  --decodage du json
    output = json:decode(result)
  --Impression de tout le retour decoder.
    print(result)
    return output.results[1].formatted_address
  end
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

le belge
Messages : 346
Enregistré le : 12 déc. 2016, 19:02

Re: Geolocalisation et info Iphone

Message par le belge » 08 déc. 2017, 18:27

vous êtes des fous !!!
faut vraiment que j'apprenne à travailler les scripts ...
pour l'instant je copie ce que je trouve !!!

mais dès qu'il faut modifier , je suis à la traîne ...

Merci

Disable adblock

This site is supported by ads and donations.
If you see this text you are blocking our ads.
Please consider a Donation to support the site.


Répondre