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]
landaisbenj
Messages : 695
Enregistré le : 12 mars 2017, 19:24

Re: Geolocalisation et info Iphone

Message par landaisbenj » 07 oct. 2019, 22:21

Génial!
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.


damolc
Messages : 114
Enregistré le : 24 juil. 2016, 22:08

Re: Geolocalisation et info Iphone

Message par damolc » 08 oct. 2019, 21:17

bonsoir
pour compléter mon message :

j ai mise le script sur un fichier lua dans domiticz/script/lua/ que j ai nommé script_time_geo.lua
j ai changé la ligne : Utilisateur1 = {username = "xxxxx@me.com" ; password = "xxxxxxxxxx" ; devicename = "Linux"
j ai mis mon UDID
j ai mis les valeurs de ma localisation :
local latitudeHome="xxxxxxxxx"
local longitudeHome="xxxxxxxx"
j ai créé une clef API sur mon adresse gmail
j ai crée des Dummy :
Présence Linux ; Batterie Linux ; Adresse Linux ; Trajet Linux
j ai crée des variable : GPS Linux (type de variable : Chaine, valeur de la variable : "vide" ? faut il mettre la position GPS du domicile?) ; "updateGeoloc" (type de variable : Chaine , valeur de la variable : "reload")
mais rien de fonctionne
j ai comme message en log : 2019-10-08 21:16:00.191 Error: EventSystem: in /home/pi/domoticz/scripts/lua/script_time_geo.lua: /home/pi/domoticz/scripts/lua/script_time_geo.lua:183: bad argument #1 to 'match' (string expected, got nil)

avez vous une explication?

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

Re: Geolocalisation et info Iphone

Message par landaisbenj » 08 oct. 2019, 21:35

Regarde à la ligne 183 du script. Dit nou ce qui est écrit qu’on remonte la piste.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

damolc
Messages : 114
Enregistré le : 24 juil. 2016, 22:08

Re: Geolocalisation et info Iphone

Message par damolc » 08 oct. 2019, 22:07

merci de ta reponse voila la ligne qui bloque :

local latitudeOld, longitudeOld = string.match(uservariables['GPS '..user], '(.*)%,'), string.match(uservariables['GPS '..user], '%,(.*)')

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 oct. 2019, 22:50

As tu essayé la mise à jour du script en dzvent?
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

damolc
Messages : 114
Enregistré le : 24 juil. 2016, 22:08

Re: Geolocalisation et info Iphone

Message par damolc » 08 oct. 2019, 23:19

landaisbenj a écrit :
08 oct. 2019, 22:50
As tu essayé la mise à jour du script en dzvent?
je ne sais pas faire ça :oops:

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

Re: Geolocalisation et info Iphone

Message par landaisbenj » 09 oct. 2019, 07:34

Supprime tout ton script, et recrée le avec le nouveau. Comme si tu repartais de zéro.
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

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

Re: Geolocalisation et info Iphone

Message par landaisbenj » 09 oct. 2019, 11:47

FredWst a écrit :
07 oct. 2019, 20:39
Bonjour,

J'ai ajouté la création automatique des objets, la position domicile est maintenant celle renseignée dans domoticz.
Pour la gestion des utilisateurs, c'est un peu plus compliqué à gérer de façon automatique …
Le seul moyen existant est de configurer dans le script. J'ai donc ajouté une option simple pour enable/disable un user.

Je mettrai à disposition dans les jours qui vienne.

Cdl
Fred
Pourquoi tu ne fais pas comme moi ? Une table, avec les utilisateurs dedans, et tu boucle sur la lecture de la table pour developper le code, ou mettre a jour les variables...
Rpbi3b: Domoticz + Homebridge + Monit + Freebox scripts + Shellinabox; Rpbi2: Jarvis
Domoticz: Derniere stable; RFLINK: Dernière stable; Xiaomi Gateway

FredWst
Messages : 19
Enregistré le : 03 oct. 2017, 21:24

Re: Geolocalisation et info Iphone

Message par FredWst » 09 oct. 2019, 22:01

Bnsoir,

Ci dessous le code actualisé avec la création d'objet, me reste a trouver le moyen de changer l'icon texte des objets.
J'ai vu un code python qui le fait … c'est donc probablement possible avec Dzvents.

Code : Tout sélectionner

-- *************************************************************************************************

-- Précision (en km) de detection de position au domicile ou de changement de position
local Precision=0.2

-- Trace 
local debug=true

-- Déclaration des utilisateurs.
-- Par défaut 3 utilisateurs possible.
-- name = "" -> utilisateur non utilisé.
-- Les devices nécéssaires sont créés automatiquement.
-- En cas de suppression d'un utilisateur, il faut supprimer les devices manuellement.

local users = {
                user1 = {name = "nom"; username = "adresse mail";   password = "mot de passe"};
                user2 = {name = "";  	username = "adresse mail";    password = "mot de passe"};
                user3 = {name = "";       username = "adresse mail";   password = "mot de passe"};
}

-- *************************************************************************************************



-- Fonction de calcul de distance
-- Renvoi la distance en kilometre a une decimale entre deux coordonées GPS
local function distancekm(latitude1, longitude1, latitude2, longitude2)
    rayonTerre = 6378137;   -- Rayon équatorial de la terre en metre
    radlatx = math.rad(latitude1);
    radlonx = math.rad(longitude1);
    radlaty = math.rad(latitude2);
    radlony = math.rad(longitude2);
    calculLatitude = (radlaty - radlatx) / 2;
    calculLongitude = (radlony - radlonx) / 2;
    detail = (math.sin(calculLatitude))^2 + math.cos(radlatx) * math.cos(radlaty) * (math.sin(calculLongitude))^2;
    calcul = 2 * math.atan(math.sqrt(detail), math.sqrt(1 - detail));
    output = math.floor((rayonTerre * calcul)/100)/10
    return output
end

-- Fonction de recuperation des informations icloud
-- Renvoi les informations du telephone (Position GPS, Batterie, Status...)      
local function iCloud(triggered)
    --On recherche le device associé au devicename de l'utilisateur
    for key,value in pairs(triggered.json.content) do
        if value.deviceClass == 'iPhone' 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
                result = {
                            batlvl = math.floor(value.batteryLevel * 100 / 1);
                            batstat = value.batteryStatus;
                            accuracy = value.location.isInaccurate;
                            latitudeiPhone = value.location.latitude;
        	                longitudeiPhone = value.location.longitude;
                            positionType = value.location.positionType;
                            timestampupdate = value.location.timeStamp;
        	                horizontalAccuracy = value.location.horizontalAccuracy
                         }	
                return result
            elseif value.isLocating == false or value.location == nil or value.location.isInaccurate == true or value.location.isOld == true or value.location.locationFinished == false then
                return nil
            else
                return nil
            end
        end
    end
end


-- Fonction de calcule d'itineraire
-- Renvoi dans une table le temps en minute et la distance en metre de trajet entre deux coordonées GPS
local function waze(dz, triggered)
    convert = dz.utils.fromJSON(triggered.data)
    routeTotalDistm = 0
    for key,value in pairs(convert.response.results) do
        routeTotalDistm = routeTotalDistm + value.length
    end
    if routeTotalDistm ~= nil and convert.response.totalRouteTime ~= nil then
        trajet = { temps = convert.response.totalRouteTime ; distance = routeTotalDistm }
        return trajet
    else
        return nil
    end
end

-- Recherche le user ayant déclenché httpResponses callback
local function findUser(dz,triggered)
    for usr,cpt in pairs(dz.data.users) do
        if string.find(triggered.callback,usr) then 
            return usr
        end
    end
end   

--Codage base64
local function encodeb64(data)
    local bb='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    return ((data:gsub('.', function(x) 
        r,b='',x:byte()
        for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
        return r;
    end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
        if (#x < 6) then return '' end
        c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
        return bb:sub(c+1,c+1)
    end)..({ '', '==', '=' })[#data%3+1])
end

local function jsonAPI(dz, apiCall)
	url = 'curl -s "'..dz.settings['Domoticz url']..'/json.htm?'..apiCall..'"'
	handle = assert(io.popen(url))
	result = handle:read("*a")
	handle:close()
	return dz.utils.fromJSON(result)
end	

--Crée virtual harware
local function createVirtualHardware(dz)
    jsonAPI(dz,"type=command&param=addhardware&htype=15&port=1&name=GeolocalisationDummy&enabled=true")
end

--Retourne idx du virtual harware s'il existe
local function isVirtualHardwareExist(dz)
    output = jsonAPI(dz,"type=hardware&filter=all&used=true&order=Name")
    if output ~= nil then
	    for index,result in pairs(output.result) do
            if result.Type == 15 then
                return result.idx
    	    end
        end
    end
	return -1        
end

--Retourne idx du device s'il existe
local function isVirtualDeviceExist(dz,device)
    output = jsonAPI(dz,"type=devices&filter=all&used=true&order=Name")
    if output ~= nil then
	    for index,result in pairs(output.result) do
            if result.Name == device then
                return result.idx
    	    end
        end
    end
	return -1
end

local function createObject(dz,nom)
    
    --Teste l'existance d'un virtual hardware
    index = isVirtualHardwareExist(dz)
    
    --Crée virtual harware s'il n'existe pas 
    if index == -1  then
       createVirtualHardware(dz) 
       index = isVirtualHardwareExist(dz)
    end
    
    if index then
        if isVirtualDeviceExist(dz,'Presence '..nom) == -1 then 
            jsonAPI(dz, "type=createvirtualsensor&idx="..index.."&sensorname=Presence%20"..nom.."&sensortype=6")
            id = isVirtualDeviceExist(dz, 'Presence '..nom)
            if id then 
                jsonAPI(dz, "type=setused&idx="..id.."&name=Presence%20"..nom.."&description=&strparam1&strparam2&protected=false&switchtype=0&customimage=18&used=true&addjvalue=0&addjvalue2=0&option")  
            end
        end
            
        if isVirtualDeviceExist(dz,'Adresse '..nom) == -1 then 
            jsonAPI(dz, "type=createvirtualsensor&idx="..index.."&sensorname=Adresse%20"..nom.."&sensortype=5")
            --id = isVirtualDeviceExist(dz, 'Adresse%20'..nom)
            --if id then 
            --    jsonAPI(dz, "type=setused&idx="..id.."&name=Adresse%20"..nom.."&description=&strparam1&strparam2&protected=false&switchtype=0&customimage=18&used=true&addjvalue=0&addjvalue2=0&option")  
            --end
        end
        
        if isVirtualDeviceExist(dz,'Trajet '..nom) == -1 then 
            jsonAPI(dz, "type=createvirtualsensor&idx="..index.."&sensorname=Trajet%20"..nom.."&sensortype=5")
            --id = isVirtualDeviceExist(dz, 'Trajet%20'..nom)
            --if id then 
            --    jsonAPI(dz, "type=setused&idx="..id.."&name=Trajet%20"..nom.."&description=&strparam1&strparam2&protected=false&switchtype=0&customimage=18&used=true&addjvalue=0&addjvalue2=0&option")  
            --end
        end
        
        if isVirtualDeviceExist(dz,'Batterie '..nom) == -1 then 
            jsonAPI(dz, "type=createvirtualsensor&idx="..index.."&sensorname=Batterie%20"..nom.."&sensortype=5")
            --id = isVirtualDeviceExist(dz, 'Batterie%20'..nom)
            --if id then 
            --    jsonAPI(dz, "type=setused&idx="..id.."&name=Batterie%20"..nom.."&description=&strparam1&strparam2&protected=false&switchtype=0&customimage=18&used=true&addjvalue=0&addjvalue2=0&option")  
            --end
        end
    end
end  


return {

	active = true,

	on = {
		timer = {'every 1 minutes'},
		httpResponses = {   'iClouduser1', 'wazeuser1', 'Adresseuser1',
		                    'iClouduser2', 'wazeuser2', 'Adresseuser2',
		                    'iClouduser3', 'wazeuser3', 'Adresseuser3'
                        }
	},
	
	--Variables persistantes initialisées au premier lancement du script par le système
	--Après les données sont mémorisées : obligation liée au principe du callback, les données doivent être non volatile entre appel
	--Le fichier de configuration ce trouve là -> domoticz/scripts/dzVents/data/ et se nomme __data_Geolocalisation.lua
    data = {
                users = { initial = {
                    
                                        user1 =  { 
                                                        latitudeiPhone = 0;
	                                                    longitudeiPhone = 0;
	                                                    DistanceDomicile = 0;
	                                                    deplacement = false;
	                                                    position = '';
	                                                    delai = 1;
                                        },
                                        user2  =  {
                                                        latitudeiPhone = 0;
	                                                    longitudeiPhone = 0;
	                                                    DistanceDomicile = 0;
	                                                    deplacement = false;
	                                                    position = '';
	                                                    delai = 6;
                                        },
                                        user3  =  {
                                                        latitudeiPhone = 0;
	                                                    longitudeiPhone = 0;
	                                                    DistanceDomicile = 0;
	                                                    deplacement = false;
	                                                    position = '';
	                                                    delai = 12;
                                        },
                                    }
                }
    },


	execute = function(domoticz, triggeredItem)

        -- Latitude et Longitude du domicile:
        latitudeDomicile=domoticz.settings.location.latitude
        longitudeDomicile=domoticz.settings.location.longitude


        --Déclenchement toutes les minutes aucun impact sur la durée batterie de l'iPhone 
        if (triggeredItem.isTimer) then

            --for user,compte in pairs(domoticz.data.users) do
            for user,compte1 in pairs(users) do    

                compte = domoticz.data.users[user]
        
                if compte1.name ~= '' then
 
                    createObject(domoticz, compte1.name)
                    
                    if debug then
                        print('Lancement demande de localisation '..compte1.name..' dans '..compte.delai..' seconde(s)')
                    end
                
                    domoticz.openURL({
                                        url =  'https://fmipmobile.icloud.com/fmipservice/device/'..compte1.username..'/initClient',
                                        headers =  {
                                                        ["Authorization"] = "Basic "..encodeb64(compte1.username..':'..compte1.password), --Type authentification basic fonctionne avec authentification deux facteurs
                                                        ["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"] = "iPad",
                                                        ["Accept-Language"] = "en-us",
                                                        ["Connection"] = "keep-alive",
                                                        ["Origin"] = "https://www.icloud.com"  
                                                    },
                                        method = 'POST',
                                        callback = 'iCloud'..user
                                    }).afterSec(compte.delai)     --compte.delai : Astuce pour décaler les demandes sinon waze n'aime pas !
                            
                end
            end
            
        elseif triggeredItem.isHTTPResponse and triggeredItem.ok then
                    
    	    if (triggeredItem.isJSON) then 
    	    
    	        --Test type de callback
                if string.find(triggeredItem.callback,'iCloud') then
                    
                    --Récupère le user qui génère le callback                
                    user = findUser(domoticz,triggeredItem)
                    compte = domoticz.data.users[user]
                    compte1 = users[user]
                    
                    --Fonction de recherche données uniquement deviceClass:iPhone voir filtre dans la fonction elle même en début de code
                    device = iCloud(triggeredItem)
                        
                    if device ~= nil then
                            
                        -- Ancienne position:
                        latitudePrecente = compte.latitudeiPhone
                        longitudePrecedente = compte.longitudeiPhone 
                            
                        -- Ancienne distance [position-domicile]:
                        DistanceDomicilePrecedente = distancekm(latitudePrecente, longitudePrecedente, latitudeDomicile, longitudeDomicile) 

                        -- Distance [nouvelle position-ancienne position]:       
                        EcartDistance = distancekm(device.latitudeiPhone, device.longitudeiPhone,latitudePrecente, longitudePrecedente)
                                    
                        -- Distance [nouvelle position-domicile]:       
                        compte.DistanceDomicile = distancekm(device.latitudeiPhone, device.longitudeiPhone, latitudeDomicile, longitudeDomicile)

                        --Presence: si la distance avec le domicile est inferieure à la précision souhaitée alors le smartphone est present au domicile
                        if compte.DistanceDomicile < Precision then --Presence
                            if domoticz.devices('Presence ' .. compte1.name).state == 'Off' then --Arrivée
                                domoticz.devices('Presence ' .. compte1.name).switchOn().silent()
                            end
                            compte.DistanceDomicile = 0
                        else
                            if domoticz.devices('Presence ' .. compte1.name).state == 'On' then
                                domoticz.devices('Presence ' .. compte1.name).switchOff().silent() 
                            end
                        end
                    
                        if debug then
                            print('Callback iCloud : '..compte1.name..': '..compte.DistanceDomicile..' km du domicile, '..device.batlvl..'% de batterie restante. Statut: "'..device.batstat..'". Precision: '..device.horizontalAccuracy)
                        end
                    
                        --Deplacement: si la distance avec l'ancienne position est superieure à la précision souhaitée alors le smartphone n'est plus au meme endroit et se deplace
                        if EcartDistance > Precision then
                            compte.deplacement = true
                            if DistanceDomicilePrecedente > compte.DistanceDomicile then
                                compte.position='En rapprochement du domicile'
                            else
                                compte.position='En éloignement du domicile'
                            end
                            
                            if debug then    
                                print('iPhone de '..compte1.name.. ': '..compte.position)
                            end
                        
                            domoticz.devices('Adresse '..compte1.name).updateText(compte.position)
                            if debug then
                                print('Lancement demande de trajet '..compte1.name)
                            end
                            
                            domoticz.openURL({
                                                url = 'https://www.waze.com/row-RoutingManager/routingRequest?from=x:'..longitudeDomicile..'+y:'..latitudeDomicile..'&to=x:'..device.longitudeiPhone..'+y:'..device.latitudeiPhone..'&at=0&returnJSON=true&returnGeometries=false&returnInstructions=false&timeout=30000&nPaths=1&clientVersion=1.0.0&options=AVOID_TRAILS:t,ALLOW_UTURNS:t',
                                                headers={["Content-Type"] = "application/json",["referer"]="https://www.waze.com"},
                                                method = 'POST',
                                                callback = 'waze'..user
                                            })                                   
                        else
                            if compte.deplacement == true and ( domoticz.devices('Adresse '..compte1.name).state=='En éloignement du domicile' or domoticz.devices('Adresse '..compte1.name).state=='En rapprochement du domicile') then
                                if debug then
                                    print("Lancement demande de l'adresse de "..compte1.name) 
                                end

                                domoticz.openURL({
                                                    url =  'https://api-adresse.data.gouv.fr/reverse/?lon='.. device.longitudeiPhone .. '&lat=' .. device.latitudeiPhone,
                                                    method = 'GET',
                                                    callback = 'Adresse'..user
                                                }) 
                            end
                            compte.deplacement = false
                        end

                        domoticz.devices('Batterie '..compte1.name).updateText('Niveau : '..device.batlvl..'%.\13\10 Statut : '..device.batstat)
                        
                        --Mémorisation nouvelle coordonnée iPhone
                        --Mise a jour des informations
                        compte.latitudeiPhone = device.latitudeiPhone
                        compte.longitudeiPhone = device.longitudeiPhone
                        
                    else 
                        print('Retour iCloud problème : '..compte1.name) 
                    end	    		    
                end
                
                --Test type de callback    
                if string.find(triggeredItem.callback,'Adresse') then
                    
                    --Récupère le user qui génère le callback        
                    user = findUser(domoticz,triggeredItem)
                    compte = domoticz.data.users[user]
                    compte1 = users[user]
                        
                    adresse = triggeredItem.json.features[1].properties.label
                    if adresse ~=nil then
                        compte.position=adresse..' ('..compte.DistanceDomicile..' km)'
                        if debug then
                            print('Callback Adresse : '..compte1.name..': '..compte.position)
                        end
                        domoticz.devices('Adresse '..compte1.name).updateText(compte.position)
                    else
                        print('Retour Adresse problème : '..compte1.name)
                        compte.position=domoticz.devices('Adresse '..compte1.name).state
                    end
                end
    	    else 
    	        --C'est bien un format JSON mais domoticz ne le detecte pas !
    	        --Test type de callback
    	        if string.find(triggeredItem.callback,'waze') then
    	            
    	            --Récupère le user qui génère le callback    
                    user = findUser(domoticz,triggeredItem)
                    compte = domoticz.data.users[user]
                    compte1 = users[user]
                        
                    trajet = waze(domoticz,triggeredItem)
                    if trajet ~= nil then
                        --Fonction waze retourne pour le trajet entre deux coordonées une table avec le temps en seconde et la distance en metre
                        heures=math.floor(trajet.temps / 3600)
                        minutes=math.floor((trajet.temps % 3600) / 60)
                        secondes=math.floor((trajet.temps % 3600) % 60)
                        ETA=os.date("%Hh%M",os.time()+trajet.temps)
                        duree=heures..'h'..minutes..'min'
                        trafic='Heure d\'arrivée: '..ETA..' - '..tostring(((math.floor(trajet.distance/100))/10))..'Km, '..duree
                        if debug then
                            print('Callback waze : ' .. compte1.name .. ': '..trafic)
                        end
                        domoticz.devices('Trajet '..compte1.name).updateText(trafic)
                    else
                        print('Retour Waze problème : '..compte1.name)
                    end
                end
    	    end
        end
	end
	
}

Fred

damolc
Messages : 114
Enregistré le : 24 juil. 2016, 22:08

Re: Geolocalisation et info Iphone

Message par damolc » 09 oct. 2019, 22:50

bonsoir
beau travail
ton script fonctionne parfaitement

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