Skip to main content

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,
)

Metadata

Release files for element-iot-api 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for element-iot-api 1.0.2
File Size Uploaded
element_iot_api-1.0.2.tar.gz 15.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for element-iot-api 1.0.2
File Interpreter ABI Platform
element_iot_api-1.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 31.2 kB

Release files / element_iot_api-1.0.2.tar.gz

Download URL element_iot_api-1.0.2.tar.gz
Size 15.9 kB
Tags Source
SHA-256 checksum
How to use checksums
cbc9c2e8d6bac848d5c2f875ba7fedd465c4735e5e1c108cb9cb1622ef996b92
BLAKE2b-256 checksum
How to use checksums
a51f9c319c88a9470976835ae186195c5a42d73398383b2aa9588cad82e7be59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release files / element_iot_api-1.0.2-py3-none-any.whl

Download URL element_iot_api-1.0.2-py3-none-any.whl
Size 15.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7169129bf94725e8c90002e0cc2feeb4731583c710ce9f7d7a391ac736ee23c9
BLAKE2b-256 checksum
How to use checksums
ea57e4e8023abc3bf4205d6300b5df42a6b7afec3740708a1074cc854a8094b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page