Sending a value to the MQTT hub

Hi everyone,

I would like to send a value (calculated via Math) to a MQTT server.
So i add an “Output: MQTT Publish: Value” → But what do I have to include in the value field?

Or is there another way to publish values to the MQTT hub? :thinking:

Wanna use some of the values to be visualized at my smart home dashboard. :slight_smile:

1 Like

You bring up a use case that hasn’t been requested until now. So you want to calculate a value (presumably using some Input or other controller), then publish that value via MQTT? For all the possible combinations that Mycodo can be configured, I can think of only one method and it requires us to get a little creative with some Python code and a Conditional Controller Function. Actually, there are multiple if we’re going to use code, but I’ll show you the easiest.

I do think there is a lot of value in adding an MQTT Publish Action. And indeed, this has been discussed for Inputs, but it really can be applied to Function Actions as well:

Here’s how (theoretically) it would work:

  1. Create an Output (MQTT Publish: Value) and set all the MQTT server settings.
  2. Create a Function (Conditional Controller).
  3. With Python code, perform the calculations you were doing with the Math controller you mentioned. If you used Input measurements, for example, use any of the available Conditions to pull measurements to use with your calculation.
  4. Add the following code to the Conditional Statement, which will pass a value to the Output created earlier that will then pass the value to the MQTT server:
output_id = "a86e7f09-c7ce-47ac-9f36-38a8e943e4b6"
publish_value = 100
control.output_on(output_id, amount=publish_value)

Where output_id is set to the ID of your MQTT Value Output and publish_value is set to the value you want to publish. You can copy the ID of your Output to your clipboard by clicking the button next to the name of your Output on the Output page. This button will show a tool tip with your Output ID when hovered over the button.

Now, considering that this is not an easy way to use Mycodo, since it involves Python code, I see a great amount of value in adding an MQTT Action that can be easily used with Functions to pass a value. Considering the two topics, above, show a lot of interest in such a feature, It’s already high on my priority list and I hope to have it added for the next Mycodo release.

1 Like

I just added a new Function Action: MQTT Publish.

This will allow you to create a Conditional Controller and add from the Actions dropdown the MQTT Publish action. This isn’t currently released, so if you want to test the new feature, you’ll have to upgrade to master.

1 Like

Hi Kyle,

thanks for the fast reply :+1:

In my case, my smart home system is collecting data from all “subsystems” and provide it to two dashboards.
The Mycodo pi will get an own display at the aquaponic system, but it would be great to have the values also at one dashboard :slight_smile:

Yes, I’m using a cheap aliexpress pH-probe + ADS1115 device. So i have to calculate the correct pH value. Altas scientific ist hard to find in Germany :confused:

I’ll add a turbidity sensor and a flow meter in the next weeks. Turbidity should give me a hint, if algae starts to grow in the system and the flow meter if the pumps are working correctly.

Hope to have some time during next week, to give your solution a try. I’ll let you know :slight_smile:

1 Like

Hi Kyle,

I had some time to check, so i did the following steps:

  • Upgrade
  • Add a functional controller
  • copied your code as a conditional statement (plain and with “my” Output ID)
  • selected the measurement as a condition
  • selected the MQTT Hub with credentials etc as an action

But i get this notification;
pi/Mycodo/mycodo/user_python_code/conditional_85b8b59a-0395-4098-ae97-0570cd8a2b55.py:18:4: R0201: Method could be a function (no-self-use)

  • Error: Modify Conditional: pylint returned with status: 8

Did I do something wrong? Maybe replace some IDs?

1 Like

Can you show your code that generated the warning? Without seeing exactly what line 18 is, I can’t help.

Sure, no problem:

I copied your code from above and changed the output ID:

output_id = "85b8b59a-0395-4098-ae97-0570cd8a2b55"
publish_value = 100
control.output_on(output_id, amount=publish_value)
  1: import os
  2: import sys
  3: sys.path.append(os.path.abspath('/var/mycodo-root'))
  4: from mycodo.controllers.base_conditional import AbstractConditional
  5: from mycodo.mycodo_client import DaemonControl
  6: control = DaemonControl()
  7: 
  8: class ConditionalRun(AbstractConditional):
  9:     def __init__(self, logger, function_id, message):
 10:         super(ConditionalRun, self).__init__(logger, function_id, message)
 11: 
 12:         self.logger = logger
 13:         self.function_id = function_id
 14:         self.variables = {}
 15:         self.message = message
 16:         self.running = True
 17: 
 18:     def conditional_code_run(self):
 19:         output_id = "85b8b59a-0395-4098-ae97-0570cd8a2b55"
 20:         publish_value = 100
 21:         control.output_on(output_id, amount=publish_value)


Conditional Statement code analysis:

************* Module mycodo.user_python_code.conditional_85b8b59a-0395-4098-ae97-0570cd8a2b55
pi/Mycodo/mycodo/user_python_code/conditional_85b8b59a-0395-4098-ae97-0570cd8a2b55.py:18:4: R0201: Method could be a function (no-self-use)

As I said and I’m not an software expert: maybe I did something wrong :slight_smile:

1 Like

This is just a warning because you made no reference to “self” in the function. Warnings are not always an issue, such as this case. The pylint that runs on the code will show a number of warnings related to minor things such as this. What’s important is that the code runs.

The problem is, that the change could not be saved.
I get the error message and when i drop down again, the old example code is listed again.

1 Like

Thanks. I just made a bugfix release (v8.10.1) that fixes this.

:+1:

I can now copy the code i posted above and it will keep it.
But i don’t see any value arriving at the MQTT hub.

Turn Log Level: Debug on for your Conditional and Output and review the Daemon log for any indication of issues.

2021-04-27 18:50:11,995 - ERROR - mycodo.outputs.mqtt_value_c2ce4780 - Cannot manipulate Output c2ce4780-04fa-4fec-86e6-f39570d8a971: output channel doesn’t exist: None

I delete everything and create from scratch.

  • copied the new output ID to the function code

Add output_channel= to output_on(), so it appears like:

control.output_on(output_id, output_channel=0, amount=publish_value)

Function seems to be fine now.

2021-04-27 19:59:55,854 - DEBUG - mycodo.outputs.mqtt_value_c2ce4780 - output_on_off(on, 0, None, 100, 0.0, True)

This is what i get.
Looks better, but the value is not set at the MQTT Hub.
When i enter a manual value in the MQTT output it is send correctly.

try:

control.output_on(output_id, output_type="value", output_channel=0, amount=publish_value)

Thats it! :slight_smile: Thanks
I owe you a beer :beers:

Now i have to find some time to play around with it (How to publish a value every 60 seconds, what values i can send and how to format it)

1 Like

Though, using the output_on() function is obsolete since there is now an MQTT Function Action that you can more easily use to publish numerical or string values.

Ok, when using this, what is needed in the functional controller code field?
Lets say sending a temperature input to the hub every 60 sec?

Under each Action that you’ve added, it will give a description and an example of how to use the action. For the MQTT, this is:

MQTT: Publish: Publish a value to an MQTT server.
self.run_action("{9e43205e}", value=33) will execute only this action and publish the value 33.