Publishing data in Thingspeak using MQTT

Hi everyone,

I'll describe my situation: I have to do an university project where I have to get data from OpenWeatherMap (http GET) and post it in Thingspeak with MQTT (it is required by the project instruction) and I managed to got the data from OWM and parse only the fields that I need (temperature and humidity).

I'm having problem publishing the data in Thingspeak, the MQTT nodes are connected but I can't figure out how to insert a number in a field.

I'll attach screenshots to better explain (the flow isn't finished yet, I have two fields to fill in Thingspeak but rn I'm only focusing on "temperature").

I put under here the configuration of node, mind that the connection is working and I'm only covering data for privacy.

In particular I don't know how to pass a variable into field1 of my Thingspeak channel.

mqtt-broker-Message

mqtt-in

Thanks in advance everyone!

You would set the msg topic going into the mqtt node and leave the topic blank in the mqtt node. You can use a change node or function node or a template node to do this.
In change node you can
Set msg. topic
To JSONata J: "channels/" & $$.payload & "/publish"
Where payload is the msg property containing the string you want to insert in the topic.

Or in a template you can set the property to msg. topic
and use the template channels/{{payload}}/publish

Or in a function

msg.topic = `channels/${msg.payload}/publish`;
reurn msg;

Thank for the respose!
But I'm not understanding, doesn't channels/xxx/payload refer only to the channel? How can I speciefield the field I want to write into? I'll have to insert two data into two field (temperature and humidity in field1 and field2 respectively).

As you present no additional information or data i can only offer an example. Hopefully you can break it down. As I do not use Thingspeak i have used a public mqtt server, that why i added a unique ref.
The example shows how to add a string into a topic to publish msg.payload.

