From 8700bd30101c37c14f00401c6af9c92411f4446e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Tro=C3=9Fbach?= Date: Thu, 8 Aug 2024 09:22:24 +0200 Subject: [PATCH] in order to reduce the number of requests, battery-details and parameter values are now fetched every 60s per default. Configurable using BATTERY_DETAILS_POLLING_INTERVAL and PARAMETER_POLLING_INTERVAL --- README.md | 29 ++++++++++++----------- cmd/noah-mqtt/main.go | 13 ++++++----- internal/config/config.go | 21 +++++++++-------- internal/polling/service.go | 46 +++++++++++++++++++++++-------------- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 948e0ed..76b5532 100644 --- a/README.md +++ b/README.md @@ -123,20 +123,21 @@ By following these steps, `noah-mqtt` will communicate with Home Assistant via y You can configure `noah-mqtt` using the following environment variables: -| Environment Variable | Description | Default | -|:--------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|:--------------| -| `LOG_LEVEL` | Sets the logging level of the application | INFO | -| `DETAILS_CYCLE_SKIPS` | To reduce request count and the probability to get locked, set the number of fetch cycles skipped fetching battery details and parameter settings. | 2 | -| `POLLING_INTERVAL` | Time in seconds between fetching new data | 10 | -| `GROWATT_USERNAME` | Your Growatt account username (required) | - | -| `GROWATT_PASSWORD` | Your Growatt account password (required) | - | -| `MQTT_HOST` | Address of your MQTT broker (required) | - | -| `MQTT_PORT` | Port number of your MQTT broker | 1883 | -| `MQTT_CLIENT_ID` | Identifier for the MQTT client | noah-mqtt | -| `MQTT_USERNAME` | Username for connecting to your MQTT broker | - | -| `MQTT_PASSWORD` | Password for connecting to your MQTT broker | - | -| `MQTT_TOPIC_PREFIX` | Prefix for MQTT topics used by Noah-mqtt | noah2mqtt | -| `HOMEASSISTANT_TOPIC_PREFIX` | Prefix for topics used by Home Assistant | homeassistant | +| Environment Variable | Description | Default | +|:--------------------------------------------------|:----------------------------------------------------------------------------------------|:--------------| +| `LOG_LEVEL` | Sets the logging level of the application | INFO | +| `POLLING_INTERVAL` | Time in seconds between fetching new status data | 10 | +| `BATTERY_DETAILS_POLLING_INTERVAL` | Time in seconds between fetching battery details (per battery SoC & temperature). | 60 | +| `PARAMETER_POLLING_INTERVAL` | Time in seconds between fetching parameter data (system-output-power, charging limits). | 60 | +| `GROWATT_USERNAME` | Your Growatt account username (required) | - | +| `GROWATT_PASSWORD` | Your Growatt account password (required) | - | +| `MQTT_HOST` | Address of your MQTT broker (required) | - | +| `MQTT_PORT` | Port number of your MQTT broker | 1883 | +| `MQTT_CLIENT_ID` | Identifier for the MQTT client | noah-mqtt | +| `MQTT_USERNAME` | Username for connecting to your MQTT broker | - | +| `MQTT_PASSWORD` | Password for connecting to your MQTT broker | - | +| `MQTT_TOPIC_PREFIX` | Prefix for MQTT topics used by Noah-mqtt | noah2mqtt | +| `HOMEASSISTANT_TOPIC_PREFIX` | Prefix for topics used by Home Assistant | homeassistant | Adjust these settings to fit your environment and requirements. diff --git a/cmd/noah-mqtt/main.go b/cmd/noah-mqtt/main.go index 6191b0d..a2c963d 100644 --- a/cmd/noah-mqtt/main.go +++ b/cmd/noah-mqtt/main.go @@ -43,12 +43,13 @@ func main() { Version: version, }) pollingService := polling.NewService(polling.Options{ - GrowattClient: growattClient, - HaClient: haService, - MqttClient: client, - PollingInterval: cfg.PollingInterval, - TopicPrefix: cfg.Mqtt.TopicPrefix, - DetailsCycleSkips: cfg.DetailsCycleSkips, + GrowattClient: growattClient, + HaClient: haService, + MqttClient: client, + PollingInterval: cfg.PollingInterval, + BatteryDetailsPollingInterval: cfg.BatteryDetailsPollingInterval, + ParameterPollingInterval: cfg.ParameterPollingInterval, + TopicPrefix: cfg.Mqtt.TopicPrefix, }) pollingService.Start() }) diff --git a/internal/config/config.go b/internal/config/config.go index c0d0fd2..0f84731 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -2,7 +2,6 @@ package config import ( "errors" - "math" "os" "strconv" "sync" @@ -10,12 +9,13 @@ import ( ) type Config struct { - LogLevel string - DetailsCycleSkips int - PollingInterval time.Duration - Growatt Growatt - Mqtt Mqtt - HomeAssistant HomeAssistant + LogLevel string + PollingInterval time.Duration + BatteryDetailsPollingInterval time.Duration + ParameterPollingInterval time.Duration + Growatt Growatt + Mqtt Mqtt + HomeAssistant HomeAssistant } type Growatt struct { @@ -42,9 +42,10 @@ var _once sync.Once func Get() Config { _once.Do(func() { _config = Config{ - LogLevel: getEnv("LOG_LEVEL", "info"), - DetailsCycleSkips: int(math.Min(math.Max(0, float64(s2i(getEnv("DETAILS_CYCLE_SKIPS", "2")))), 999)), - PollingInterval: time.Duration(s2i(getEnv("POLLING_INTERVAL", "10"))) * time.Second, + LogLevel: getEnv("LOG_LEVEL", "info"), + PollingInterval: time.Duration(s2i(getEnv("POLLING_INTERVAL", "10"))) * time.Second, + BatteryDetailsPollingInterval: time.Duration(s2i(getEnv("BATTERY_DETAILS_POLLING_INTERVAL", "60"))) * time.Second, + ParameterPollingInterval: time.Duration(s2i(getEnv("PARAMETER_POLLING_INTERVAL", "60"))) * time.Second, Growatt: Growatt{ Username: getEnv("GROWATT_USERNAME", ""), Password: getEnv("GROWATT_PASSWORD", ""), diff --git a/internal/polling/service.go b/internal/polling/service.go index b30fd04..6dedbdb 100644 --- a/internal/polling/service.go +++ b/internal/polling/service.go @@ -12,12 +12,13 @@ import ( ) type Options struct { - GrowattClient *growatt.Client - HaClient *homeassistant.Service - MqttClient mqtt.Client - PollingInterval time.Duration - TopicPrefix string - DetailsCycleSkips int + GrowattClient *growatt.Client + HaClient *homeassistant.Service + MqttClient mqtt.Client + PollingInterval time.Duration + BatteryDetailsPollingInterval time.Duration + ParameterPollingInterval time.Duration + TopicPrefix string } type Service struct { @@ -133,20 +134,31 @@ func (s *Service) fetchNoahSerialNumbers() []string { func (s *Service) poll() { slog.Info("start polling growatt", slog.Int("interval", int(s.options.PollingInterval/time.Second))) - i := 0 - for { - for _, serialNumber := range s.serialNumbers { - s.pollStatus(serialNumber) - if i%(s.options.DetailsCycleSkips+1) == 0 { + + go func() { + for { + for _, serialNumber := range s.serialNumbers { + s.pollStatus(serialNumber) + } + <-time.After(s.options.PollingInterval) + } + }() + + go func() { + for { + for _, serialNumber := range s.serialNumbers { s.pollBatteryDetails(serialNumber) - s.pollParameterData(serialNumber) } + <-time.After(s.options.BatteryDetailsPollingInterval) } - <-time.After(s.options.PollingInterval) + }() - i += 1 - if i >= 1000 { - i = 0 + go func() { + for { + for _, serialNumber := range s.serialNumbers { + s.pollParameterData(serialNumber) + } + <-time.After(s.options.ParameterPollingInterval) } - } + }() }