Big Brother regarde ... lui-même ou une carte avec l'historique des mouvements dans HomeAssistant

Entrée


Pour ma domotique, j'utilise HomeAssistant depuis longtemps. Une fois qu'un ami m'a demandé, ils disent, pourquoi HomeAssistant a la possibilité d'indiquer uniquement la position actuelle du tracker sur la carte, mais il n'est pas possible d'afficher l'itinéraire complet? Depuis lors, cette idée m'a captivé. Et une fois que j'ai réalisé que je voulais vraiment avoir cette fonction maintenant. Tous ceux qui sont intéressés par ce qui en est arrivé, bienvenue au chat…

Intelligence


En fait, pour afficher l'itinéraire, vous devez avoir un ensemble de points avec des coordonnées.La première étape consistait donc à savoir où le HomeAssistant stocke les données nécessaires (le cas échéant) et comment les extraire de là. Une brève étude de la source primaire a immédiatement conduit à la solution: vous avez besoin du module enregistreur inclus pour enregistrer l'état des capteurs souhaités dans la base de données à différents moments, ainsi que du module historique, qui vous permet d'obtenir de manière magnifique des données de la base de données. Le module d'historique possède une API REST bien documentée. Ce dont vous avez besoin!

Ensuite, vous devez en quelque sorte afficher les données reçues sur la carte. Il existe de nombreux services différents qui vous permettent d'afficher l'historique des mouvements. J'ai probablement essayé loin de tous, mais je me permettrai de dire quelques mots sur ceux que j'ai vérifiés:
A. yandex et google. En fait pour mes besoins il y a de tout et même plus, mais à cause des services payants et des fortes restrictions des versions gratuites, ils ne me convenaient pas tout de suite. Yandex, par exemple, permet une utilisation gratuite uniquement pour les projets ouverts (c'est-à-dire que n'importe qui devrait pouvoir ouvrir votre ressource à tout moment et profiter de ses capacités), sans parler d'autres restrictions sur le nombre de demandes. Seuls les paresseux n'ont pas écrit sur les modifications des politiques de Google concernant les API. Pour le moment, si je comprends bien, chaque demande de carte API ou de directions API est payée, plus il y a de demandes - moins cher. Cependant, chaque utilisateur disposant d'une carte bancaire connectée à son compte bénéficie d'une limite gratuite de 200 $ par mois. Tout sur le dessus est immédiatement payé à partir de votre carte. Lier une carte à un compte n'est pas notre façon.

Correct si j'ai fait une erreur quelque part sur google et / ou yandex.

