Publishing a value to Cayenne using mqtt

All the examples I have found show how to publish things like switch on / off status - and being new to mqtt I am struggling to adapt the examples to my use case - can someone help and/or point me in the right direction please.

I have found some code online on a raspberry pi which is taking a measurement from an attached digital flow sensor (each time the impeller in the flow meter rotates i get an on / off digital signal and the code basically counts the number of rotations, expresses this in Litres per minute using the term “flow”). This works well and displays the flow value every 5 seconds on the screen.

I would like to publish the flow value to cayenne using mqtt. I can manage the cayenne dashboard end as the instructions there are clear - its the code that publishes the value I cannot fathom.

Thanks

The code is as follows:

#!/usr/bin/python
import RPi.GPIO as GPIO
import time, sys

FLOW_SENSOR_GPIO = 13

GPIO.setmode(GPIO.BCM)
GPIO.setup(FLOW_SENSOR_GPIO, GPIO.IN, pull_up_down = GPIO.PUD_UP)

global count
count = 0

def countPulse(channel):
global count
if start_counter == 1:
count = count+1

GPIO.add_event_detect(FLOW_SENSOR_GPIO, GPIO.FALLING, callback=countPulse)

while True:
try:
start_counter = 1
time.sleep(1)
start_counter = 0
flow = (count / 7.5) # Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
print(“The flow is: %.3f Litre/min” % (flow))

    count = 0
    time.sleep(5)
except KeyboardInterrupt:
    print('\nkeyboard interrupt!')
    GPIO.cleanup()
    sys.exit()

in the above code you need to use client.virtuallWrite(5, flow)

Thanks. Do i need to combine the code that generates the “flow” output with the code above to produce one script? I ask as on first attempt I get a whole load of syntax and other errors which I’m struggling to resolve. Odd as the first script runs fine yet combining them creates errors in the original script.

Thanks again

yes, you need to combine both the sensor code and cayenne publish code together, so that the sensor reading can be published to cayenne.

ok. I have hopefully combined. I took out the try: and except: but for some reason the client.loop() in the while true loop seems to be causing some issue - but it seems the problem is another program?

pi@raspberrypi : ~ $ python3 flowrate.py

Traceback (most recent call last):

File “flowrate.py”, line 36, in

client.loop()

File “/home/pi/.local/lib/python3.7/site-packages/cayenne/client.py”, line 154, in loop

self.client.loop()

AttributeError: ‘NoneType’ object has no attribute ‘loop’

here is the code I am using:

#!/usr/bin/env python
import cayenne.client
import logging
import RPi.GPIO as GPIO
import time, sys

MQTT_USERNAME = “xxxxxxxxxx”
MQTT_PASSWORD = “xxxxxxxxxx”
MQTT_CLIENT_ID = “xxxxxxxxxxx”

client = cayenne.client.CayenneMQTTClient()

For a secure connection use port 8883 when calling client.begin:

client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)

i=0
timestamp = 0

FLOW_SENSOR_GPIO = 13

GPIO.setmode(GPIO.BCM)
GPIO.setup(FLOW_SENSOR_GPIO, GPIO.IN, pull_up_down = GPIO.PUD_UP)

global count
count = 0

def countPulse(channel):
global count
if start_counter == 1:
count = count+1

GPIO.add_event_detect(FLOW_SENSOR_GPIO, GPIO.FALLING, callback=countPulse)

while True:

    client.loop()
    start_counter = 1
    time.sleep(1)
    start_counter = 0
    flow = (count / 7.5) # Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    print("The flow is: %.3f Liter/min" % (flow))
  
    count = 0
    time.sleep(5)
    if (time.time() > timestamp +10):
        client.virtuallWrite(5, flow)
        timestamp = time.time()
        i = i+1

can you try installing via git :-

git clone https://github.com/myDevicesIoT/Cayenne-MQTT-Python
cd Cayenne-MQTT-Python
python3 setup.py install

Then create a file in the example folder and add the combined code there.

same issue it seems

pi@raspberrypi : ~/Cayenne-MQTT-Python/examples $ sudo python3 flowrate2.py

Traceback (most recent call last):

File “flowrate2.py”, line 37, in

client.loop()

File “/usr/local/lib/python3.7/dist-packages/cayenne_mqtt-1.1.0-py3.7.egg/cayenne/client.py”, line 122, in loop

AttributeError: ‘NoneType’ object has no attribute ‘loop’

pi@raspberrypi : ~/Cayenne-MQTT-Python/examples $

you need to verify with some debug code if client = cayenne.client.CayenneMQTTClient() is working. And potentially add some debug messages in client.py to see if self.client = mqtt.Client(client_id=clientid, clean_session=True, userdata=self) is returning None

Thanks. I spent some time this afternoon and restarted over with combining the code. Critically I repositioned the client.loop() command to be just before the If command in effect moving it to after the flow calculation. This fixed the error. Here is the code I used (and run from the Cayenne-MQTT-Python / examples folder you suggested).

#!/usr/bin/env python
import cayenne.client
import logging
import RPi.GPIO as GPIO
import time, sys

MQTT_USERNAME = “XXXXXXXXX”
MQTT_PASSWORD = “YYYYYYYYY”
MQTT_CLIENT_ID = “ZZZZZZZZZZ”

client = cayenne.client.CayenneMQTTClient()
client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID)

For a secure connection use port 8883 when calling client.begin:

#client.begin(MQTT_USERNAME, MQTT_PASSWORD, MQTT_CLIENT_ID, port=8883, loglevel=logging.INFO)

i=0
timestamp = 0

FLOW_SENSOR_GPIO = 13

GPIO.setmode(GPIO.BCM)
GPIO.setup(FLOW_SENSOR_GPIO, GPIO.IN, pull_up_down = GPIO.PUD_UP)

global count
count = 0

def countPulse(channel):
global count
if start_counter == 1:
count = count+1

GPIO.add_event_detect(FLOW_SENSOR_GPIO, GPIO.FALLING, callback=countPulse)

while True:

    start_counter = 1
    time.sleep(1)
    start_counter = 0
    flow = (count / 7.5) # Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
    print("The flow is: %.3f Liter/min" % (flow))
    #publish.single("/Garden.Pi/WaterFlow", flow, hostname=MQTT_SERVER)
    count = 0
    time.sleep(10)
    client.loop()
    if (time.time() > timestamp +10):
        client.virtualWrite(5, flow)
        timestamp = time.time()
        i = i+1

Glad to hear it is working.