Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: This and that #5

Merged
merged 4 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased
- Added transformer for MongoDB CDC to CrateDB SQL conversion
- Rename "Airrohr" decoder to "Sensor.Community"

## 2024/07/16 v0.0.1
- Added decoders for Airrohr, Tasmota, and TTS/TTN from Kotori DAQ
Expand Down
25 changes: 17 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,30 @@ pip install --upgrade commons-codec
In order to learn how to use the library, please visit the [documentation],
and explore the source code or its [examples].

## License
The project uses the LGPLv3 license for the whole ensemble. However, individual
portions of the code base are vendorized from other Python packages, where
deviating licenses may apply. Please check for detailed license information
within the header sections of relevant files.

## Contributing
## Project Information

### Acknowledgements
Kudos to the authors of all the many software components this library is
vendoring and building upon.

### Contributing
The `commons-codec` package is an open source project, and is
[managed on GitHub](https://github.com/daq-tools/commons-codec).
We appreciate contributions of any kind.
The project is still in its infancy, and we appreciate contributions
of any kind.

## Etymology
### Etymology
The [Apache Commons Codec] library was the inspiration for the name. Otherwise,
both libraries' ingredients don't have anything in common, yet.

### License
The project uses the LGPLv3 license for the whole ensemble. However, individual
portions of the code base are vendorized from other Python packages, where
deviating licenses may apply. Please check for detailed license information
within the header sections of relevant files.



[Apache Commons Codec]: https://commons.apache.org/proper/commons-codec/
[commons-codec]: https://pypi.org/project/commons-codec/
Expand Down
14 changes: 14 additions & 0 deletions docs/backlog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Backlog

## Iteration +1
- [x] Add Kotori decoders
- [x] Add DynamoDB and MongoDB CDC translators
- [x] Resolve dependencies: `bson` vs. `pymongo`?
- [ ] Documentation
- [x] Release v0.0.2

## Iteration +2
- [ ] Performance: Batching!
- [ ] MongoDB: Implement stream resumption using `start_after`
- [ ] Feature: Filter by events, e.g. Ignore "delete" events?
- [ ] Integration Testing the "example" programs?
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ keywords = [
"encode",
"i/o",
"json",
"luftdaten.info",
"map data",
"marshall",
"mongodb",
"nested data",
"sensor.community",
"serialize",
"sql",
"tasmota",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
from commons_codec.util.data import is_number


class AirrohrDecoder:
class SensorCommunity:
"""
Decode JSON payloads in Airrohr format.
Decode JSON payloads in Sensor.Community format.

Previously / Also: Airrohr, dusti.api, Luftdaten.info

Documentation
=============
- https://getkotori.org/docs/integration/airrohr.html
- https://github.com/opendata-stuttgart/meta/wiki/APIs
- https://kotori.readthedocs.io/en/latest/integration/airrohr.html
- https://community.hiveeyes.org/t/more-data-acquisition-payload-formats-for-kotori/1421/2

Example
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# -*- coding: utf-8 -*-
# (c) 2020-2021 Andreas Motl <andreas@getkotori.org>
# Copyright (c) 2020-2024, The Kotori Developers and contributors.
# Distributed under the terms of the LGPLv3 license, see LICENSE.
import logging
import typing as t

from commons_codec.decode.airrohr import AirrohrDecoder
from commons_codec.decode.sensor_community import SensorCommunity
from commons_codec.util.data import jd

logger = logging.getLogger(__name__)


# https://community.hiveeyes.org/t/more-data-acquisition-payload-formats-for-kotori/1421/2


data_in = {
"esp8266id": 12041741,
"sensordatavalues": [
Expand Down Expand Up @@ -42,13 +39,12 @@
}


def test_decode_airrohr():
def test_decode_sensor_community():
"""
Submit single reading in Airrohr JSON format to HTTP API
and proof it is stored in the InfluxDB database.
Verify decoding a single reading in Sensor.Community JSON format.
"""

result = AirrohrDecoder.decode(jd(data_in))
result = SensorCommunity.decode(jd(data_in))
assert result == data_out
assert_type(result["SDS_P1"], float)
assert_type(result["BME280_pressure"], float)
Expand All @@ -59,6 +55,9 @@ def test_decode_airrohr():


def assert_type(value: t.Any, type_: t.Type):
"""
Assertion helper with better error reporting.
"""
assert isinstance(
value, type_
), f"Value is of type '{type(value).__name__}', but should be '{type_.__name__}' instead"
18 changes: 5 additions & 13 deletions tests/decode/test_tasmota.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
@pytest.mark.tasmota
def test_tasmota_sonoff_sc():
"""
Publish a single SENSOR reading in Tasmota/JSON format
to MQTT broker, including a timestamp.
Proof that the reading is processed and stored correctly.
Verify decoding a reading from a "Sonoff SC" device in Tasmota JSON format.

https://kotori.readthedocs.io/en/latest/integration/tasmota.html#submit
"""
Expand All @@ -45,9 +43,7 @@ def test_tasmota_sonoff_sc():
@pytest.mark.tasmota
def test_tasmota_ds18b20():
"""
Publish another single SENSOR reading in Tasmota/JSON format
to MQTT broker, including a timestamp.
Proof that the reading is processed and stored correctly.
Verify decoding a reading from a "Wemos DS18B20" device in Tasmota JSON format.

https://kotori.readthedocs.io/en/latest/integration/tasmota.html#submit
"""
Expand All @@ -68,8 +64,7 @@ def test_tasmota_ds18b20():
@pytest.mark.wemos
def test_tasmota_wemos_dht22():
"""
Publish a reading from a Wemos multi sensor device.
Proof that the reading is processed and stored correctly.
Verify decoding a reading from a "Wemos DHT22" device in Tasmota JSON format.
"""

# Submit a single measurement.
Expand All @@ -89,8 +84,7 @@ def test_tasmota_wemos_dht22():
@pytest.mark.wemos
def test_tasmota_wemos_multi():
"""
Publish a reading from a Wemos multi sensor device.
Proof that the reading is processed and stored correctly.
Verify decoding a reading from a "Wemos multi sensor" device in Tasmota JSON format.
"""

# Submit a single measurement.
Expand Down Expand Up @@ -121,9 +115,7 @@ def test_tasmota_wemos_multi():
@pytest.mark.tasmota
def test_tasmota_state():
"""
Publish a single STATE reading in Tasmota/JSON format
to MQTT broker, including a timestamp.
Proof that the reading is processed and stored correctly.
Verify decoding a "state message" in Tasmota JSON format.

https://kotori.readthedocs.io/en/latest/integration/tasmota.html#submit
"""
Expand Down
10 changes: 6 additions & 4 deletions tests/decode/test_tts_ttn.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@

def test_decode_tts_ttn_full(tts_ttn_full):
"""
Submit single reading in TTS/TTN webhook JSON format to HTTP API,
and verify it was correctly stored in the InfluxDB database.
Verify decoding a full message in TTS/TTN webhook JSON format.

https://kotori.readthedocs.io/en/latest/integration/tts-ttn.html
"""

data_in = read_jsonfile(tts_ttn_full)
Expand Down Expand Up @@ -60,8 +61,9 @@ def test_decode_tts_ttn_full(tts_ttn_full):

def test_decode_tts_ttn_minimal(tts_ttn_minimal):
"""
Submit single reading in TTS/TTN webhook JSON format to HTTP API,
and verify it was correctly stored in the InfluxDB database.
Verify decoding a minimal message in TTS/TTN webhook JSON format.

https://kotori.readthedocs.io/en/latest/integration/tts-ttn.html
"""

data_in = read_jsonfile(tts_ttn_minimal)
Expand Down