Gérer dynamiquement un geofence "variable"

Bonjour,

Jeedom Core : 4.2.21
Version JC : 1.4.1
DNS Jeedom : oui

Equipements :
  Telephone : v1.4.0 sur android [os : 30] (polling)
  Telephone : v1.4.0 sur android [os : 30] (polling)

Je cherche à modifier automatiquement un point geofence.
Je le créé via l’interface du plugin sous Jeedom, comme ceci :

Ce que je cherche à faire, c’est de pouvoir mettre à jour ce geofence (latitude, longitude, rayon) sur événement, via un scénario et bloc code.
J’ai essayé différentes commandes afin de comprendre la structure et y accéder, mais en vain…

$scenario->setLog(print_r(cmd::byString("#[Dukei][Telephone][Variable]#")->getConfiguration()));
$scenario->setLog(print_r(eqLogic::byString("#[Dukei][Telephone]#")->getConfiguration()));
$scenario->setLog(count(eqLogic::byString("#[Dukei][Telephone]#")->getConfiguration()));
$scenario->setLog(count(eqLogic::byString("#[Dukei][Telephone]#")->getConfiguration(), COUNT_RECURSIVE));

$var=eqLogic::byString("#[Dukei][Telephone]#")->getConfiguration();
$max=count(eqLogic::byString("#[Dukei][Telephone]#")->getConfiguration());
for($i=0; $i<$max; $i++) $scenario->setLog($var[$i][0]);

cmd::byString("#[Dukei][Telephone][Variable]#")->setConfiguration('latitude', 0);

eqLogic::byString($geofence)->setConfiguration('latitude', $value);

Bref, si vous avez une idée, je suis preneur.
Merci d’avance.

2 « J'aime »

Peux tu mettre tes infos de config (comme d’habitude) ?
Ensuite, peut-être décrire ce que tu veux faire, parceque avoir un geofence variable, c’est quand même un peu en contradiction avec la notion de geofence.

Norbert

Bonjour,

Ce ne serait pas plus simple de calculer une distance entre 2 points ?

2 « J'aime »

Je veux bien aussi un descriptif du besoin final parce que je vois pas trop pour l’instant.
Creer un point fixe et un point dynamique permet deja pas mal de chose… meme 2 points dynamiques on peut faire quelque chose mais un geofence (par définition fixe) dynamique la je vois pas

Bonjour,

J’ai modifié mon 1er post avec les infos config, désolé pour l’oubli.

Alors, oui, je comprends votre incompréhension.
Mon cas d’usage est que la position « Boulot » pour ma femme change tous les jours.
Aussi, je voulais géré ça dynamiquement avec un geofence car ça implique de laisser l’application géré tout cela, le calcul de la distance, l’update des booléens des geofences (in /out), déclenchement des scénarios, etc… vu que tout est déjà en place.

Au final, je vais juste enregistrer la dernière position GPS reçue et dès que cette position est mise à jour, je mesure la distance avec la position enregistrée et si la distance > 500m, elle est partie.

Je voulais juste laisser le boulot être fait par Jeedom Connect et son appli.

Et, je vous vois venir ^^, ce n’est pas du flicage, c’est juste que c’est plus pratique pour nous deux pour nous notifier et s’organiser, au lieu de renvoyer un SMS au volant, quand on a oublié de le faire avant de partir…

Tu peux créer un geofence par lieu de travail et ensuite un virtuel « travail » de type binaire dont la formule est la suivante
(geofence1 == 1 || geofence2 == 1 || geofence3 == 1 || …)? 1 : 0

Ton virtuel « travail » sera ainsi à 1 dès lors que ta femme est sur un de ses lieux de travail et tu bases tes scenarios sur ce virtuel plutot que sur les geofences

Norbert

2 « J'aime »

Je n’ai pas répondu tout de suite car le « pourquoi » m’intéressait aussi.

Le bout de code pour modifier les positions sur le plugin n’est pas compliqué.
La problématique c’est que ces positions ne sont envoyées à l’application que lors du démarrage de celle-ci. Le inet out ne seront donc pas à jour et tu n’obtiendras pas ce que tu veux en l’état.

La proposition de @ngrataloup me semble assez pertinente.

2 « J'aime »

@tomitomas
Ok, je comprends mieux., donc ça ne marche pas.
J’avais dans l’idée de mettre à jour le geofence au moment où elle « ne bouge plus » et de lancer la commande « mettre à jour les données » sur l’appli, via scénario, via bloc code, comme suit :
cmd::byString("#[Dukei][Telephone][Modifier Préférences Appli]#")->execCmd(array("title" => "updateData", "message" => "ON"));
, mais cela , si j’ai bien compris, demande à l’application de recharger les données de jeedom, et non pas les données de l’application vers jeedom, donc ça ne marche pas.

@ngrataloup
Merci pour ta proposition, j’y avais pensé mais malheureusement elle peut faire des interventions sur tout un département, ce qui peut faire des dizaines de geofences donc ça peut vite devenir compliqué ^^

