From 0de7d116d78acf3e3bf30dc7e9c94de2cbb79cf1 Mon Sep 17 00:00:00 2001 From: germanhydrogen Date: Thu, 18 Apr 2024 15:01:51 +0200 Subject: [PATCH] Added influx measurement log --- poetry.lock | 40 ++++++++++++++++++- pyobs_cloudcover/measurement_log/__init__.py | 0 pyobs_cloudcover/measurement_log/influx.py | 31 ++++++++++++++ .../measurement_log/measurement_log.py | 10 +++++ pyproject.toml | 1 + tests/unit/measurment_log/__init__.py | 0 tests/unit/measurment_log/test_influx.py | 34 ++++++++++++++++ 7 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 pyobs_cloudcover/measurement_log/__init__.py create mode 100644 pyobs_cloudcover/measurement_log/influx.py create mode 100644 pyobs_cloudcover/measurement_log/measurement_log.py create mode 100644 tests/unit/measurment_log/__init__.py create mode 100644 tests/unit/measurment_log/test_influx.py diff --git a/poetry.lock b/poetry.lock index 28036bc..457940b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1132,6 +1132,30 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.link perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1)"] +[[package]] +name = "influxdb-client" +version = "1.42.0" +description = "InfluxDB 2.0 Python client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "influxdb_client-1.42.0-py3-none-any.whl", hash = "sha256:0161b963f221d5c1769202f41ff55f5d79e00e6dc24e2a0729c82a1e131956ee"}, + {file = "influxdb_client-1.42.0.tar.gz", hash = "sha256:f5e877feb671eda41e2b5c98ed1dc8ec3327fd8991360dc614822119cda06491"}, +] + +[package.dependencies] +certifi = ">=14.05.14" +python-dateutil = ">=2.5.3" +reactivex = ">=4.0.4" +setuptools = ">=21.0.0" +urllib3 = ">=1.26.0" + +[package.extras] +async = ["aiocsv (>=1.2.2)", "aiohttp (>=3.8.1)"] +ciso = ["ciso8601 (>=2.1.1)"] +extra = ["numpy", "pandas (>=1.0.0)"] +test = ["aioresponses (>=0.7.3)", "coverage (>=4.0.3)", "flake8 (>=5.0.3)", "httpretty (==1.0.5)", "jinja2 (==3.1.3)", "nose (>=1.3.7)", "pluggy (>=0.3.1)", "psutil (>=5.6.3)", "py (>=1.4.31)", "pytest (>=5.0.0)", "pytest-cov (>=3.0.0)", "pytest-timeout (>=2.1.0)", "randomize (>=0.13)", "sphinx (==1.8.5)", "sphinx-rtd-theme"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -2261,6 +2285,20 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] +[[package]] +name = "reactivex" +version = "4.0.4" +description = "ReactiveX (Rx) for Python" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "reactivex-4.0.4-py3-none-any.whl", hash = "sha256:0004796c420bd9e68aad8e65627d85a8e13f293de76656165dffbcb3a0e3fb6a"}, + {file = "reactivex-4.0.4.tar.gz", hash = "sha256:e912e6591022ab9176df8348a653fe8c8fa7a301f26f9931c9d8c78a650e04e8"}, +] + +[package.dependencies] +typing-extensions = ">=4.1.1,<5.0.0" + [[package]] name = "reproject" version = "0.12.0" @@ -2818,4 +2856,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.12" -content-hash = "3ac3b9175f9ad410774c80214732b9ca8021f537b1ba6f543b3e240822b39c69" +content-hash = "ec5968cb6d3a47d6ee80b8887a2001d92a612b42ecf376db689c799064d4b2a7" diff --git a/pyobs_cloudcover/measurement_log/__init__.py b/pyobs_cloudcover/measurement_log/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyobs_cloudcover/measurement_log/influx.py b/pyobs_cloudcover/measurement_log/influx.py new file mode 100644 index 0000000..c56c3a1 --- /dev/null +++ b/pyobs_cloudcover/measurement_log/influx.py @@ -0,0 +1,31 @@ +import datetime + +import influxdb_client +from influxdb_client.client.write_api import SYNCHRONOUS + + +from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo +from pyobs_cloudcover.measurement_log.measurement_log import MeasurementLog + + +class Influx(MeasurementLog): + def __init__(self, url: str, bucket: str, org: str, token: str) -> None: + self._client = influxdb_client.InfluxDBClient( + url=url, + token=token, + org=org + ) + self._bucket = bucket + self._org = org + + def __call__(self, measurement: CloudCoverageInfo, obs_time: datetime.datetime) -> None: + data = influxdb_client.Point("measurement") + + data.time(obs_time) + + data.field("total-cover", measurement.total_cover) + data.field("zenith-cover", measurement.zenith_cover) + data.field("change", measurement.change) + + with self._client.write_api(write_options=SYNCHRONOUS) as write_api: + write_api.write(bucket=self._bucket, org=self._org, record=data) diff --git a/pyobs_cloudcover/measurement_log/measurement_log.py b/pyobs_cloudcover/measurement_log/measurement_log.py new file mode 100644 index 0000000..bed07b9 --- /dev/null +++ b/pyobs_cloudcover/measurement_log/measurement_log.py @@ -0,0 +1,10 @@ +import abc +import datetime + +from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo + + +class MeasurementLog(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, measurement: CloudCoverageInfo, obs_time: datetime.datetime) -> None: + ... diff --git a/pyproject.toml b/pyproject.toml index 20111e3..afe928c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ packages = [{include = "pyobs_cloudcover"}] [tool.poetry.dependencies] python = ">=3.11,<3.12" pyobs-core = {version = ">=1.13.0", extras = ["full"]} +influxdb-client = "^1.42.0" [tool.poetry.group.dev.dependencies] pytest = "^7.4.0" diff --git a/tests/unit/measurment_log/__init__.py b/tests/unit/measurment_log/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/measurment_log/test_influx.py b/tests/unit/measurment_log/test_influx.py new file mode 100644 index 0000000..c3c0a8b --- /dev/null +++ b/tests/unit/measurment_log/test_influx.py @@ -0,0 +1,34 @@ +import datetime +from unittest.mock import Mock + +import influxdb_client +import numpy as np + +from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo +from pyobs_cloudcover.measurement_log.influx import Influx + +from influxdb_client.client.write_api import WriteApi + + +def test_call(): + influxdb_client.client.write_api.WriteApi.write = Mock() + + measurement = CloudCoverageInfo(np.array([]), 0, 1, 2) + obs_time = datetime.datetime(2020, 1, 1, 0, 0, 0) + + measurement_log = Influx("", "bucket", "org", "token") + + measurement_log(measurement, obs_time) + + call_args = influxdb_client.client.write_api.WriteApi.write.call_args_list + + kwargs = call_args[0].kwargs + assert kwargs["bucket"] == "bucket" + assert kwargs["org"] == "org" + + data: influxdb_client.Point = kwargs["record"] + assert data._time == obs_time + assert data._fields["total-cover"] == 0 + assert data._fields["zenith-cover"] == 1 + assert data._fields["change"] == 2 +