Widget stuck at zero, but data is being received

Hello people,

In my project, when I configure a device to display Temperature as Celsius, it doesn’t update in real time. The widget aways displays zero.
In Live Data, I can see the values being received, and I can also see the values in the widget’s Chart mode.

I don’t know if this is a bug or if I missed something. It’s a Bring Your Own Thing project too, and I coded it using Python. If code is needed, I’ll provide. I’m using MQTT.

This is a uni project, my teacher deducted points from me cause of that. :frowning:

can you share the code,

Sure! I’m sorry for taking that long to respond. Had no access to it until today.
Just to add detail - while the code isn’t running, the latest info is displayed normally in the widget.

main.py

from sim import aquecedor, aquecedor2, temperatura, temperatura2, umidade, desligaf, desligaf2
import paho.mqtt.client as mqtt
import time
from defi import user, password, client_id, client_id2, server, port, comms, comms2

def mensagem(client, user, msg):
    vetor = '0'
    vetor = msg.payload.decode().split(',')
    if vetor[1] == '1':
        aquecedor(estado='on'),desligaf(estado=0)
        client.publish(comms+'data/2','1')
    if vetor[1] == '0':
        aquecedor(estado='off'),desligaf(estado=1)
        client.publish(comms+'data/2','0')
    client.publish(comms+'response', f'ok,{vetor[0]}')
    print(vetor)
    return vetor[1]

    
def mensagem2(client2, user, msg):
    vetor2 = '0'
    vetor2 = msg.payload.decode().split(',')
    if vetor2[1] == '1':
        aquecedor2(estado2='on'),desligaf2(estado2=0)
        client2.publish(comms2+'data/2','1')
    if vetor2[1] == '0':
        aquecedor2(estado2='off'),desligaf2(estado2=1)
        client2.publish(comms2+'data/2','0')
    client2.publish(comms2+'response', f'ok,{vetor2[0]}')
    print(vetor2)
    return vetor2[1]
    


client = mqtt.Client(client_id)
client2 = mqtt.Client(client_id2)

client.username_pw_set(user, password)
client2.username_pw_set(user, password)
client.connect(server, port)
client2.connect(server, port)

client.on_message = mensagem
client2.on_message = mensagem2
client.subscribe(comms+'cmd/3')
client2.subscribe(comms2+'cmd/3')
client.loop_start()
client2.loop_start()

def comm():
    client.publish(comms+'data/0', temperatura())
    client.publish(comms+'data/1', umidade())
    client.publish(comms+'data/2', 1)
    time.sleep(2)

def comm2():
    client2.publish(comms2+'data/0', temperatura2())
    client2.publish(comms2+'data/1', umidade())
    client2.publish(comms2+'data/2', 1)
    time.sleep(2)

while True:
    comm()
    comm2()

client.disconnect()

sim.py

import random

temp = 0
temp2 = 0
tempp = 0
tempp2 = 0
forceoff = 0
forceoff2 = 0

def temperatura():
    global temp
    global tempp
    if temp == 0:
        temp = random.randrange(2,35)
        return temp
    else:
        if tempp >= temp:
            return aquecedor(estado='off')
        if tempp <= temp:
            return aquecedor(estado='on')
            
def temperatura2():
    global temp2
    global tempp2
    if temp2 == 0:
        temp2 = random.randrange(2,35)
        return temp2
    else:
        if tempp2 >= temp2:
            return aquecedor2(estado2='off')
        if tempp2 <= temp2:
            return aquecedor2(estado2='on')

def umidade():
    return random.randrange(10,70)

def aquecedor(estado: str):
    global temp
    global tempp
    global forceoff
    print('forceoff', forceoff)
    if temp <= 29 and forceoff == 0:
        estado == 'on'
        tempp = temp
        temp += 1
        print('Aquecedor ON', temp)
        print('temp:', temp)
        print('tempp:', temp)
        return temp
    if temp >= 30 or forceoff == 1:
        estado == 'off'
        tempp = temp
        temp -= 1
        print('Aquecedor OFF', temp)
        print('temp:', temp)
        print('tempp:', tempp)
        return tempp

def aquecedor2(estado2: str):
    global temp2
    global tempp2
    global forceoff2
    print('forceoff', forceoff2)
    if temp2 <= 29 and forceoff2 == 0:
        estado2 == 'on'
        tempp2 = temp2
        temp2 += 1
        print('Aquecedor 2 ON', temp2)
        print('temp2:', temp2)
        print('tempp2:', temp2)
        return temp2
    if temp2 >= 30 or forceoff2 == 1:
        estado2 == 'off'
        tempp2 = temp2
        temp2 -= 1
        print('Aquecedor 2 OFF', temp2)
        print('temp2:', temp2)
        print('tempp2:', tempp2)
        return tempp2

def desligaf(estado: int):
    global forceoff
    if estado == 1:
        forceoff = 0
        return forceoff
    if estado == 0:
        forceoff = 1
        return forceoff

def desligaf2(estado2: int):
    global forceoff2
    if estado2 == 1:
        forceoff2 = 0
        return forceoff2
    if estado2 == 0:
        forceoff2 = 1
        return forceoff2

defi.py

user = 'a9486150-1b1c-11ec-8da3-474359af83d7'
password = '83c315a918b101c36751a0d2cca14dc3f9a24dec'
client_id = 'ee71ea80-1b1c-11ec-ad90-75ec5e25c7a4'
client_id2 = 'd6e60460-1fd0-11ec-ad90-75ec5e25c7a4'
server = 'mqtt.mydevices.com'
port = 1883
comms = 'v1/a9486150-1b1c-11ec-8da3-474359af83d7/things/ee71ea80-1b1c-11ec-ad90-75ec5e25c7a4/'
comms2 = 'v1/a9486150-1b1c-11ec-8da3-474359af83d7/things/d6e60460-1fd0-11ec-ad90-75ec5e25c7a4/'

in place of using the paho library for manual creating topic and publishing, you can us GitHub - myDevicesIoT/Cayenne-MQTT-Python: Python Library for Cayenne MQTT API

1 Like

It was one of the appointment’s rules to do it like that.

Could you tell me what I did wrong? Or is that a bug?

the payload should include the datatype and unit.

for eg:-

sensor_temp_value = 32
data =  "temp,c="  + str(sensor_temp_value)
client.publish(comms+'data/0',  data)

temp,c= is the datatype and unit followed by the sensor value.
i am not sure what your temperatura function returns.

1 Like

Temperatura just returns a random number in range, and the state of a fictional heater.
So, what I missed is the “,c” after that so it recognizes it as Celcius, right?
Thank you very much for the info! :slight_smile:

That explains why the Temperature widget doesn’t work, but why does Humidity not work?

correct.

if it is state, then you need to use different datatype and unit and send on differnet channel:-

"digital_sensor,d="

all supported data types can be found here Data types for Cayenne MQTT API

1 Like

Very nice. Thank you for being so helpful. Now, I didn’t find how to close this topic. :frowning: