Page 3 sur 8

Re: Geolocalisation et info Iphone

Publié : 27 févr. 2018, 18:43
par landaisbenj
J'ai fini les evolutions de mon script. Basé sur tout ce qu'a pu m'apporter ce forum. (Le script est exactement le meme que les autes au final lol)

Je met a joue le premier post

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




--################################################################################################################################--
--##################                                    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



--################################################################################################################################--
--##################                                    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 -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://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

local delai = {}

---------------------------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

Re: Geolocalisation et info Iphone

Publié : 17 mai 2018, 20:07
par amelyfred
Salut
Bravo pour ce sript.
Si j'ai bien compris au départ tu souhaitais récupérer les données du calendrier iCloud.
As tu réussi car cela m'intéresse et je n'ai pour le moment rien trouvé.
Fred

Re: Geolocalisation et info Iphone

Publié : 17 mai 2018, 20:12
par landaisbenj
Salut. Merci. En fait c'était surtout pour magic mirror. J'ai bien réussi à récupérer le calendrier mais c'est le plugin de magic mirror qui s'en charge. Et j'ai du mettre mon calendrier en public ce qui n'est pas terrible.

Tu souhaitais récupérer le calendrier dans domoticz?

Re: Geolocalisation et info Iphone

Publié : 17 mai 2018, 22:33
par amelyfred
Je souhaiterais mettre un texte avec les rdv du jour à partir du calendrier family icloud

Re: Geolocalisation et info Iphone

Publié : 06 déc. 2018, 14:29
par Datawolf
[Mode déterrage=On]

Salut,

J'ai créé les devices et variables conformément à ta procédure, copié/collé ton script et l'ai paramétré.
Malheureusement j'ai une erreur sur le decode du json de icloud, il semblerait que result soit vide.
Sais-tu comment je pourrais débugger ça ?

@+
Datawolf

Re: Geolocalisation et info Iphone

Publié : 06 déc. 2018, 22:11
par Datawolf
J'ai légèrement modifié le script, et j'obtiens une réponse, avec apparemment toutes les réponses attendues (et bien plus !) mais le format json est invalide :evil:

Re: Geolocalisation et info Iphone

Publié : 06 déc. 2018, 23:16
par landaisbenj
Tu pourrais coller les différents messages? Je regarderai ça dès que je peux. Ça fait une plombe que je dois relancer le script et je ne l'ai toujours pas fait :\

Re: Geolocalisation et info Iphone

Publié : 07 déc. 2018, 10:44
par Datawolf

Code : Tout sélectionner

attempt to index global 'json' (a nil value)
J'ai entrepris de modifier le résultat "result" pour en extraire la substantifique moelle. Je touche au but, je le sens, mais je ne sais pas quel format est attendu par ton "for key,value in pairs(output.content)".

J'arrive à ça mais j'ai toujours la même erreur sur le json.decode(result)

Code : Tout sélectionner

{"isLocating":true,"modelDisplayName":"iPhone","lostTimestamp":"","batteryLevel":0.7300000190734863,"mesg":null,"locationEnabled":true,"lockedTimestamp":null,"locFoundEnabled":false,"snd":null,"fmlyShare":false,"lostDevice":null,"lostModeCapable":true,"wipedTimestamp":null,"deviceDisplayName":"iPhone 5c","prsId":null,"audioChannels":[],"locationCapable":true,"batteryStatus":"NotCharging","trackingInfo":null,"name":"iPhone de Datawolf","isMac":false,"thisDevice":false,"deviceClass":"iPhone",
"location":{"isOld":false,"isInaccurate":false,"altitude":0.0,"positionType":"Cell","latitude":99.01234567891234,"floorLevel":0,"horizontalAccuracy":65.0,"locationType":"","timeStamp":1544175431580,"locationFinished":true,"verticalAccuracy":0.0,"longitude":9.123456789012345},"deviceModel":"5c-3b3b3c-f5f4f7","maxMsgChar":160,"darkWake":false,"remoteWipe":null}

Re: Geolocalisation et info Iphone

Publié : 08 déc. 2018, 13:31
par Datawolf
Salut,
Bon j'ai réussi à extraire toutes les données iCloud avec string.sub
Je détermine donc correctement la présence et la batterie. 8-)
Malheureusement j'ai un pb avec waze. Du coup j'ai entré l'url dans mon nagigateur => 403 Forbidden :(
@+
Datawolf

Re: Geolocalisation et info Iphone

Publié : 08 déc. 2018, 18:44
par landaisbenj
Ok cool. J'ai vu sur l'autre sujet qui traite du temps de trajet qu'il y avait un soucis avec waze. Du coup je vais relancer mon script quand meme pour voir.