du coup le fait de pouvoir définir les zones à la main change quoi ??
si tu ne connais pas ces zones à l’avances, même via du code, comment est ce que tu vas les définir ?
:thinking:

1 « J'aime »

Et raisonnement à l’envers, alors …
Tu définis un geofence de 100, 200 ou 500m autour de chez toi, et si elle n’est pas dans ce geofence (geofence == 0), c’est qu’elle est ailleurs

Norbert

Je ne peux pas savoir à l’avance mais je pourrai savoir une fois arrivée (quand sa position GPS ne bouge plus ou très peu). Je stocke alors les coordonnées GPS dans un virtuel.
Lorsque sa position GPS sera remise à jour (départ ?), je calcule la distance entre le téléphone et la position « boulot du jour » enregistrée, via la formule de Haversine.
Si cette distance > 500m, elle a quitté le boulot et ça déclenche mes scénario habituels pour le geofencing.

Oui, ça je le gère.
Si aucun geofence == 1, alors le statut est « Sur la route ».
L’intérêt pour moi, comme dis au début, est surtout de savoir quand elle part le soir, pour qu’on s’organise pour la « 2ème journée », qu’on soit notifié en automatique plutôt que de bidouiller le téléphone au volant, si oublie d’envoi de message avant de prendre la route.

Tu peux utiliser ce tuto : Tuto : calculer la vitesse, la distance au domicile et le nb de km parcourus avec la geoloc

Il y a le calcul de la vitesse et de la distance au domicile … Tu sauras si elle est loin et si elle rentre …

ou celui là : Tuto : Integrer de manière dynamique Waze In Time à Jeedom Connect

En adaptant, tu devrais trouver ton bonheur pour avoir la distance au domicile, la vitesse actuelle et le temps de parcours

Merci beaucoup, je vais regarder cela tranquillement.

