Tuto : calculer la vitesse, la distance au domicile et le nb de km parcourus avec la geoloc

Un petit tutoriel pour agrémenter Jeedom Connect de quelques données associées à la geolocalisation
Ce tuto est réalisé sur la base des infos de JC mais n’importe quel équipement remontant une géolocalisation (et le type d’activité ) peut être utilisé !
Il est réalisé pour calculer les données pour plusieurs membres de la famille

Voilà le résultat final coté Jeedom Connect, avec pour l’affichage des données calculées, l’utilisation du widget résumé de pièce. les icone s de la distance au domicile ainsi que celui de la vitesse, évoluent en fonction de la valeur via des images conditionnelles sur JC.

image

Et voici la méthode utilisée, assez classique → crearion d’un virtuel → creation d’un scenario → creation des widgets coté JC

1 - Implémenter autant d’équipement que nécessaire remontant la localisation et le type d’activité au sens android (pour ma part, 1 téléphone par membre de la famille avec JC dessus, avec ma geolocalisation activée)

2 - créer un équipement virtuel avec les commandes

  • Vitesse
  • Distance au domicile
  • Nb de kilomètres d’activité physique (hors déplacements en voiture - ‹ in_vehicule ›) - le petit plus santé :wink:

pour ma part, j’ai prefixer ces commandes des différents prénoms des membres de la famille pour realiser les calculs pour tous les membres

3 - Mettre en place le scenario ci-dessous pour calcul de l’ensemble des commandes :

  • Vitesse
  • Distance au domicile
  • Nb de kilomètres d’activité physique

