Python library to decrypt Airtag reports, as well as a InfluxDB/Grafana self-hosted dashboard example

Overview

Openhaystack-python

This python daemon will allow you to gather your Openhaystack-based airtag reports and display them on a Grafana dashboard.
You can also use AirTagCrypto.py library alone to decrypt your reports via Python

Demo

Requirements

  • Running Openhaystack simple-server (I'm using a Big Sur Hackintosh virtual machine on my Proxmox server).
  • Grafana instance with installed Track map plugin (in my case running on a separate Arch Linux machine with InfluxDB).
  • InfluxDB 2.0 to store your decrypted reports and send them to Grafana.

Installation

To run a daemon you'll need to:

  • Create a python venv and install necessary libraries:
cd daemon
python3 -m venv venv
source venv/bin/activate
python3 -m pip install -r requirements.txt
  • Edit your config.py to fill your InfluxDB credentials, simple_server URL, and put your tokens' private key in there (you can get them by exporting your accessories in an OpenHaystack app and copying privateKeys from there).
  • Edit systemd/airtags.service so that your path to "airtags" directory matches your actual path
  • Copy airtags.service and airtags.timer to /etc/systemd/system/ and run sudo systemctl enable --now airtags.timer

Now the daemon should be working and your InfluxDB must be filled with reports.


To link your InfluxDB with Prometheus you'll need to create a new empty panel, change its type to "Track map", select your InfluxDB as a data source, and create a query like that:

range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r["_measurement"] == "YOUR_TAG_ID") |> filter(fn: (r) => r["_field"] == "latitude" or r["_field"] == "longitude" or r["_field"] == "tooltip") |> pivot(columnKey: ["_field"], rowKey: ["_time"], valueColumn: "_value") |> duplicate(column: "latitude", as: "lat") |> duplicate(column: "longitude", as: "lon") |> keep(columns: ["_time", "popup", "tooltip", "lat", "lon"]) ">
from(bucket: "airtags")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "YOUR_TAG_ID")
  |> filter(fn: (r) => r["_field"] == "latitude" or r["_field"] == "longitude" or r["_field"] == "tooltip")

  |> pivot(columnKey: ["_field"], rowKey: ["_time"], valueColumn: "_value")
  |> duplicate(column: "latitude", as: "lat")
  |> duplicate(column: "longitude", as: "lon")
  |> keep(columns: ["_time", "popup", "tooltip", "lat", "lon"])

You can find your tag's id in OpenHaystack app by right-clicking your tag and selecting "Copy advertisement key (Base64)". Also, there's a grafana/dashboard.json example dashboard that you can use.

You might also like...
A library to access OpenStreetMap related services
A library to access OpenStreetMap related services

OSMPythonTools The python package OSMPythonTools provides easy access to OpenStreetMap (OSM) related services, among them an Overpass endpoint, Nomina

This is a simple python code to get IP address and its location using python

IP address & Location finder @DEV/ED : Pavan Ananth Sharma Dependencies: ip2geotools Note: use pip install ip2geotools to install this in your termin

GeoIP Legacy Python API

MaxMind GeoIP Legacy Python Extension API Requirements Python 2.5+ or 3.3+ GeoIP Legacy C Library 1.4.7 or greater Installation With pip: $ pip instal

Python bindings and utilities for GeoJSON

geojson This Python library contains: Functions for encoding and decoding GeoJSON formatted data Classes for all GeoJSON Objects An implementation of

Python Data. Leaflet.js Maps.

folium Python Data, Leaflet.js Maps folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js

Python tools for geographic data
Python tools for geographic data

GeoPandas Python tools for geographic data Introduction GeoPandas is a project to add support for geographic data to pandas objects. It currently impl

Python bindings and utilities for GeoJSON

geojson This Python library contains: Functions for encoding and decoding GeoJSON formatted data Classes for all GeoJSON Objects An implementation of

Documentation and samples for ArcGIS API for Python

ArcGIS API for Python ArcGIS API for Python is a Python library for working with maps and geospatial data, powered by web GIS. It provides simple and

Simple, concise geographical visualization in Python
Simple, concise geographical visualization in Python

Geographic visualizations for HoloViews. Build Status Coverage Latest dev release Latest release Docs What is it? GeoViews is a Python library that ma

