Gran hermano está mirando ... a sí mismo o un mapa con la historia de los movimientos en HomeAssistant

Entrada


Para mi automatización del hogar, he estado usando HomeAssistant durante mucho tiempo. Una vez que un amigo me preguntó, me dijeron, ¿por qué HomeAssistant tiene la capacidad de indicar solo la posición actual del rastreador en el mapa, pero no es posible mostrar la ruta completa? Desde entonces, esta idea me ha capturado. Y una vez que me di cuenta de que realmente quiero tener esta función en este momento. Todos los que estén interesados ​​en lo que vino de esto, bienvenidos al gato ...

Inteligencia


En realidad, para mostrar la ruta necesita tener un conjunto de puntos con coordenadas, por lo que el primer paso fue averiguar dónde almacena HomeAssistant los datos necesarios (si es que los hay) y cómo sacarlos de allí. Un breve estudio de la fuente condujo inmediatamente a la decisión: necesita el módulo grabador incluido para registrar el estado de los sensores deseados en la base de datos en diferentes momentos, así como el módulo de historial, que le permite obtener datos de la base de datos de una manera hermosa. El módulo de historia tiene una API REST bien documentada. Lo que necesitas!

A continuación, debe mostrar de alguna manera los datos recibidos en el mapa. Existen muchos servicios diferentes que le permiten mostrar el historial de movimientos. Probablemente probé lejos de todos ellos, pero me permitiré algunas palabras sobre las que verifiqué:
A. Yandex y Google. En realidad, para mis necesidades, hay de todo y aún más, pero debido a los servicios pagos y las fuertes restricciones de las versiones gratuitas, no me convenían de inmediato. Yandex, por ejemplo, permite el uso gratuito solo para proyectos abiertos (es decir, cualquiera debería poder abrir su recurso en cualquier momento y aprovechar sus capacidades), sin mencionar otras restricciones en el número de solicitudes. Solo los perezosos no escribieron sobre los cambios en las políticas de Google con respecto a la API. Por el momento, según tengo entendido, cada solicitud de mapas api o direcciones api se paga, cuantas más solicitudes, más barato. Sin embargo, cada usuario con una tarjeta bancaria conectada a su cuenta recibe un límite gratuito de $ 200 por mes. Todo en la parte superior se paga inmediatamente de su tarjeta. Vincular una tarjeta a una cuenta no es nuestro camino.

Corrija si cometí un error en algún lugar sobre google y / o yandex.

B. Un montón de mapas OpenRouteService y OpenRouteService. En principio, las capacidades no son muy diferentes de google o yandex (en cualquier caso, no me di cuenta). Completamente gratis (hay restricciones en la cantidad de solicitudes por día y por minuto, si se excede, se recomienda contactar al soporte ... no hay una descripción de ninguna tarifa pagada). Sin embargo, el uso del recurso de mapas OpenRouteService resultó ser un inconveniente (carga prolongada de la aplicación y el molesto menú ancho a la izquierda, que se abre de forma predeterminada y no está deshabilitado por la API, además, el servicio no se abre correctamente desde dispositivos móviles). Para ser justos, los mapas de OpenRouteService se pueden colocar en su servidor y es muy posible que allí pueda configurar todo usted mismo.

B. Mapbbcode Me topé con una implementación interesante de tarjetas en un formato simple. En principio, el proyecto es absolutamente adecuado para mi tarea, sin embargo, de este artículo aprendí sobre Leaflet y decidí recurrir a la fuente. Al final, se detuvo en eso ...

G. Folleto Muy buena biblioteca js de código abierto para mapas, fácil de aprender y bien documentada. Desde los chips: le permite usar mosaicos de muchos servicios (openstreetmaps, yandex, google, mapbox, microsoft, etc., etc.). Además, utilicé el complemento leaflet.polylineDecorator para indicar la dirección del movimiento en el mapa.

Vale la pena mencionar que los dos últimos recursos considerados no admiten "rutas", es decir, no saben cómo conectar puntos a lo largo de carreteras y / o aceras existentes, sino que simplemente conectan los puntos con una línea recta. Para mí personalmente, esto no es un problema, sino un paso consciente. Si necesita navegación en las carreteras, entonces debe mirar en la dirección de google, yandex o servicio gratuito de openroutes.

Implementación


La solicitud al módulo de historial a través de REST-API es bastante simple (en adelante, el código estará en el lenguaje HomeAssistant, es decir, python) y le permite obtener la respuesta en forma de JSON simple para comprender:

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] 