Le scenario est lancé toutes les minutes (planifié) et non pas de manière provoquée (au changement de la geoloc car les changements ont lieux plusieurs fois par minute en cas de déplacement et génère du coup beaucoup beaucoup trop de lancements du scenario.
il utilise un unique bloc code
A paramétrer :
La liste des membres de la famille (qui permet de générer les déclinaisons des commandes / membre
la commande remontant la position et l’activité (incluant la variable définie ci-dessus)
les différentes commandes qui ont été implémentées ci-dessus pour renseigner la vitesse, la distance et le nb de km
($cmd_vitesse, $cmd_distance_jours_enCours, $cmd_distance_domicile)
la variable precisant les corrdonnées GPS du domicile (il est sans doute possible de recuperer les coordonnées definies dans Jeedom, mais je ne sais pas faire !!! :roll_eyes:)

EDIT du 8/12 : correction de quelques bugs dans le script et recupération suite à conseils de @chris94440 des coordonnées du domicile dans les paramétrages Jeedom

$noms = array('xxxx','xxxx','xxxxx','xxxxx','Norbert');

// variables utilisées plusieurs fois dans le bloc code
// Necessite que la latitude et la longitude du domicile soient integrés dans les paramétrages jeedom
$heure = time();
$latDom = deg2rad(config::byKey('info::latitude','core'));  // coordonnées domicile en rad
$lonDom = deg2rad(config::byKey('info::longitude','core')); // coordonnées domicile en rad


foreach ($noms as $nom) {
	// Commande position
	$cmd_position = '#[' . $nom . '][JeedomConnect_' . $nom . '][Position]#' ;
    $cmd_activite = '#[' . $nom . '][JeedomConnect_' . $nom . '][Activité]#' ;
    // Commandes à créer  
    $cmd_vitesse = '#[Famille][Geoloc Famille]['.$nom.'_Vitesse]#' ;
  	$cmd_distance_jour_enCours = '#[Famille][Geoloc Famille]['.$nom.'_Distance_jour_enCours]#' ;
    $cmd_distance_domicile = '#[Famille][Geoloc Famille]['.$nom.'_Distance]#' ;
  
    // variables necessaires au script
  	$var_coord_prec = $nom .'_coordonnees_gps_prec' ;  // creer automatiquement
  	$var_time_coord_prec = $nom.'_coordonnees_gps_time_prec' ;  // creer automatiquement
    $var_distance_jour = $nom.'_distance_jour' ;  // creer automatiquement
    
  
  	// recuperation des coordonnées GPS  (array[0] pour la longitude, array[1] pour la lattitude
  	$coord_gps_actuel = explode("," , cmd::byString($cmd_position)->execCmd() ); //coordonnées GPS actuelles
    $activite = cmd::byString($cmd_activite)->execCmd(); // activité
	$coord_gps_prec = explode("," , $scenario->getData($var_coord_prec) ); // coordonnées GPS precedent calcul
    $coord_gps_domicile = explode("," , $scenario->getData($var_coord_domicile) );  // coordonnées GPS domicile
    $vitesse_prec = cmd::byString($cmd_vitesse)->execCmd() ; // vitesse precedente
    
  	// Si les coordonnées GPS n'ont pas changées - la vitesse et la distance au domicile n'ont pas changé depuis le dernier calcul
    // on met juste à jour le timestamps
  	if ( $coord_gps_prec[0] == $coord_gps_actuel[0] and $coord_gps_prec[1] == $coord_gps_actuel[1] ) {
      	$vitesse = 0 ;
      	if ( $vitesse_prec != 0 ) cmd::byString($cmd_vitesse)->event($vitesse) ;
      	$scenario->setData($var_time_coord_prec, $heure ) ;
//log  	$scenario->setLog('vitesse '.$nom.' : '.$vitesse.' km/h');
      	$scenario->setLog('Geolocalisation '.$nom.': Pas de mouvement');
   }
  	else {
        $scenario->setLog('Geolocalisation '.$nom.':');
		// les coordonnées GPS ont changées, calcul de la vitesse 
      	
      	// Conversion des coordonnées GPS de degrés en radians
		$latFrom = deg2rad($coord_gps_prec[0]);
		$lonFrom = deg2rad($coord_gps_prec[1]);
		$latTo = deg2rad($coord_gps_actuel[0]);
		$lonTo = deg2rad($coord_gps_actuel[1]);
		$earthRadius = '6371000' ;
      
	  	// Calcul de la distance entre les 2 points GPS
	  	$lonDelta = $lonTo - $lonFrom ;
		$a = pow(cos($latTo) * sin($lonDelta), 2) + pow(cos($latFrom) * sin($latTo) - sin($latFrom) * cos($latTo) * cos($lonDelta), 2);
		$b = sin($latFrom) * sin($latTo) + cos($latFrom) * cos($latTo) * cos($lonDelta);
		$angle = atan2(sqrt($a), $b);
	
	  	// Calcul de la vitesse en km/h
  		$coord_gps_time_prec = $scenario->getData($var_time_coord_prec) ;
        $distance = $angle * $earthRadius ;
      	$vitesse = $distance / ( $heure - $coord_gps_time_prec) * 3600 / 1000 ;
  
  		if ( $vitesse < 0.5 ) $vitesse = 0 ;   // Si vitesse < 0.5, vitesse == 0
        elseif ( $vitesse >= 10 ) $vitesse = round($vitesse,0)  ;  // Si vitesse > 10 , Precision sans chiffre après la virgule
    		else $vitesse = round($vitesse,1) ;
    	
      	// calcul de la distance faite / jour  ==> enregistrement
      	if ( $activite !=  'in_vehicle' ) {
          $distance_jour = $scenario->getData($var_distance_jour) ;
          $distance_jour = $distance + $distance_jour ;
          $scenario->setData($var_distance_jour, $distance_jour ) ;
          
          // enregistrment de la distance réalisée aujourdhui hors voiture
          $scenario->setLog('  --> Distance du jour : '.round($distance_jour/1000,1).'km ('.$activite.')');
          cmd::byString($cmd_distance_jour_enCours)->event( round($distance_jour/1000,1));
        }
      
        // calcul de la distance au domicile
        $lonDelta = $lonDom - $lonTo ;
	$a = pow(cos($latDom) * sin($lonDelta), 2) + pow(cos($latTo) * sin($latDom) - sin($latTo) * cos($latDom) * cos($lonDelta), 2);
	$b = sin($latTo) * sin($latDom) + cos($latTo) * cos($latDom) * cos($lonDelta);
	$angle = atan2(sqrt($a), $b);
        $distfromdom = $angle * $earthRadius / 1000 ;
        if ( $distfromdom <= 10 ) $distfromdom = round($distfromdom,1) ;
        else $distfromdom = round($distfromdom,0) ;
		// 	$scenario->setLog('vitesse '.$nom.' : '.$vitesse.' km/h');
		// 	$scenario->setLog('distance '.$nom.' : '.$distfromdom.' km');	
      
      	// Renseignement de la commande vitesse et distance au domicile
  		cmd::byString($cmd_vitesse)->event($vitesse);
        cmd::byString($cmd_distance_domicile)->event($distfromdom);
        $scenario->setLog('  --> Vitesse : '.$vitesse.'km/h');
        $scenario->setLog('  --> Distance domicile : '.$distfromdom.'km');
    	$scenario->setData($var_time_coord_prec, $heure ) ;   // dernier temps
  		$scenario->setData($var_coord_prec, $coord_gps_actuel[0].','.$coord_gps_actuel[1] ) ;  // dernieres coordonnées
        
	}
}

A noter que le calcul ne se réalise QUE si les coordonnées GPS ont changé depuis le dernier calcul.

(scenario sans doute très perfectible, je ne suis pas développeur, et ne connaissait pas le php il y a 6mois !!!)

4 - creer un scenario qui se lance à 23h59 et qui remet à 0 la variable $var_distance_jour définie au dessus

5 - il ne reste plus qu’à implémenter les commandes info créées dans Jeedom connect. j’ai opté pour les résumés de pièce mais ceci peut être fait via des widgets génériques numériques et/ou via des résumés (tout court).

Voilà, en plus de la géolocalisation, vous avez dans JC, la distance au domicile, la vitesse instantanée (enfin sur la dernière minute) et le nb de km d’activité physique de la journée !

Bonne implémentation pour ceux que ca intéresse

12 « J'aime »

Hello
Super partage.
Pour les latitudes et longitudes tu peux récupérer celle de jeedom comme ci-dessous (stockées dans la database config)

config::byKey('info::latitude','core');
config::byKey('info::longitude','core');

@chris94440

Update :
Après pour ne pas créer un scénario pour réinitialiser la variables vu qu’il est schedulé toutes les minutes tu peux tester l’heure et les minutes et si 23h59 faire l’init

//init variable tous les jours
if ((date('H')  == '23') and (date('i')  == '59') ) {
	$scenario->setLog('	-> init distance jour à 0');
	$scenario->setData($var_distance_jour, 0 ) ;
}
2 « J'aime »

Merci, trop cool la recup de la longitude et de la lattitude !!!

1 « J'aime »

@ngrataloup n’y a t il pas une erreur sur ce test

if ( $coord_gps_prec[0] == $coord_gps_prec[0] and $coord_gps_prec[1] == $coord_gps_actuel[1] ) {

qui devrait être plutot

if ( $coord_gps_prec[0] == $coord_gps_actuel[0] and $coord_gps_prec[1] == $coord_gps_actuel[1] ) {

non ?

Bien-sûr que c’est une erreur ! Je corrigerai sur le post
Merci pour la vérif

Peux tu me donner stp le nom de l icone que tu utilises pour l’activité physique … j’arrive pas à la trouver …:unamused:

ce sont les icones material design :

  1. human-male
  2. walk
  3. run
  4. run-fast

Non pas celle la celle que tu utilises pour l’activité physique

Oups, desolé …
Material design → map-marker-distance

J’ai mis à jour le code suivant tes conseils pour les coordonnées du domicile et la correction du bug.
Merci !

1 « J'aime »

Du coup suite derniers échanges sur l’autre fil je regarde ta manière de faire.
Quelques questions :

  • comment calcules tu l’activité physique par rapport à un déplacement en voiture ,
  • la distance calculée est une distance via une ligne entre 2 points exacts ?
    (Du coup si on veut la distance et temps de route, faudrait appeler les plugins geotrac ou geoloc)
    Joli en tout cas le script

On utilise la commande info activité qui une notion remontée par le telephone. Il y a quelques threads sur le sujet

Oui

Tu as raison @loic69 … j’y avais pensé mais je ne m’étais pas penché dessus … moyennant la souscrition à l’api google distance il est possible d’avoir la vraie distance entre 2 position

Si besoin je peux fournir un exemple d’utilisation

Oui merci j’ai vu ton autre poste.
Il y a aussi la solution par les plugin geoloc et geotrav. Avec l’API Google en sous jacent

Oui mais ça fait des surcouches mais c’est une solution …:grin:

1 « J'aime »

Hello tout le monde,
Bon, j’ai quelque peu galérer à tout mettre en place et adapter ce Tuto à mon fonctionnement, mais, whaoouh, ca fonctionne du feu de Dieu !
Merci @ngrataloup ! et aux autres Jeedomiens (@chris94440 @loic69) qui m’ont éclairé à travers les échanges que vous aviez entre vous :smiley:

Bonne continuation à tous :slight_smile:

2 « J'aime »

Hello
@ngrataloup

J’ai mis en place ce tuto , sauf que je me retrouve avec des grandes distance. :thinking:

11

Tu as bien renseigné les données GPS de ton domicile dans les paramétrages jeedom ?

Re,

Oui

Je pense qu’il y a un pb dans ton bloc code sur la récupération des variables créée automatiquement. Envoie en mp un screenshot de tes variables et de ton scénario

C’est fait @ngrataloup