Skip to main content

library to interact with the element IoT platform

Project description

ci pre-commit.ci status deploy docs to gh-page

element-iot-api

A separate sphinx documentation exists and can be found here: Docs

Installation

via pip

pip install element-iot-api

via https

pip install git+https://github.com/RUBclim/element-iot-api

via ssh

pip install git+ssh://git@github.com/RUBclim/element-iot-api

Quick start

To get started interacting with the API, you will need an API key. Do not store the API key in your code and especially do not commit the API key. Provide the API key via environment variables.

Get started by creating an instance of element.ElementApi.

import os
from element import ElementApi

api = ElementApi(
    api_location='https://dew21.element-iot.com/api/v1/',
    api_key=os.environ['API_KEY'],
)

If you already know the address of an device, you can get data as a pandas.DataFrame as easy as:

df = api.get_readings(
    device_name='DEC005304',
    start=datetime(2024, 8, 15, 9, 0),
    end=datetime(2024, 8, 15, 10, 0),
    as_dataframe=True,
)
measured_at air_humidity air_temperature battery_voltage device_id protocol_version
2024-08-15 09:00:43.730454+00:00 71.4382 21.1841 3.073 21668 2
... ... ... ... ... ...
2024-08-15 09:55:42.164904+00:00 63.4684 22.6661 3.073 21668 2

Converting between identifiers

There are multiple identifiers per station on the one hand the decentlab_id (e.g. 21668) which is the serial number, an integer and the hexadecimal mac address (e.g. DEC005304).

decentlab_id → address

You can easily get the decentlab_id from the address using element.ElementApi.decentlab_id_from_address.

api.decentlab_id_from_address('DEC0054A4')

This will return 21668. The result will be cached, so no request is made, the next time you call it.

address → decentlab_id

Converting from the address to the decentlab_id is no so easy, since there is no direct mapping possible in the API. So the first time calling this may be slow. Afterwards it will also be cached in the element.ElementApi instance.

This time we need to specify a folder when calling element.ElementApi.address_from_decentlab_id.

api.address_from_decentlab_id(
    decentlab_id=21668,
    folder='stadt-dortmund-klimasensoren-aktiv-sht35'
)

This will return DEC0054A4. The result will be cached, so no request is made, the next time you call it.

listing the folders

The Element system is structured and organized based on folders where sensors are stored in. You can get a list of all available folders by calling element.ElementApi.get_folders:

api.get_folders()

...which will return the raw api request. Or if you're just interested in the folder-slugs, which are combined identifiers for each folder, you can use element.ElementApi.get_folder_slugs:

api.get_folder_slugs()

which will return a list of of folder-slugs:

['stadt-dortmund-klimasensoren-aktiv-sht35', ..., 'stadt-dortmund-klimasensoren-aktiv-atm41']

Listing devices

Each folder contains devices which you can list using element.ElementApi.get_devices. This will return the raw API response you can use to extract information.

api.get_devices()

If you are just interested in the device addresses, e.g. to retrieve data from all devices in a folder, you can use element.ElementApi.get_device_addresses.

api.get_device_addresses(folder='stadt-dortmund-klimasensoren-aktiv-sht35')

...which will return a list of strings which correspon to the device addresses of all devices in the folder

['DEC0054A6', 'DEC0054B0', ..., 'DEC0054C6']

Getting detailed device information

Based on the address e.g. DEC0054C6, we can get detailed information from one station using element.ElementApi.get_device.

api.get_device('DEC0054C6')

This returns the raw API response where you can extract data from.

Getting data

As readings

As described above, you can get data for one station using element.ElementApi.get_readings. as_dataframe will determine whether to return the raw API response or already a pandas.DataFrame.

data = api.get_readings(
    device_name='DEC0054C6',
    start=datetime(2024, 8, 1, 0, 0),
    end=datetime(2024, 8, 10, 0, 0),
    as_dataframe=True,
)

Additionally, you may specify the following keyword-arguments:

  • sort: how to sort the data (by either measured_at or inserted_at)
  • sort_direction: either asc or desc
  • limit: how many value to fetch per paginated request
  • max_page: how many pages of pagination to get maximum to avoid infinite pagination

From packets

If the original data was not parsed or incorrectly parsed, you can get the data directly from the unparsed packets. The raw packets can be retrieved using element.ElementApi.get_packets by either specifying the device_name or the folder (to get data for all stations in this folder). If you want to just get the measurements, you need to specify packet_type='up', for uplink packages.

packets = api.get_packets(
    folder='stadt-dortmund-klimasensoren-aktiv-sht35',
    packet_type='up',
    start=datetime(2024, 8, 1, 0, 0),
    end=datetime(2024, 8, 10, 0, 0),
)

This will return the raw package data, where you will need to extract the message from und subsequently parse it.

Parsing packets

Code for parsing the packets is provided by decentlab and was vendored into this repo.

This packages provides functions for parsing different sensor types.

BLG

Use element.parsers.decode_BLG to decode a message from the BLG sensor.

data = decode_BLG(msg=b'0254970003498800830BF7', hex=True)

This will return a dictionary similar to this:

{
   'Battery voltage': {
      'unit': 'V',
      'value': 3.063,
   },
   'Device ID': 21655,
   'Protocol version': 2,
   'Temperature': {
      'unit': '°C',
      'value': 47.728822273125274,
   },
   'Thermistor resistance': {
      'unit': 'Ω',
      'value': 36877.08418433659,
   },
   'Voltage ratio': {
      'unit': None,
      'value': 0.012840747833251953,
   },
}

SHT35

Use element.parsers.decode_STH35 to decode a message from the SHT35 sensor.

data = decode_STH35(msg=b'0254A60003783F596E0C17', hex=True)

ATM41

Use element.parsers.decode_ATM41 to decode a message from the SHT35 sensor.

data = decode_ATM41(
    msg=b'02530400038283800080008000803488CD8076815C80CBA708816D817D80197FF680007FDB7FDB0AAE',
    hex=True,
)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

element_iot_api-1.0.2.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

element_iot_api-1.0.2-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file element_iot_api-1.0.2.tar.gz.

File metadata

  • Download URL: element_iot_api-1.0.2.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.3

File hashes

Hashes for element_iot_api-1.0.2.tar.gz
Algorithm Hash digest
SHA256 cbc9c2e8d6bac848d5c2f875ba7fedd465c4735e5e1c108cb9cb1622ef996b92
MD5 05991e1a23449afd935d947f061c3cfc
BLAKE2b-256 a51f9c319c88a9470976835ae186195c5a42d73398383b2aa9588cad82e7be59

See more details on using hashes here.

File details

Details for the file element_iot_api-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for element_iot_api-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7169129bf94725e8c90002e0cc2feeb4731583c710ce9f7d7a391ac736ee23c9
MD5 7eb29df4492f349cab0fe1ab9462bcc1
BLAKE2b-256 ea57e4e8023abc3bf4205d6300b5df42a6b7afec3740708a1074cc854a8094b5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page