kizniche / Mycodo

An environmental monitoring and regulation system
http://kylegabriel.com/projects/
GNU General Public License v3.0
2.96k stars 494 forks source link

"Python 3 Code"-Input debug log shows empty measurement added to InfluxDB #1297

Closed cmwfuchs closed 1 year ago

cmwfuchs commented 1 year ago

Describe the problem/bug

When adding measurements via Python 3 Code input, the measurement is not correctly displayed in the debug log: [...] DEBUG - mycodo.controllers.controller_input_30d13119 - Adding measurements to InfluxDB with ID 30d13119-069a-4dc1-aa03-7b87f7eebab4: {}.

The measurement itself is however correctly stored in the DB, as verified on the Live Measurements page and the Asynchronous Measurements graph.

Versions:

Tested on Raspberry Pi and on Debian server.

Reproducibility

  1. Add new "Python 3 Code" input
  2. Configure measurement name and unit
  3. Set Log Level:Debug
  4. Save Input
  5. Activate Input
  6. Observe Daemon log

The issue appears when using the preset default example Python code as well as when using custom Python code (both storing measurements using the store_measurement() function.

Expected behavior

The Debug log should show the information of the added measurement. Similar to other inputs: Adding measurement to influxdb: {0: {'measurement': 'unitless', 'unit': 'none', 'value': 42.0, 'timestamp_utc': datetime.datetime(2023, 4, 10, 10, 34, 6, 971382)}}

Screenshots

The measurement in the Live Measurements page: image

Logfile

Output of the Daemon logfile ``` 2023-04-10 12:39:29,837 - DEBUG - mycodo.inputs.python_code_30d13119 - Python Code: import os import sys sys.path.append(os.path.abspath('/var/mycodo-root')) from mycodo.databases.models import Conversion from mycodo.mycodo_client import DaemonControl from mycodo.utils.database import db_retrieve_table_daemon from mycodo.utils.influx import add_measurements_influxdb from mycodo.utils.inputs import parse_measurement control = DaemonControl() class PythonInputRun: def __init__(self, logger, input_id, measurement_info, channels_conversion, channels_measurement): self.logger = logger self.input_id = input_id self.measurement_info = measurement_info self.channels_conversion = channels_conversion self.channels_measurement = channels_measurement def store_measurement(self, channel=None, measurement=None, timestamp=None): if None in [channel, measurement]: return measure = { channel: { 'measurement': self.measurement_info[channel]['measurement'], 'unit': self.measurement_info[channel]['unit'], 'value': measurement, 'timestamp_utc': None } } if timestamp: measure[channel]['timestamp_utc'] = timestamp if channel in self.channels_conversion and self.channels_conversion[channel]: conversion = db_retrieve_table_daemon( Conversion, unique_id=self.channels_measurement[channel].conversion_id) if conversion: # Convert value/unit is conversion_id present and valid meas_conv = parse_measurement( self.channels_conversion[channel], self.channels_measurement[channel], measure, channel, measure[channel], timestamp=measure[channel]['timestamp_utc']) measure[channel]['measurement'] = meas_conv[channel]['measurement'] measure[channel]['unit'] = meas_conv[channel]['unit'] measure[channel]['value'] = meas_conv[channel]['value'] add_measurements_influxdb(self.input_id, measure) def python_code_run(self): import random # Import any external libraries # Get measurements/values (for example, these are randomly-generated numbers) random_value_channel_0 = random.uniform(10.0, 100.0) # Store measurements in database (must specify the channel and measurement) self.store_measurement(channel=0, measurement=random_value_channel_0) 2023-04-10 12:39:29,872 - DEBUG - mycodo.controllers.controller_input_30d13119 - Adding measurements to InfluxDB with ID 30d13119-069a-4dc1-aa03-7b87f7eebab4: {} ```
kizniche commented 1 year ago

the measurement is not correctly displayed in the debug log

This is expected behavior. The Input is designed this way and it is not possible for this input to do what you describe as your expected behavior.

kizniche commented 1 year ago

However, You may be happy to hear that you got me thinking how a Python Code Input could be developed that would allow Input Actions to work, and I managed to make one. So, if you upgrade to master, you'll see a new Python 3 Code (v2.0) Input that uses a different method for storing values to the database and should work with Input Actions.