MQTT Manually Publishing / Subscribing


#29

hi Adam,

Spend along time trying Pope and call subprocess scripts and could not get the temp value out the
temp = subprocess.Popen(“mosquitto_sub -t /tinkerforge/bricklet/temperature/t6Q/temperature”,shell=True)

removing all the humidity, air-pressure I made a cayenne-mqtt-test.py file with

while True:
try: 
	temp = subprocess.call("mosquitto_sub -t /tinkerforge/bricklet/temperature/t6Q/temperature",shell=True)
	print (temp)			
	temp = str(dict(temp).get("temperature"))
	print (temp)
	
	time.sleep(5)
	
except (EOFError, SystemExit, KeyboardInterrupt):
	mqttc.disconnect()
	sys.exit()

keeping the fist part intact to try to see what value is in temp and different stages. Runinning it gives me this:

pi@pi20:~/tinkerforge $ python cayenne-mqtt-test.py

{"_timestamp":1487165024.991951,“temperature”:2550}
{"_timestamp":1487165095.287481,“temperature”:2556}
^Cpi@pi20:~/tinkerforge $

tried print with () and without but nothing prints on the screen.

How to I “debug” the value of temp during the running of this test script?

Thanks

Patrick


#30

Maybe try stdout=subprocess.PIPE. Sorry, I don’t have mosquitto_sub installed to test right now. I’ll try to get that installed tonight and do a proper test to see what the issue is instead of stabbing in the dark.


#31

Try this with Omega Onion2:


#32

Hi Adam,

ok will wait.

But I have some doubts about the value of temp in the

temp = subprocess.call(“mosquitto_sub -t /tinkerforge/bricklet/temperature/t6Q/temperature”,shell=True)

So I put the value {"_timestamp":1487085328.256301,“temperature”:2525} in temp

while True:
try: 
	
	temp = {"_timestamp":1487085328.256301,"temperature":2525}
	print (temp)			
	temp = str(dict(temp).get("temperature"))
	print (temp)
					
	time.sleep(5)
	
except (EOFError, SystemExit, KeyboardInterrupt):
	mqttc.disconnect()
	sys.exit()

and receive this when running

pi@pi20:~/tinkerforge python cayenne-mqtt-test.py {'_timestamp': 1487085328.256301, 'temperature': 2525} 2525 {'_timestamp': 1487085328.256301, 'temperature': 2525} 2525 {'_timestamp': 1487085328.256301, 'temperature': 2525} 2525 {'_timestamp': 1487085328.256301, 'temperature': 2525} 2525 ^Cpi@pi20:~/tinkerforge

What is the right solution.

Now I am convinced that the value of temp with the
temp = subprocess.call(“mosquitto_sub -t /tinkerforge/bricklet/temperature/t6Q/temperature”,shell=True)
is not a " {’_timestamp’: 1487085328.256301, ‘temperature’: 2525} " type value but something else.

Is there a way to see/print the value of temp just after the line
temp = subprocess.call(“mosquitto_sub -t /tinkerforge/bricklet/temperature/t6Q/temperature”,shell=True)
when running the script, just to be 100% sure ?

Thanks

Patrick


#33

Ok, so it’s been a while since I’ve used subprocess…I was doing it all wrong. I’m not sure if it’s possible or not, but it probably would have been much easier to just read the values natively in python instead of using subprocess. Might look in to that sometime to see if it’s possible to connect to more than one server in the same script. Anyway…This should work for you:

import paho.mqtt.client as mqtt
import time
import sys
import subprocess


mqttc = mqtt.Client(client_id="xxxx")
mqttc.username_pw_set("yyyy", password="zzzz")
mqttc.connect("mqtt.mydevices.com", port=1883, keepalive=60)

topic_temp = "v1/username/things/xxxx/data/1"  #change username/clientid here without quotes
topic_humidity = "v1/username/things/xxxx/data/2"
topic_airpress = "v1/username/things/xxx/data/3"