[{"id":"28b404d83fbcbec5","type":"inject","z":"febe25a17f3bb5df","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"temperature\":20,\"humidity\":70}","payloadType":"json","x":292.9999885559082,"y":100.00000286102295,"wires":[["5d0db1e8d16ffcf4"]]},{"id":"5d0db1e8d16ffcf4","type":"split","z":"febe25a17f3bb5df","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":432.9999885559082,"y":100.00000286102295,"wires":[["737ef434a0143382","59d2079ac3552883"]]},{"id":"737ef434a0143382","type":"template","z":"febe25a17f3bb5df","name":"","field":"topic","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"unique_ref_ug5k786/channels/{{parts.key}}/publish","output":"str","x":602.9999885559082,"y":100.00000286102295,"wires":[["a44ef113e9122992","8d993f891cc7bb03"]]},{"id":"59d2079ac3552883","type":"debug","z":"febe25a17f3bb5df","name":"debug 291","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":592.9999885559082,"y":40.00000286102295,"wires":[]},{"id":"a44ef113e9122992","type":"mqtt out","z":"febe25a17f3bb5df","name":"","topic":"","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"9704c3ad5fdb77c8","x":772.9999885559082,"y":100.00000286102295,"wires":[]},{"id":"8d993f891cc7bb03","type":"debug","z":"febe25a17f3bb5df","name":"debug 293","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":812.9999885559082,"y":40.00000286102295,"wires":[]},{"id":"b0d0d66499f5396b","type":"mqtt in","z":"febe25a17f3bb5df","name":"","topic":"unique_ref_ug5k786/channels/+/publish","qos":"2","datatype":"auto-detect","broker":"9704c3ad5fdb77c8","nl":false,"rap":true,"rh":0,"inputs":0,"x":440,"y":180,"wires":[["91514e98d6e64169"]]},{"id":"91514e98d6e64169","type":"debug","z":"febe25a17f3bb5df","name":"debug 292","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":180,"wires":[]},{"id":"9704c3ad5fdb77c8","type":"mqtt-broker","name":"","broker":"broker.hivemq.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

How to import a flow

Ok so, maybe you could help me to understand better the mqtt out node?
This is the doc from Thingspeak, msg.payload have the correct string for the request, but I'm not quite sure how to configure the mqtt out node (like, where to put the payload and how, how to insert the value of a variable, how to correctly define the topic...).

Beside this, thank so much for the help!

You set the url, port and client Id in the mqtt config node, and any login security details.
You set the message you want to send in msg.payload. You set the topic in msg.topic as shown. You do not have to add any details to the mqtt out node, except selecting the mqtt config to use.

Ok thanks, I'll post a picture of my flow then, maybe I'm doing something wrong with that:

This is the function node:
pic-selected-230504-1445-27

I point out that the Json node is set to "Convert between JSON String & Object".

In the "inject" node (the one connected with the mqtt node on the top) I have "msg.payload = msg.payload" and "msg.topic = channels//publish"

And in the mqtt config I have no settings in the "Messages" tab (removed "topic" show in the first pic of the first post).

  1. The http request node has an option to output a parsed json object, so no need for json node or JSON.parse() in function node.
  2. You have not set msg.topic in the function, i gave example of how to do this.
  3. They say a picture is worth a thousand word, but this is not true in this case the image does not help, it would be best to export your flow and post here, as i have in above posts. Also the output of the http request node would help make an example for you.
  4. It looks to me like your function sends a msg of msg.payload.payload, is that correct or should it be msg.payload.
  5. Setting msg.payload to msg.payload in the inject will result in msg.payload being undefined, as the inject does not have a incoming message containing msg.payload, and never will, as it is an inject.

Got it, here's the flow:


[
    {
        "id": "1d319bc3005a51a2",
        "type": "tab",
        "label": "Flow 5",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "e46e775c6f0776dc",
        "type": "inject",
        "z": "1d319bc3005a51a2",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 150,
        "y": 420,
        "wires": [
            [
                "b900a61996e12571"
            ]
        ]
    },
    {
        "id": "b900a61996e12571",
        "type": "http request",
        "z": "1d319bc3005a51a2",
        "name": "",
        "method": "GET",
        "ret": "obj",
        "paytoqs": "ignore",
        "url": "https://api.openweathermap.org/data/2.5/weather?q=Milan,it&APPID=<OWMAPI>",
        "tls": "",
        "persist": false,
        "proxy": "",
        "insecureHTTPParser": false,
        "authType": "",
        "senderr": false,
        "headers": [],
        "credentials": {
            "user": "",
            "password": ""
        },
        "x": 330,
        "y": 420,
        "wires": [
            [
                "d482a5dd055e2b33"
            ]
        ]
    },
    {
        "id": "55dd1d46ef91b923",
        "type": "function",
        "z": "1d319bc3005a51a2",
        "name": "Conversione temp",
        "func": "msg.payload = JSON.parse(msg.payload);\n\nmsg.payload.main.temp = msg.payload.main.temp - 273.15;\n\nvar fieldString = \"field1=\" +\n    msg.payload.main.temp +\n    \"&field2=\" +\n    msg.payload.main.humidity;\n\nvar newMsg = {\n    payload: fieldString\n}\n\nmsg.payload = newMsg;\n\nreturn newMsg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 320,
        "wires": [
            [
                "3b64295684b6c8c2",
                "d2bc0d1fc82d8703"
            ]
        ]
    },
    {
        "id": "d482a5dd055e2b33",
        "type": "json",
        "z": "1d319bc3005a51a2",
        "name": "",
        "property": "payload",
        "action": "",
        "pretty": true,
        "x": 490,
        "y": 420,
        "wires": [
            [
                "55dd1d46ef91b923"
            ]
        ]
    },
    {
        "id": "d2bc0d1fc82d8703",
        "type": "mqtt out",
        "z": "1d319bc3005a51a2",
        "name": "Thingspeak prova POST",
        "topic": "",
        "qos": "0",
        "retain": "false",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "3d6675c689220dd2",
        "x": 650,
        "y": 180,
        "wires": []
    },
    {
        "id": "3b64295684b6c8c2",
        "type": "debug",
        "z": "1d319bc3005a51a2",
        "name": "debug 4 flow 3",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 650,
        "y": 320,
        "wires": []
    },
    {
        "id": "474599d714e96bb9",
        "type": "inject",
        "z": "1d319bc3005a51a2",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "channels/<channelID>/publish",
        "payload": "payload",
        "payloadType": "msg",
        "x": 370,
        "y": 180,
        "wires": [
            [
                "d2bc0d1fc82d8703"
            ]
        ]
    },
    {
        "id": "3d6675c689220dd2",
        "type": "mqtt-broker",
        "name": "prova2",
        "broker": "mqtt3.thingspeak.com",
        "port": "1883",
        "clientid": "<channelID>",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthRetain": "false",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": "",
        "credentials": {
            "user": "<channelUsername>",
            "password": ""
        }
    }
]

Is there some reason you did not supply the output of http request node?

Here is yet another example, but untested as you failed to supply requested data

[{"id":"474599d714e96bb9","type":"inject","z":"1d319bc3005a51a2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"channels/1234/publish","payload":"field1=12&field2=70","payloadType":"str","x":340,"y":180,"wires":[["d2bc0d1fc82d8703"]]},{"id":"d2bc0d1fc82d8703","type":"mqtt out","z":"1d319bc3005a51a2","name":"Thingspeak prova POST","topic":"","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"3d6675c689220dd2","x":650,"y":180,"wires":[]},{"id":"55dd1d46ef91b923","type":"function","z":"1d319bc3005a51a2","name":"Conversione temp","func":"msg.payload.main.temp = msg.payload.main.temp - 273.15;\nlet channelID = \"1234\"\nlet fieldString = \"field1=\" +\n    msg.payload.main.temp +\n    \"&field2=\" +\n    msg.payload.main.humidity;\n\nmsg.payload = fieldString;\nmsg.topic = `channels/${channelID}/publish`;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":320,"wires":[["3b64295684b6c8c2","d2bc0d1fc82d8703"]]},{"id":"b900a61996e12571","type":"http request","z":"1d319bc3005a51a2","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.openweathermap.org/data/2.5/weather?q=Milan,it&APPID=<OWMAPI>","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":330,"y":420,"wires":[["55dd1d46ef91b923"]]},{"id":"3b64295684b6c8c2","type":"debug","z":"1d319bc3005a51a2","name":"debug 4 flow 3","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":650,"y":320,"wires":[]},{"id":"e46e775c6f0776dc","type":"inject","z":"1d319bc3005a51a2","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":420,"wires":[["b900a61996e12571"]]},{"id":"3d6675c689220dd2","type":"mqtt-broker","name":"prova2","broker":"mqtt3.thingspeak.com","port":"1883","clientid":"<channelID>","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":"","credentials":{}}]

Setting topic in the inject node would have worked, but you then create a new message with newMsg but failed to add the topic to the new message.

Sorry, my bad.

Here's the output of the http request node:


{"coord":{"lon":9.1895,"lat":45.4643},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":296.65,"feels_like":296.23,"temp_min":295.19,"temp_max":297.51,"pressure":1018,"humidity":45},"visibility":10000,"wind":{"speed":2.57,"deg":120},"clouds":{"all":20},"dt":1683212992,"sys":{"type":2,"id":20368,"country":"IT","sunrise":1683173260,"sunset":1683225140},"timezone":7200,"id":3173435,"name":"Milan","cod":200}

I only need the values "temp" (in Celsious and not in Kelvin as they are provided) and "humidity".

I can't tell you how much you're helping me, thanks again!