aquí self._haddr es la dirección de su HA igual a la especificada en la configuración de la interfaz, self._myid es la identificación del dispositivo de device_tracker, cuya ruta construiremos, dayBegin es el comienzo del período para mostrar la ruta, seleccioné el comienzo del día actual de forma predeterminada, self._token es un token de larga duración para acceder a la API, que se puede obtener en la interfaz HomeAssistant.

Cuando el objeto cuyo historial estamos tratando de mostrar en el mapa es estacionario durante mucho tiempo o se mueve extremadamente lento, obtendremos un montón de puntos que se encuentran cerca y obstruirán el mapa. Para corregir la situación, deje que la matriz de coordenadas resultante pase por el filtro: si la distancia entre el punto anterior y el siguiente es inferior a 100 metros, no muestre el punto en el mapa. Para calcular las distancias entre dos puntos vecinos, utilizamos una fórmula simplificada con una aproximación equiangular . La aproximación es aplicable cuando la distancia entre puntos vecinos no excede varios km:

  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 

Aquí dst es la distancia en km.

Describir la API del folleto aquí no ve el punto. Para esto, en el sitio web oficial . El módulo funciona de la siguiente manera: cada n segundos (lo configuré en 300) se realiza una solicitud al historial actual del objeto que me interesa. La matriz resultante de coordenadas se ejecuta a través del filtro de distancia, reduciendo el número de puntos. Además, en la carpeta con la configuración HomeAssistant en la carpeta www, se forman 2 archivos: index.html y route.html. El archivo route.html contiene toda la lógica para crear un mapa. Y el archivo index.html es un truco para evitar el almacenamiento en caché de la página. De manera predeterminada, HomeAssistant almacena en caché todo lo que es posible, y solo restablecer el caché ayudó a actualizar los datos en el mapa, lo que, por supuesto, es inaceptable. En el archivo index.html, se llama al contenido de route.html, sin embargo, con un parámetro aleatorio generado dinámicamente, que le permite solicitar siempre la versión actual de route.html del servidor:

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

Un poco sobre seguridad


HomeAssistant está diseñado para que todos los archivos dentro del directorio www sean públicos, es decir, cualquier archivo dentro del directorio www puede abrirse en cualquier navegador sin ninguna autorización, conociendo el enlace directo. En el caso de mi módulo, este enlace es el siguiente: your_address_homeassistant / local / route / index.html . Si esto no es crítico para usted, puede omitir esta sección. Fui un poco más lejos y atornillé la autorización a la página con rutas. Para esto, utilicé nginx (puede elegir otro servidor web con soporte de proxy inverso) como servidor proxy. El sitio web HomeAssistant tiene instrucciones oficiales para configurar esta configuración. Después de configurar el proxy y la operación de verificación, debe agregar autorización a las páginas necesarias en la configuración de 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; } 

Luego cree el archivo "/etc/nginx/.htpasswd" y ejecute los siguientes comandos en la consola:

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

admin: reemplazar con el inicio de sesión deseado.

Después de eso, reinicie nginx y verifique: cuando intente abrir una página con una ruta, el navegador debe solicitar un nombre de usuario y contraseña. Observo que esta es una autorización separada que no tiene nada que ver con la autorización de HomeAssistant.

Conclusión


Quizás todo lo que se pueda decir sobre este módulo.
Quienes estén interesados, aquí hay un enlace al módulo. Coloque el archivo a lo largo de la ruta: config_folder_homeassistant / custom_components / route / sensor.py, no se olvide de los derechos.

Si no existe, cree la carpeta config_folder_homeassistant / www y dele los derechos correspondientes.

En el archivo de configuración configuration.yaml, escriba las siguientes líneas:

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

aquí your_device_tracker_entity_id es la ID de su dispositivo device_tracker, your_address_homeassistant es la dirección externa de su HomeAssistant, your_long_life_token es el token de acceso recibido previamente en la interfaz de HomeAssistant para utilizar la API REST.

Después de eso, reinicie HomeAssistant y disfrute. El mapa estará disponible a través de un enlace directo: your_address_homeassistant / local / route / index.html . Si lo desea, puede agregarlo al menú HA utilizando panel_iframe o en cualquier ventana HA a través de la tarjeta lovelace "iframe".
Eso es todo, gracias por su atención.

UPD:
Se agregó un enlace a GitHub. Se modificaron algunos lugares (se eliminó de la configuración haddr, se obtuvo automáticamente config_dir, se agregó la capacidad de establecer mi zona horaria)

¿Y cómo se ve todo? ¡Cuidado, Bluer!
imagen

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


All Articles