Comments
  • Data poins are duplicated each time reports are fetched

    Data poins are duplicated each time reports are fetched

    Hello mate, I'm running a fork of your project and just wanted to let you know that the new commit introduced a bug. Namely this line where a tag is given to a data point: https://github.com/hatomist/openhaystack-python/blob/d076f332efc0c32ac403ae629d6853642e7e898e/daemon/main.py#L24

    Fun fact (didn't know either before today), Python's hash() function isn't deterministic between program runs as it uses a new random seed each run for security reasons (https://stackoverflow.com/questions/27522626/hash-function-in-python-3-3-returns-different-results-between-sessions). As such, on each run to fetch the data points the same data point gets a new hash and added again, i.e. duplicated...

    Would submit a pull request, but it's already getting late and dunno when I'm gonna have time to tidy up and commit this so here is a quick one-liner which fixes the problem.

    import md5 from hashlib
    .tag('report_id', md5(result['payload'].encode("UTF-8")).hexdigest())
    

    MD5 is deterministic between runs, the fastest of the hash algos and collisions should only happen every 2^64 data points so for our use case I'd say good enough. Might even be trimmed to make it more storage efficient because we won't have so many data points in 7 days to have hash collisions (I think...). But didn't have yet time to think it through so went with the full hash.

    Also thanks for making this amazing integration!

    opened by zakyum 7
  • InvalidTag when trying to decrypt report

    InvalidTag when trying to decrypt report

    Hi, I would like to thank you for this extremely convenient library. I am not sure I am using everything as intended. First, in the main.py example, I found that tags[tag.get_advertisement_key()] = tag would not work with tags[result['id']], as result['id'] references the private key and not the advertisement key. I thus replaced this line with tags[key] = tag.

    However, I get an InvalidTag error when I use tags[result['id']].decrypt_message(result['payload']). The OpenHaystack app seems to decrypt the report correctly, showing me the correct location. Have you already experienced this issue ?

    Best regards,

    EDIT : After some debugging, it seems my problem lies in __derive_shared_key_from_private_key_and_eph_key, but I still can't find the exact issue

    opened by jdexyz 1
  • Lat and Long are unpacked incorrectly

    Lat and Long are unpacked incorrectly

    Your code in the __decode_tag function does not properly unpack the coordinate data. Your code is not properly handling the sign of, e.g. longitude, so I was getting longitudes >180 where they should be negative instead. I made the below fix that solved my problem.

    #current incorrect code
    latitude = int.from_bytes(data[0:4], 'big', signed=True) / 10000000.0
    longitude = int.from_bytes(data[4:8], 'big', signed=True) / 10000000.0
    
    #correct
    latitude = struct.unpack('>i',data[0:4])[0] / 10000000.0
    longitude = struct.unpack('>i',data[4:8])[0] / 10000000.0
    

    I know these both look like they should do the same thing, but they apparently do not. I was getting bad data until I updated these lines.

    opened by que5o 0
Owner
Bezmenov Denys
Bezmenov Denys
Solving the Traveling Salesman Problem using Self-Organizing Maps

Solving the Traveling Salesman Problem using Self-Organizing Maps This repository contains an implementation of a Self Organizing Map that can be used

Diego Vicente 3.1k Dec 31, 2022
Geocoding library for Python.

geopy geopy is a Python client for several popular geocoding web services. geopy makes it easy for Python developers to locate the coordinates of addr

geopy 3.8k Dec 30, 2022
Python interface to PROJ (cartographic projections and coordinate transformations library)

pyproj Python interface to PROJ (cartographic projections and coordinate transformations library). Documentation Stable: http://pyproj4.github.io/pypr

null 832 Dec 31, 2022
PySAL: Python Spatial Analysis Library Meta-Package

Python Spatial Analysis Library PySAL, the Python spatial analysis library, is an open source cross-platform library for geospatial data science with

Python Spatial Analysis Library 1.1k Dec 18, 2022
Python interface to PROJ (cartographic projections and coordinate transformations library)

pyproj Python interface to PROJ (cartographic projections and coordinate transformations library). Documentation Stable: http://pyproj4.github.io/pypr

null 832 Dec 31, 2022
prettymaps - A minimal Python library to draw customized maps from OpenStreetMap data.

A small set of Python functions to draw pretty maps from OpenStreetMap data. Based on osmnx, matplotlib and shapely libraries.

Marcelo de Oliveira Rosa Prates 9k Jan 8, 2023
Hapi is a Python library for building Conceptual Distributed Model using HBV96 lumped model & Muskingum routing method

Current build status All platforms: Current release info Name Downloads Version Platforms Hapi - Hydrological library for Python Hapi is an open-sourc

Mostafa Farrag 15 Dec 26, 2022
Python library to visualize circular plasmid maps

Plasmidviewer Plasmidviewer is a Python library to visualize plasmid maps from GenBank. This library provides only the function to visualize circular

Mori Hideto 9 Dec 4, 2022
peartree: A library for converting transit data into a directed graph for sketch network analysis.

peartree ?? ?? peartree is a library for converting GTFS feed schedules into a representative directed network graph. The tool uses Partridge to conve

Kuan Butts 183 Dec 29, 2022
Client library for interfacing with USGS datasets

USGS API USGS is a python module for interfacing with the US Geological Survey's API. It provides submodules to interact with various endpoints, and c

Amit Kapadia 104 Dec 30, 2022