SolarManager unter Versionsverwaltung

Erster Stand der Hintergrundprozesse, die auf der Synology unter
/volume1/homes/wagner/SolarManager laufen: der Manager selbst, die Sammler
je Geraet, die MQTT-Bruecke, der Wecker und - neu hinzugezogen - der
AutoAction-Runner, der als Hintergrundprozess hierher gehoert und nicht ins
Web-Verzeichnis.

Zugangsdaten stehen nicht mehr im Quelltext, sondern in config.ini, die
nicht mit eingecheckt wird. Vorlage ist config.ini.example, gelesen wird sie
von konfig.py. Betroffen waren solarManager.py (Datenbank und Wattpilot),
zeit.py, gatherWaterData.py, wecker.py und skoda_testdaten.py, das sich das
Passwort bisher aus dem Quelltext eines anderen Moduls herausgesucht hat.

Die Kia-Anbindung ist mit dem Fahrzeug entfallen: kiaTest.py,
gatherCarData.py und hyundai_kia_connect_api sind nicht mehr dabei, ebenso
gatherInverterData.py, auf das nur noch eine auskommentierte Zeile zeigte.

Die mitgelieferten Bibliotheken bleiben im Repository - die NAS hat kein
pip, sie muessen neben den Skripten liegen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-02 20:46:59 +02:00
co-authored by Claude Opus 5
commit 79843aa2ae
968 changed files with 261182 additions and 0 deletions
@@ -0,0 +1,120 @@
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=unused-import
from abc import ABC, abstractmethod
from threading import Lock
from time import time_ns
from typing import Iterable, List, Mapping
# This kind of import is needed to avoid Sphinx errors.
import mysql.opentelemetry.sdk.metrics
import mysql.opentelemetry.sdk.metrics._internal.instrument
import mysql.opentelemetry.sdk.metrics._internal.sdk_configuration
from mysql.opentelemetry.metrics._internal.instrument import CallbackOptions
from mysql.opentelemetry.sdk.metrics._internal.exceptions import MetricsTimeoutError
from mysql.opentelemetry.sdk.metrics._internal.measurement import Measurement
from mysql.opentelemetry.sdk.metrics._internal.metric_reader_storage import (
MetricReaderStorage,
)
from mysql.opentelemetry.sdk.metrics._internal.point import Metric
class MeasurementConsumer(ABC):
@abstractmethod
def consume_measurement(self, measurement: Measurement) -> None:
pass
@abstractmethod
def register_asynchronous_instrument(
self,
instrument: (
"mysql.opentelemetry.sdk.metrics._internal.instrument_Asynchronous"
),
):
pass
@abstractmethod
def collect(
self,
metric_reader: "mysql.opentelemetry.sdk.metrics.MetricReader",
timeout_millis: float = 10_000,
) -> Iterable[Metric]:
pass
class SynchronousMeasurementConsumer(MeasurementConsumer):
def __init__(
self,
sdk_config: "mysql.opentelemetry.sdk.metrics._internal.SdkConfiguration",
) -> None:
self._lock = Lock()
self._sdk_config = sdk_config
# should never be mutated
self._reader_storages: Mapping[
"mysql.opentelemetry.sdk.metrics.MetricReader", MetricReaderStorage
] = {
reader: MetricReaderStorage(
sdk_config,
reader._instrument_class_temporality,
reader._instrument_class_aggregation,
)
for reader in sdk_config.metric_readers
}
self._async_instruments: List[
"mysql.opentelemetry.sdk.metrics._internal.instrument._Asynchronous"
] = []
def consume_measurement(self, measurement: Measurement) -> None:
for reader_storage in self._reader_storages.values():
reader_storage.consume_measurement(measurement)
def register_asynchronous_instrument(
self,
instrument: (
"mysql.opentelemetry.sdk.metrics._internal.instrument._Asynchronous"
),
) -> None:
with self._lock:
self._async_instruments.append(instrument)
def collect(
self,
metric_reader: "mysql.opentelemetry.sdk.metrics.MetricReader",
timeout_millis: float = 10_000,
) -> Iterable[Metric]:
with self._lock:
metric_reader_storage = self._reader_storages[metric_reader]
# for now, just use the defaults
callback_options = CallbackOptions()
deadline_ns = time_ns() + timeout_millis * 10**6
default_timeout_millis = 10000 * 10**6
for async_instrument in self._async_instruments:
remaining_time = deadline_ns - time_ns()
if remaining_time < default_timeout_millis:
callback_options = CallbackOptions(timeout_millis=remaining_time)
measurements = async_instrument.callback(callback_options)
if time_ns() >= deadline_ns:
raise MetricsTimeoutError("Timed out while executing callback")
for measurement in measurements:
metric_reader_storage.consume_measurement(measurement)
return self._reader_storages[metric_reader].collect()