while True:
    try: 
        temp = subprocess.Popen(['mosquitto_sub', '-t', '/tinkerforge/bricklet/temperature/t6Q/temperature', stdout=subprocess.PIPE)
        humidity= subprocess.Popen(['mosquitto_sub', '-t', '/tinkerforge/bricklet/humidity/uk9/humidity', stdout=subprocess.PIPE)
        airpress= subprocess.Popen(['mosquitto_sub', '-t', '/tinkerforge/bricklet/barometer/vGZ/air_pressure', stdout=subprocess.PIPE)
	
        if temp is not None:
                temp = "temp,c=" + str(int(temp.stdout.readline()))
                mqttc.publish(topic_temp, payload= temp , retain=True)	

        if humidity is not None:
                humidity = "humidity,%=" + str(int(humidity.stdout.readline())
                mqttc.publish(topic_humidity, payload= humidity , retain=True)

        if airpress is not None:
                airpress = "airpress,mBar=" + str(int(airpress.stdout.readline()))
                mqttc.publish(topic_airpress, payload= airpress , retain=True)

        time.sleep(5)
    except (EOFError, SystemExit, KeyboardInterrupt):
        mqttc.disconnect()
        sys.exit()

#34

Hi Adam,

Tried out your latest solution and got this error:

pi@pi20:~/tinkerforge $ python cayenne-mqtt-test.py

File “cayenne-mqtt-test.py”, line 15
temp = subprocess.Popen([‘mosquitto_sub’, ‘-t’, ‘/tinkerforge/bricklet/temperature/t6Q/temperature’, stdout =subprocess.PIPE)
^
SyntaxError: invalid syntax
pi@pi20:~/tinkerforge $

Saw that a ] was missing after …/t6Q/temperature’ ] , stdout =subprocess.PIPE)

This problem was solved, but the I receive this

pi@pi20:~/tinkerforge python cayenne-mqtt-test.py Traceback (most recent call last): File "cayenne-mqtt-test.py", line 18, in <module> temp = "temp,c=" + str(int(temp.stdout.readline())) ValueError: invalid literal for int() with base 10: '{"_timestamp":1487318726.163536,"temperature":2431}\n' pi@pi20:~/tinkerforge

does it has to do with the fact that the value is a dict[ ]and not an int() ???
I only need the temperature value and not the full {"_timestamp":1487318726.163536,“temperature”:2431} data value.
could this be the error???

Then to replace int with dic
temp = “temp,c=” + str(dict(temp.stdout.readline()))
and rafter running got this error

pi@pi20:~/tinkerforge $ python cayenne-mqtt-test.py
Traceback (most recent call last):
File “cayenne-mqtt-test.py”, line 18, in
temp = “temp,c=” + str(dict(temp.stdout.readline()))
ValueError: dictionary update sequence element #0 has length 1; 2 is required

Still not the temp value we need…

Thanks
Patrick


#35

Lets just get rid of subprocess…it’s not really a good thing to use anyway. Try this:

import paho.mqtt.client as mqtt
import time
import sys
import subprocess
import json

temp = None
humidity = None
airpress = None

def on_message_temp(mosq, obj, msg):
    global temp
    temp = json.loads(msg.payload)

def on_message_humidity(mosq, obj, msg):
    global humidity
    humidity = json.loads(msg.payload)

def on_message_airpress(mosq, obj, msg):
    global airpress
    airpress = json.loads(msg.payload)

Cayenne = mqtt.Client(client_id="clientid")
Cayenne.username_pw_set("username", password="password")
Cayenne.connect("mqtt.mydevices.com", port=1883, keepalive=60)

localmqtt = mqtt.Client()
localmqtt.message_callback_add("tinkerforge/bricklet/temperature/t6Q/temperature", on_message_temp) #do not include leading slash on topic
localmqtt.message_callback_add("tinkerforge/bricklet/humidity/uk9/humidity", on_message_humidity) #do not include leading slash on topic
localmqtt.message_callback_add("tinkerforge/bricklet/barometer/vGZ/air_pressure", on_message_airpress) #do not include leading slash on topic
localmqtt.connect("localhost", port=1883, keepalive=60)
localmqtt.subscribe([("/tinkerforge/bricklet/temperature/t6Q/temperature",0),("/tinkerforge/bricklet/humidity/uk9/humidity",0),("/tinkerforge/bricklet/barometer/vGZ/air_pressure",0)])
localmqtt.loop_start()

topic_temp = "v1/username/things/clientid/data/1"  #change username/clientid here
topic_humidity = "v1/username/things/clientid/data/2" #change username/clientid here
topic_airpress = "v1/username/things/clientid/data/3" #change username/clientid here

while True:
    try: 
        if temp is not None:
            cayennetemp = "temp,c=" + str(temp['temperature'])
            Cayenne.publish(topic_temp, payload=cayennetemp , retain=True)	

        if humidity is not None:
            cayennehumidity = "humidity,%=" + str(humidity['humidity'])
            Cayenne.publish(topic_humidity, payload=cayennehumidity , retain=True)

        if airpress is not None:
            cayenneairpress = "airpress,mBar=" + str(airpress['airpress'])
            Cayenne.publish(topic_airpress, payload=cayenneairpress , retain=True)

        time.sleep(5)
    except (EOFError, SystemExit, KeyboardInterrupt):
        localmqtt.loop_stop()
        Cayenne.disconnect()
        localmqtt.disconnect()
        sys.exit()

#36

Hi Adam,

Put your new code in my cayenne-mqtt-test.py and replaced clientid, username and password with the values of my bring your own thing page.

Gat a strange error, the code for airpress seems similar as for temp and humidity but I still receive this error:

pi@pi20:~/tinkerforge $ python cayenne-mqtt-test.py
Traceback (most recent call last):
File “cayenne-mqtt-test.py”, line 50, in
cayenneairpress = “airpress,mBar=” + str(airpress[‘airpress’])
KeyError: ‘airpress’

When I open my dashboard, I see this:

I have a value in temp ,to be divided by 100 to have the real temp.
Used this code cayennetemp = “temp,c=” + str(temp[‘temperature’]/100)
And the value became 25,00 °C

But no value or unit for humidity or airpress when this strange error will be gone.

Do you have to use the “hvac_hum,P=” instead of “humidity,%=” to see the value and unit as I found at one of the last pages of the MQTT Manually publishing / Subscripbing documentation?
It is a very large table with all sorts of units for a lot of possible sensors.
Or can you keep “humidity,%=” ???

Thanks

Patrick


#37

What is the output of:

“mosquitto_sub -t /tinkerforge/bricklet/humidity/uk9/humidity"
and
"mosquitto_sub -t /tinkerforge/bricklet/barometer/vGZ/air_pressure”


#38

Adam,

Made some progress.
As I have a keyerror: ‘airpress’ and do not see from where the error originate, I remarked the lines

#if airpress is not None:
        #cayenneairpress = "airpress,mBar=" + str(airpress['airpress'])
        #Cayenne.publish(topic_airpress, payload=cayenneairpress , retain=True)

Now the program runs without error and I receive the value for humidity but without the % unit (see arrow)

So temp and humidy are working and I see the values changing.

Rest the airpress problem.When removing the 3 remarks from the airpress lines, the program stops with error:

pi@pi20:~/tinkerforge $ python cayenne-mqtt-test.py
Traceback (most recent call last):
File “cayenne-mqtt-test.py”, line 50, in
cayenneairpress = “airpress,mBar=” + str(airpress[‘airpress’])
KeyError: ‘airpress’

As you ask I ran mosquitto_sub -t /tinkerforge/bricklet/barometer/vGZ/air_pressure and receive

pi@pi20:~/tinkerforge $ mosquitto_sub -t /tinkerforge/bricklet/barometer/vGZ/air_pressure
{"_timestamp":1487407795.6225,“air_pressure”:1023000}
{"_timestamp":1487407800.684803,“air_pressure”:1022990}
{"_timestamp":1487407805.756374,“air_pressure”:1022996}
{"_timestamp":1487407810.811612,“air_pressure”:1022989}
{"_timestamp":1487407815.842195,“air_pressure”:1022987}

So that seems good.

I try to solve the keyerror and the unit missing without success.

Any idea’s

Thanks

Patrick


#39

Use this:

cayenneairpress = “airpress,mBar=” + str(airpress[‘airpressure’])


#40

Adam,
Tried it and got the same mistake.
Then changed the last airpressure to air_pressure and it works.
cayenneairpress = “airpress,mBar=” + str(airpress[‘air_pressure’]/1000) #divided by 1000 to have the right value.

Here is the proof:

Thanks you, you are the best.

Patrick.

P.S. any idea why we do not see the % in humidity and mBar in the air pressure widget? Should appear as Celcius in the temp widget or am I wrong?


#41

For the types try

cayennehumidity = “rel_hum,p=” + str(humidity[‘humidity’])
cayenneairpress = “press,bar=” + str(airpress[‘airpress’])


#42

Hi Adam,
Not working, same result as before.
It is not important, but niece to have.
Could put the type in the title of the widget.
Or better have a “choose unit” field in the gauge widget as it exist in the temperature widget.

Again a lot of thanks for helping me,

Patrick


#43

hit ctrl+f5, try logging out and back in, or delete and re-add the widget. It should show up correctly, I just tried it.


#44

Hi adam,
It worked with your
cayennehumidity = “rel_hum,p=” + str(humidity[‘humidity’])
cayenneairpress = “press,bar=” + str(airpress[‘airpress’])

Had to remove widget and reset my Tinkerforge dashboard and re-log to the Cayenne dashboard before seeing the right values and units.

Two remarks:

  • in air pressure I need Mbar. So I divide the value by 1000 again and changed number of decimals to 5. But the value after the decimal divider always says 00000 or it should be for instance 1,03100 when I have 1031,00 mBar. Then looked at the humidity value and same phenomena. The decimals after the “.” are always = xxx zero’s ;xxx equal number of decimals you choose in the settings.

*when clicking on the detail & charts for humidity and air pressure icon in the widget I receive this error

If you look in right corner you see jan 01 1.0AM ; but my pc and pi have the right time! Strange.

With the temperature widget I can see the details & charts without problems.

Are those two bugs?

Thanks

Patrick


#45

Hi Adam,

Removed the widgets, closed the dashboard and signed back, launched the cayenne-mqtt.py and now the widget doesn’t have this first strange error. I can see the log and graphs.

But the value after the decimal still gives me problems.

Question: i have made a document detailing the procedures to replicate my configuration and how to get the dashboard working.
I would like to send it to you for revision via private mail. Is this possible via this forum?

Thanks

Patrick


#46

Sure thing, just click my name then click the message button.


#47

Hi Adam,

As you propose I published a detailed guide of my project on https://www.instructables.com/id/Connect-Tinkerforge-Sensors-to-Cayenne-IOT-Dashboa/

Had some problems with the instructables editor, who screwed the placement of the pictures and added “things” to code line.

Hope it can help someone.

Thanks

Patrick


#48

If you incorporate an Arduino you’ll be eligible for the contest that is currently running! Automation Around the Home - Contest Guidelines