Skip to content

Commit d6caf06

Browse files
committed
influxdb fix
1 parent e226055 commit d6caf06

1 file changed

Lines changed: 24 additions & 4 deletions

File tree

classes/transports/influxdb_out.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from configparser import SectionProxy
33
from typing import TextIO
44
import time
5+
import logging
56

67
from defs.common import strtobool
78

@@ -21,6 +22,7 @@ class influxdb_out(transport_base):
2122
include_device_info: bool = True
2223
batch_size: int = 100
2324
batch_timeout: float = 10.0
25+
force_float: bool = True # Force all numeric fields to be floats to avoid InfluxDB type conflicts
2426

2527
client = None
2628
batch_points = []
@@ -37,6 +39,7 @@ def __init__(self, settings: SectionProxy):
3739
self.include_device_info = strtobool(settings.get("include_device_info", fallback=self.include_device_info))
3840
self.batch_size = settings.getint("batch_size", fallback=self.batch_size)
3941
self.batch_timeout = settings.getfloat("batch_timeout", fallback=self.batch_timeout)
42+
self.force_float = strtobool(settings.get("force_float", fallback=self.force_float))
4043

4144
self.write_enabled = True # InfluxDB output is always write-enabled
4245
super().__init__(settings)
@@ -103,14 +106,17 @@ def write_data(self, data: dict[str, str], from_transport: transport_base):
103106
for key, value in data.items():
104107
# Check if we should force float formatting based on protocol settings
105108
should_force_float = False
109+
unit_mod_found = None
106110

107111
# Try to get registry entry from protocol settings to check unit_mod
108112
if hasattr(from_transport, 'protocolSettings') and from_transport.protocolSettings:
109113
# Check both input and holding registries
110114
for registry_type in [Registry_Type.INPUT, Registry_Type.HOLDING]:
111115
registry_map = from_transport.protocolSettings.get_registry_map(registry_type)
112116
for entry in registry_map:
113-
if entry.variable_name == key:
117+
# Match by variable_name (which is lowercase)
118+
if entry.variable_name.lower() == key.lower():
119+
unit_mod_found = entry.unit_mod
114120
# If unit_mod is not 1.0, this value should be treated as float
115121
if entry.unit_mod != 1.0:
116122
should_force_float = True
@@ -124,14 +130,28 @@ def write_data(self, data: dict[str, str], from_transport: transport_base):
124130
# Try to convert to float first
125131
float_val = float(value)
126132

127-
# If it's an integer but should be forced to float, or if it's already a float
128-
if should_force_float or not float_val.is_integer():
133+
# Always use float for InfluxDB to avoid type conflicts
134+
# InfluxDB is strict about field types - once a field is created as integer,
135+
# it must always be integer. Using float avoids this issue.
136+
if self.force_float:
129137
fields[key] = float_val
130138
else:
131-
fields[key] = int(float_val)
139+
# Only use integer if it's actually an integer and we're not forcing floats
140+
if float_val.is_integer():
141+
fields[key] = int(float_val)
142+
else:
143+
fields[key] = float_val
144+
145+
# Log data type conversion for debugging
146+
if self._log.isEnabledFor(logging.DEBUG):
147+
original_type = type(value).__name__
148+
final_type = type(fields[key]).__name__
149+
self._log.debug(f"Field {key}: {value} ({original_type}) -> {fields[key]} ({final_type}) [unit_mod: {unit_mod_found}]")
150+
132151
except (ValueError, TypeError):
133152
# If conversion fails, store as string
134153
fields[key] = str(value)
154+
self._log.debug(f"Field {key}: {value} -> string (conversion failed)")
135155

136156
# Create InfluxDB point
137157
point = {

0 commit comments

Comments
 (0)