B. Un tas de cartes OpenRouteService et OpenRouteService. En principe, les fonctionnalités ne sont pas très différentes de google ou yandex (en tout cas, je ne l'ai pas remarqué). Entièrement gratuit (il y a des restrictions sur le nombre de demandes par jour et par minute, s'il est dépassé, il est conseillé de contacter le support ... il n'y a aucune description des tarifs payés du tout). Cependant, l'utilisation de la ressource de cartes OpenRouteService s'est avérée gênante (chargement long de l'application et menu large ennuyeux à gauche, qui s'ouvre par défaut et n'est pas désactivé par l'API, de plus, le service ne s'ouvre pas correctement à partir d'appareils mobiles). En toute honnêteté, les cartes OpenRouteService peuvent être placées sur votre serveur et il est fort possible que vous puissiez tout configurer par vous-même.

B. Mapbbcode Je suis tombé sur une implémentation intéressante de cartes dans un format simple. En principe, le projet convient parfaitement à ma tâche, cependant, à partir de cet article, j'ai appris sur Leaflet et j'ai décidé de me tourner vers la source. Finalement, il s'y est arrêté ...

G. Dépliant. Très bonne bibliothèque js open-source pour les cartes, facile à apprendre et bien documentée. Depuis les puces: permet d'utiliser des tuiles de nombreux services (openstreetmaps, yandex, google, mapbox, microsoft, etc., etc.). De plus, j'ai utilisé le plugin leaflet.polylineDecorator pour indiquer la direction du mouvement sur la carte.

Il convient de mentionner que les deux dernières ressources considérées ne prennent pas en charge les «itinéraires», c'est-à-dire qu'elles ne savent pas comment connecter des points le long des routes et / ou des trottoirs existants, mais relient simplement les points avec une ligne droite. Pour moi personnellement, ce n'est pas un problème, mais une étape consciente. Si vous avez besoin de navigation sur les routes, vous devez regarder dans le sens de google, yandex ou openrouteservice gratuit.

Implémentation


La demande au module d'historique via l'API REST est assez simple (ci-après le code sera dans le langage HomeAssistant, c'est-à-dire python) et vous permet d'obtenir la réponse sous la forme d'un JSON facile à comprendre:

response = requests.get(self._haddr + '/api/history/period/' + dayBegin + '?filter_entity_id=' + self._myid, headers={'Authorization': 'Bearer ' + self._token, 'content-type': 'application/json'}) data = response.json()[0] 

ici self._haddr est l'adresse de votre HA identique à celle spécifiée dans les paramètres frontend, self._myid est l'identifiant de périphérique de device_tracker, dont nous allons construire l'itinéraire, dayBegin est le début de la période d'affichage de l'itinéraire, j'ai sélectionné le début de la journée en cours par défaut, self._token est un jeton longue durée pour accéder à l'API, qui peut être obtenu dans l'interface HomeAssistant.

Lorsque l'objet dont nous essayons d'afficher l'historique sur la carte est stationnaire pendant une longue période ou se déplace extrêmement lentement, nous obtenons un tas de points qui sont proches et obstruent la carte. Pour corriger la situation, laissez le tableau de coordonnées résultant passer à travers le filtre: si la distance entre le point précédent et le suivant est inférieure à 100 mètres, n'affichez pas le point sur la carte. Pour calculer les distances entre deux points voisins, nous utilisons une formule simplifiée avec une approximation équiangulaire . L'approximation est applicable lorsque la distance entre des points voisins ne dépasse pas plusieurs kilomètres:

  def getDistance(self, latA, lonA, latB, lonB): dst = 0 latRadA = math.radians(latA) lonRadA = math.radians(lonA) latRadB = math.radians(latB) lonRadB = math.radians(lonB) x = latRadB - latRadA y = (lonRadB-lonRadA)*math.cos((latRadB+latRadA)*0.5) dst = 6371*math.sqrt(x*x+y*y) return dst 

Ici dst est la distance en km.

Décrire l'API Leaflet ici ne comprend pas l'intérêt. Pour cela - sur le site officiel . Le module fonctionne comme suit: Toutes les n secondes (je l'ai fixé à 300), une requête est faite pour l'historique d'aujourd'hui de l'objet qui m'intéresse. Le tableau de coordonnées résultant est exécuté à travers le filtre de distance, ce qui réduit le nombre de points. De plus, dans le dossier avec la configuration HomeAssistant dans le dossier www, 2 fichiers sont formés: index.html et route.html. Le fichier route.html contient toute la logique de création d'une carte. Et le fichier index.html est un hack de vie pour empêcher la mise en cache des pages. Par défaut, HomeAssistant met en cache tout ce qui est possible, et la réinitialisation du cache uniquement a aidé à mettre à jour les données sur la carte, ce qui, bien sûr, est inacceptable. Dans le fichier index.html, le contenu de route.html est appelé, mais avec un paramètre aléatoire généré dynamiquement, qui vous permet de toujours demander la dernière version du fichier route.html au serveur:

 src = 'route.html?datetime=' + (new Date()).getTime() + Math.floor(Math.random() * 1000000) 

Un peu de sécurité


HomeAssistant est conçu pour que tous les fichiers à l'intérieur du répertoire www soient publics, c'est-à-dire que tout fichier à l'intérieur du répertoire www puisse être ouvert dans n'importe quel navigateur sans aucune autorisation, connaissant le lien direct. Dans le cas de mon module, ce lien est le suivant: your_address_homeassistant / local / route / index.html . Si cela n'est pas critique pour vous, vous pouvez ignorer cette section. Je suis allé un peu plus loin et j'ai vissé l'autorisation à la page des itinéraires. Pour cela, j'ai utilisé nginx (vous pouvez choisir un autre serveur Web avec prise en charge du proxy inverse) comme serveur proxy. Le site Web HomeAssistant contient des instructions officielles pour la configuration de cette configuration. Après avoir configuré le proxy et vérifié l'opération, vous devez ajouter une autorisation aux pages nécessaires dans la configuration nginx:

 location /local/route/route.html { proxy_pass http://localhost:8123/local/route/route.html; proxy_set_header Host $host; proxy_redirect http:// https://; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; auth_basic "Unauthorized"; auth_basic_user_file /etc/nginx/.htpasswd; } 

Créez ensuite le fichier "/etc/nginx/.htpasswd" et exécutez les commandes suivantes dans la console:

 sh -c "echo -n 'admin:' >> /etc/nginx/.htpasswd" sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd" 

admin - remplacez par la connexion désirée.

Après cela, redémarrez nginx et vérifiez: lorsque vous essayez d'ouvrir une page avec un itinéraire, le navigateur doit demander un nom d'utilisateur et un mot de passe. Je note qu'il s'agit d'une autorisation distincte qui n'a rien à voir avec l'autorisation de HomeAssistant elle-même.

Conclusion


Peut-être tout ce que l'on peut dire sur ce module.
Qui est intéressé, voici un lien vers le module. Placez le fichier le long du chemin: config_folder_homeassistant / custom_components / route / sensor.py, n'oubliez pas les droits.

S'il n'existe pas, créez le dossier config_folder_homeassistant / www et donnez-lui les droits appropriés.

Dans le fichier de configuration configuration.yaml, écrivez les lignes suivantes:

 sensor: - platform: route name: route entityid: your_device_tracker_entity_id haddr: your_address_homeassistant token: your_long_life_token 

ici your_device_tracker_entity_id est l'ID de votre appareil device_tracker, your_address_homeassistant est l'adresse externe de votre HomeAssistant, your_long_life_token est le jeton d'accès précédemment reçu dans le frontend HomeAssistant pour utiliser l'API REST.

Après cela, redémarrez HomeAssistant et profitez. La carte sera disponible via un lien direct: your_address_homeassistant / local / route / index.html . Si vous le souhaitez, vous pouvez l'ajouter au menu HA à l'aide de panel_iframe ou à n'importe quelle fenêtre HA via la carte de lacet «iframe».
C'est tout, merci de votre attention.

UPD:
Ajout d'un lien vers GitHub. Modification de certains endroits (supprimé de la configuration haddr, obtention automatique de config_dir, ajout de la possibilité de définir mon fuseau horaire)

Et à quoi tout cela ressemble-t-il? Attention, Bluer!
image

Source: https://habr.com/ru/post/fr448656/


All Articles