Avant de connaitre Jeedom Connect, le plugin et l’application, j’avais déjà réalisé tout cela (calcul distance, vitesse et temps de parcours, à la main et/ou avec le plugin Waze on time et plugin Geoloc. Mais là il s’agissait surtout de réutiliser, enfin de détourner l’utilisation des geofences intégré à Jeedom Connect.

En tous cas, merci à tous, pour toutes vos réponses et propositions, ça fait plaisir :smiley:

Pour info, ma solution à mon problème, si ça en intéresse certain.

Scénario « Situation » pour détecter la sortie du geofence « Maison » (géré par Jeedom Connect)

$trigger = cmd::cmdToHumanReadable($scenario->getRealTrigger());
$cmd = cmd::byString($trigger);
$cmd_name = $cmd->getName();
$cmd_value = $cmd->execCmd();
$eqLogicName = $cmd->getEqLogic()->getName();
$eqLogic = eqLogic::byId($cmd->getEqLogic()->getId());
$object = $eqLogic->getObject()->getName();

// Le geofence recherché ici est : #[Utilisateur][Telephone][Maison]#
if($object == "Utilisateur")
{
	if($cmd_value == 0)
	{
		cmd::byString("#[Utilisateur][Statut][Situation]#")->event("Route");
		if($cmd_name == "Maison")	// L'utilisateur est parti de la maison
		{
			// Lancement scénario "getWorkPlace" afin de déterminer le lieu "Boulot" du jour
			scenario::byId("41")->launch("Scénario", "Lancé par " . $scenario->getHumanName());
		}
	}
	else	// L'utilisateur est arrivé à destination "Maison"
	{
		// On calcule le temps du trajet depuis le départ de "Boulot"
		cmd::byString("#[Utilisateur][Statut][Situation]#")->event($cmd_name);
		$duration = time() - $scenario->getData(departUtilisateur);
		($duration >= 3600) ? $duration = ($duration / 3600 % 24).'h '.($duration / 60 % 60).'m' : $duration = ($duration / 60 % 60).'m';
		// Préparation du message de notification
		$titre = $object." situation";	$message = "Arrivée à \"".$cmd_name."\"<br>Durée du trajet : ".$duration;
		$options = array("title" => $titre, "message" => $message);
	}
}
cmd::byString("#[Dukei][Telephone][Notification]#")->execCmd($options);
cmd::byString("#[Utilisateur][Telephone][Notification]#")->execCmd($options);

Le scénario « getWorkPlace » est alors lancé, afin de déterminer le lieu « Boulot » du jour :

$cmd = cmd::byString("#[Utilisateur][Telephone][Position]#");
$GPS = $cmd->execCmd();
$valueDate = $cmd->getValueDate();
$scenario->setLog("Value date : ".$valueDate);

$tags = $scenario->getTags();
$tags["#delay#"] = time() - strtotime($valueDate);
if($tags["#delay#"] >= 300)  // Si les coordonnées GPS n'ont pas été mise à jour depuis plus de 5 minutes
{
	// On récupère les coordonnées GPS pour les mettre en forme et les sauvegarder
	list($lat, $lon) = explode(",", $GPS);
	$lat_degree = intval($lat);																		
	$lat_degree_minute = intval(($lat - $lat_degree) * 60);											
	$lat_degre_seconde = round((($lat - $lat_degree) * 60 - intval($lat_degree_minute)) * 60, 1);
	
	$lon_degree = intval($lon);																		
	$lon_degree_minute = intval(($lon - $lon_degree) * 60);											
	$lon_degre_seconde = round((($lon - $lon_degree) * 60 - intval($lon_degree_minute)) * 60, 1);	
	
	cmd::byString("#[Utilisateur][Localisation][GPS]#")->event($GPS);
	cmd::byString("#[Utilisateur][Statut][Situation]#")->event("Boulot");

	// Construction de l'url attendu par Maps pour afficher correctement la localisation
	// Encodage des URL HTML : %C2%B0 = ° et %22 = " (voir https://www.w3schools.com/tags/ref_urlencode.ASP)
	$url = "https://www.google.com/maps/place/".$lat_degree."%C2%B0".$lat_degree_minute."'".$lat_degre_seconde."%22N+".$lon_degree."%C2%B0".$lon_degree_minute."'".$lon_degre_seconde."%22E/@".$GPS.",15z";

	$options = array("title" => "L'utilisateur ne bouge plus", "message" => "Boulot du jour : <a href=".$url.">".$GPS."</a>");
	cmd::byString("#[Dukei][Telephone][Notification]#")->execCmd($options);
	cmd::byString("#[Utilisateur][Telephone][Notification]#")->execCmd($options);
}
$scenario->setTags($tags);

Et enfin, le scénario « Calcul distance » , qui est déclenché à la mise à jour de l’info #[Utilisateur][Telephone][Position]# , qui vérifie la distance entre le point « Boulot du jour » et le téléphone et qui permet donc de savoir si l’utilisateur a quitté ce geofence « perso » , et de déclencher les notifications qui vont bien :

$work = cmd::byString("#[Utilisateur][Localisation][GPS]#")->execCmd();		// Lieu "Boulot" du jour
list($lat1, $lon1) = explode(",", $work);	$lat1 = round($lat1, 7);	$lon1 = round($lon1, 7);
$phone = cmd::byString("#[Utilisateur][Telephone][Position]#")->execCmd();	// Position actuelle du téléphone
list($lat2, $lon2) = explode(",", $phone);	$lat2 = round($lat2, 7);	$lon2 = round($lon2, 7);

// Calcul de la distance entre deux points GPS
$R = 6371;
$dLat = deg2rad($lat2-$lat1);	$dLon = deg2rad($lon2-$lon1);
$lat1 = deg2rad($lat1);			$lat2 = deg2rad($lat2);

$a = sin($dLat/2) * sin($dLat/2) + sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = round($R * $c, 2);

cmd::byString("#[Utilisateur][Localisation][Distance]#")->event($d);		$scenario->setLog("Distance = ".$d." km");
if($d > 0.5)  // Si la distance est supérieur à 500 m
{
	cmd::byString("#[Utilisateur][Statut][Situation]#")->event("Route");
	
	// Calcul du temps moyen du trajet vers la maison (via le plugin "Waze in time")
	cmd::byString("#[Utilisateur][vers Maison][Rafraichir]#")->execCmd();	// Ces durées sont en minutes, et non pas en secondes
	$duration1 = cmd::byString("#[Utilisateur][vers Maison][Durée 1]#")->execCmd();
	$duration2 = cmd::byString("#[Utilisateur][vers Maison][Durée 2]#")->execCmd();
	$duration3 = cmd::byString("#[Utilisateur][vers Maison][Durée 3]#")->execCmd();
	
	$scenario->setData(departUtilisateur, time());	$average = 0;	$sum = 3;
	($duration1 > 0) ? $average += $duration1 * 60 : $sum--;
	($duration2 > 0) ? $average += $duration2 * 60 : $sum--;
	($duration3 > 0) ? $average += $duration3 * 60 : $sum--;
	
	if($sum > 1) $average = round($average / $sum);
	($average >= 3600) ? $duration = ($average / 3600 % 24).'h '.($average / 60 % 60).'m' : $duration = ($average / 60 % 60).'m';
	$arrival = date('H:i', time() + $average);
	
	// Préparation du message de notification
	$titre = "Utilisateur situation";	$message = "Départ de \"Boulot\"<br>Arrivée estimée à ".$arrival." (".$duration.")";
	$options = array("title" => $titre, "message" => $message);
	cmd::byString("#[Dukei][Telephone][Notification]#")->execCmd($options);
	cmd::byString("#[Utilisateur][Telephone][Notification]#")->execCmd($options);
}

Ce scénario est désactivé une fois le « geofence » quitté (pour éviter les déclenchements inutiles par la suite) et est (ré)activé par le scénario « getWorkPlace »

1 « J'aime »

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.