Coordenadas GPS - History [.csv] - num mapa (python)

Fiquei na dúvida, entre partilhar, ou não, esta ideia… mas acaba por ser um pouco como a questão de uma arma não ter morais, apenas quem a empunha.

Respeitem, por isso, parceiros, familiares, etc., que confiaram em nós para automatizarmos tudo e mais alguma coisa através dos seus aparelhos & localização.


O objetivo era conseguir criar um mapa, que me mostrasse ao longo de um determinado período de tempo, onde eu ou alguém teria andado - utilizando como base sensores de localização do HA: “person.xxx”/“device_tracker_xxx”.

Primeiro tem de se criar um template que ‘separe’ as coordenadas que cada sensor (person.xxx/device_tracker_xxx) vai divulgando ao HA.

Tem de se ir ao file configuration.yaml - ou outro file onde filtrem os templates - e criar:

template:
  - sensor:
      - name: "person_XXX Coordinates"
        unique_id: person_xxx_coordinates
        state: >
          {{states['device_tracker.person_xxx'].attributes.latitude,
            states['device_tracker.person_xxx].attributes.longitude}}

Alterem “person_xxx” para o nome que quiserem; e para o device_tracker que usam (tlm, smartwatch, etc.)

Vão a Developer Tools > Yaml > Templates. Confirmem a configuração, e se tudo correr bem já terão um sensor que irá começar a detalhar as coordenadas de dito device_tracker:

sensor_coord

De seguida carregam no “Show more” e na pop-up seguinte escolhem o período de tempo que pretendem. Finalmente, carregam no botão (demarcado a vermelho) para fazer o download de um ficheiro .csv que irá detalhar: entity_id, state e last_changed.

excel_csv

O que nos interessa é o state, ou seja, as coordenadas: “(xxxxxxx, xxxxxxx)”.

É aí que o script python entra em acção.

import folium
import os

def create_map_with_markers(coordinates, save_dir):
    map_center = coordinates[0]
    m = folium.Map(location=map_center, zoom_start=15)

    for i, coord in enumerate(coordinates, start=1):
        folium.Marker(
            location=coord,
            popup=f"Point {i}: {coord}",
            icon=folium.Icon(color='blue')
        ).add_to(m)

    lats = [coord[0] for coord in coordinates]
    lons = [coord[1] for coord in coordinates]
    min_lat, max_lat = min(lats), max(lats)
    min_lon, max_lon = min(lons), max(lons)

    # Fit map to the bounding box
    m.fit_bounds([[min_lat, min_lon], [max_lat, max_lon]])

    # Save the map as an HTML file
    map_file = os.path.join(save_dir, 'map_with_markers.html')
    m.save(map_file)
    print(f"Map saved to: {map_file}")

if __name__ == "__main__":
    # Path to the CSV file & TXT file
    input_file = r"D:\Download\history.csv"
    output_file = r"D:\Download\filtered_coordinates.txt"


    with open(input_file, 'r') as file:
        lines = file.readlines()

    coordinates = []
    for line in lines[1:]: 
        parts = line.split('"')
        if len(parts) >= 2:  
            coordinate = parts[1]  
            coordinates.append(coordinate)

    with open(output_file, 'w') as file:
        for idx, coordinate in enumerate(coordinates):
            # Remove any trailing comma
            coordinate = coordinate.rstrip(',')
            file.write(f"{coordinate}\n")

    print(f"Filtered coordinates saved to: {output_file}")

    # Read coordinates from filtered_coordinates.txt
    coordinates_file = r"D:\Download\filtered_coordinates.txt"
    with open(coordinates_file, 'r') as file:
        lines = file.readlines()

    # Extract coordinates
    coordinates = []
    for line in lines:
        # Remove parentheses, whitespace, and split into latitude and longitude
        coord = line.replace('(', '').replace(')', '').strip().split(',')
        if len(coord) == 2:
            try:
                latitude, longitude = float(coord[0]), float(coord[1])
                coordinates.append((latitude, longitude))
            except ValueError:
                print(f"Skipping invalid coordinates: {coord}")

    save_directory = r'C:\Users\Utilizador\Desktop\Python Scripts\map'
    create_map_with_markers(coordinates, save_directory)

    # Delete history.csv
    os.remove(input_file)
    print(f"Deleted: {input_file}")

Terão, no entanto, de configurar as vossas localizações.
Ex:

###Local para onde é transferido o ficheiro "history.csv"###
input_file = r"D:\Download\history.csv" 
output_file = r"D:\Download\filtered_coordinates.txt"
###Local onde o ficheiro .txt com apenas as coordenadas é criado###
coordinates_file = r"D:\Download\filtered_coordinates.txt"
###Local onde querem que o mapa (html) seja criado###
save_directory = r'C:\Users\Utilizador\Desktop\Python Scripts\map'

Para quem já tiver instalado python apenas deverá entrar no Command Pront (Win+R > cmd) e escrever:

pip install folium

Para quem não tiver instalado, errr… https://www.python.org/ :sweat_smile:

O resultado final será um ficheiro: “map_with_markers.html”

Que nos mostrará algo como, se eu me tivesse armado em turista em Lisboa (Entrecampos, passear para o Colombo, ir ver o Museu Calouste Gulbenkian, ir mergulhar na confusão junto ao Mosteiro dos Jerónimos, e à noite me apetecesse ir gastar bastante dinheiro para o Alma do chef Henrique Sá):

map

2 Curtiram

Obrigado pela partilha. Eu acho que poderia se útil para registar as minhas saídas para correr. Tenho que testar.

Terás de ver se é viável, a nível do número de vezes que as coordenadas são enviadas.
Se repares no screenshot do ficheiro .csv, os inputs são algo aleatórios: 2x às 8h, 3x às 9h, 3x às 10h, 7x às 11h, etc.


Copyright © 2017-2021. Todos os direitos reservados
CPHA.pt - info@cpha.pt


FAQ | Termos de Serviço/Regras | Política de Privacidade