kizniche / Mycodo

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

" MQTT: Publish" action not working when used to publish measurements from "Python 3 Code" input #1298

Closed cmwfuchs closed 1 year ago

cmwfuchs commented 1 year ago

Describe the problem/bug

The "MQTT: Publish" action fails when using it to publish values obtained from the "Python 3 Code" input:

[...] - DEBUG - mycodo.action.input_action_mqtt_publish_7252774f - Input channel: 0, payload: None
[...] - ERROR - mycodo.action.input_action_mqtt_publish_7252774f -  Error: No measurement found in dictionary passed to Action for channel 0.
[...] - DEBUG - mycodo.trigger_action_7252774f - Message: Executing actions of Input. Error: No measurement found in dictionary passed to Action for channel 0.

Versions:

Tested on Raspberry Pi and on Debian server.

Reproducibility

  1. Add MQTT-Value input
  2. Add Python 3 Code input, Debug mode activated
  3. Add Publish to MQTT action in Python code
  4. Configure MQTT input and action to subscribe/publish to 127.0.0.1:1883, topic test_send, login:no
  5. Activate both inputs
  6. Observe Daemon log

Expected behavior

The measurement saved by the Python Code should be passed to the MQTT-publish action and subsequently published.

Screenshots

The Live Measurements should display the same values for the Python Code input and the MQTT input. image

Additional context

Possibly related to #1297.

Full log output ``` 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: {} 2023-04-10 12:39:30,579 - DEBUG - mycodo.action.input_action_mqtt_publish_7252774f - Input channel: 0, payload: None 2023-04-10 12:39:30,580 - ERROR - mycodo.action.input_action_mqtt_publish_7252774f - Error: No measurement found in dictionary passed to Action for channel 0. 2023-04-10 12:39:30,580 - DEBUG - mycodo.trigger_action_7252774f - Message: Executing actions of Input. Error: No measurement found in dictionary passed to Action for channel 0. ```
kizniche commented 1 year ago

See #1297 that should fix this issue