Wanting to send data with different intervals

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 5:39 pm

So I have the following MicroPython code in my script, running on an ESP32, which uploads the data from a BME environment sensor to my Adafruit feed once a minute, however, for the 'pres' variable, I don't need to send that data up to my feed anywhere near as often.

I'm very new to Python, and am wondering how I would set up code to have the 'pres' feed to be uploaded once every 60 mins, rather than once every minute as is the case of 'temp'.

Any advice greatly appreciated.
Thanks

Code: Select all

while True:
    # Setup my MQTT connection to Adafruit
    c = MQTTClient(conf['deviceid'], server="io.adafruit.com", user=conf['user'], password=conf['apikey'], port=1883) 
    c.connect()

    # Get the latest values from the BME sensor
    envi = bme.values
    print(envi)

    # Publish the values to Adafruit via MQTT
    c.publish(conf['user']+"/feeds/temp", envi[0])
    c.publish(conf['user']+"/feeds/pres", envi[1])
    #c.publish(conf['user']+"/feeds/humid", envi[2])
    #NOTE: humidity not being returned... maybe faulty sensor, hence commented out

    # Disconnect from MQTT, sleep for a minute
    c.disconnect()
    time.sleep_ms(60000) #60k mili = 60 seconds

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: Wanting to send data with different intervals

Post by kevinkk525 » Fri Feb 22, 2019 5:56 pm

You could learn about using the uasyncio module in micropython for asnyc programming.

A CPython tutorial can be found here https://realpython.com/async-io-python/

An awesome tutorial for the corresponding uasyncio module on micropython can be found here: https://github.com/peterhinch/micropyth ... UTORIAL.md

With this you can run 2 tasks with different time periods.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 6:04 pm

Thanks Kevin, this is certainly something I will add to my 'need to learn' list, but might be a tad overkill for my needs just now.

I have managed to write some test code on the Pi using IDLE that seems to do the trick; a little tidying up and I think I can add this to my ESP32 MicroPython code.

Code: Select all

import time

temp = 20
press = 1021
count = 0

while True:
    print(temp)
    print(count)
    count = count + 1

    if count > 5:
        print(press)
        count = 0
    else:
        print("Press not yet ready")

    time.sleep(3)    

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: Wanting to send data with different intervals

Post by kevinkk525 » Fri Feb 22, 2019 7:30 pm

You might be right.

You can do something like this:

Code: Select all

last_task1=time.ticks_ms()
last_task2=time.ticks_ms()

while True:
    if time.ticks_ms()-last_task1>=3000: # publish data of task1 every 3 seconds
        c.publish(...)
    if time.ticks_ms()-last_task2>=8000: # publish data of task2 every 8 seconds
        c.publish(...)
    time.sleep_ms(50)
By the way, don't disconnect from mqtt if you don't have a good reason to do so.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 7:33 pm

kevinkk525 wrote:
Fri Feb 22, 2019 7:30 pm
You might be right.

You can do something like this:

Code: Select all

last_task1=time.ticks_ms()
last_task2=time.ticks_ms()

while True:
    if time.ticks_ms()-last_task1>=3000: # publish data of task1 every 3 seconds
        c.publish(...)
    if time.ticks_ms()-last_task2>=8000: # publish data of task2 every 8 seconds
        c.publish(...)
    time.sleep_ms(50)
By the way, don't disconnect from mqtt if you don't have a good reason to do so.
Oh wow... that's some superb code there Kevin, much appreciated thanks. I am going to try this - it appears to be a million times more 'experienced coder' than my 'very sad noobie' attempt. :lol:

Also... may I ask why not disconnect? I am happy to take your advice of course and amend my code accordingly, but what would be the coding reason that I shouldn't (if there is one!) ?

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 7:43 pm

kevinkk525 wrote:
Fri Feb 22, 2019 7:30 pm
You might be right.
By the way, don't disconnect from mqtt if you don't have a good reason to do so.
I tried this code in my test set up on the Pi... and get an error Kevin... any advice please?

Code: Select all

Traceback (most recent call last):
  File "/home/pi/Documents/john_count.py", line 7, in <module>
    last_task1=time.ticks_ms()
AttributeError: module 'time' has no attribute 'ticks_ms'
>>> 

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: Wanting to send data with different intervals

Post by kevinkk525 » Fri Feb 22, 2019 8:59 pm

time.ticks_ms is a method only available in micropython, not on your pi. on your pi you can use time.time() which returns seconds so you have to replace the 3000ms in my example with 3s.

I would not disconnect because this way you could keep track of whether the device is still connected or not. You probably need to configure a keepalive and last will message but I guess one step after the other.
The coding difference is, that you would need to connect before you publish anything, which is more difficult in my example as you would have to do it before every publish but also disconnect after every publish or keep track of the connection state... It makes the program complicated without a reason, that's all.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 9:10 pm

kevinkk525 wrote:
Fri Feb 22, 2019 8:59 pm
time.ticks_ms is a method only available in micropython, not on your pi. on your pi you can use time.time() which returns seconds so you have to replace the 3000ms in my example with 3s.
Aha... now I understand, super explanation thanks, Kevin. The programme I am actually using to send the data to Adafruit is coded on the ESP8266 which I have successfully (after some trials and tribulation) flashed with Micropython, and so for the eventual code I upload to there I will use your syntax. For the test on the Pi (or maybe on my Mac) I'll amend the code to use test.time().

kevinkk525 wrote:
Fri Feb 22, 2019 8:59 pm
I would not disconnect because this way you could keep track of whether the device is still connected or not. You probably need to configure a keepalive and last will message but I guess one step after the other.
The coding difference is, that you would need to connect before you publish anything, which is more difficult in my example as you would have to do it before every publish but also disconnect after every publish or keep track of the connection state... It makes the program complicated without a reason, that's all.
I was actually thinking about if there would be a way to monitor if my ESP8266 had lost connection to the net, but then I wondered how I would get it to send me a message somehow when it had no way of so doing!! I am curious (and eager to learn) about how this would work?

As a side note... I have a not so normal set up at home re internet access. I don't have a broadband service - used to have Virgin Media when ex wife and kids were here, but that was 7 years ago and I no longer needed that level of internet access or speed, so I use my excellent mobile provider to give me WiFi from a hotspot on my phone when I am home. Super speeds sometimes up to 40MBPS, and never an issue. However... now that I am dabbling with IoT I do of course need an always-on internet connection at home, but I am not wanting to commit to a contract with one of the service providers. So, I've found a super mobile service called Smarty - no contract, various plans, even up to unlimited for £25 pm which is super. So, I am up and running with this second provider to determine how much bandwidth I need for the home network - started off with 4GB, will see how it goes. But I have a SONOFF TH10 controlling the CH and have started using the ESP8266 for other stuff. All good fun eh!

Thanks for your help thus far, Kevin, much appreciated.

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 9:18 pm

kevinkk525 wrote:
Fri Feb 22, 2019 8:59 pm
time.ticks_ms is a method only available in micropython, not on your pi. on your pi you can use time.time() which returns seconds so you have to replace the 3000ms in my example with 3s.
So I tried this with some amended Python code Kevin, and get not the results I expected...
import time

Code: Select all

temp = 20
press = 1021

last_task1=time.time()
last_task2=time.time()

while True:
    if time.time()-last_task1>=2: # publish data of task1 every 2 seconds
#        c.publish(...)
         print(temp)
    if time.time()-last_task2>=4: # publish data of task2 every 4 seconds
#        c.publish(...)
         print(press)
    time.sleep(1)
Gives the following output...

Code: Select all

>>> %Run john_count.py
20
20
20
1021
20
1021
20
1021
20
1021
20
1021
Should I be resetting any timers?

theMusicMan
Posts: 23
Joined: Mon Feb 11, 2019 12:16 am

Re: Wanting to send data with different intervals

Post by theMusicMan » Fri Feb 22, 2019 9:35 pm

kevinkk525 wrote:
Fri Feb 22, 2019 8:59 pm
time.ticks_ms is a method only available in micropython, not on your pi. on your pi you can use time.time() which returns seconds so you have to replace the 3000ms in my example with 3s.
Think I figured it out... don't need the last sleep line.

Code: Select all

import time

temp = 20
press = 1021

last_task1=time.time()
last_task2=time.time()

while True:
    if time.time()-last_task1>=1: # publish data of task1 every 2 seconds
#        c.publish(...)
         print(temp)
         last_task1=time.time()
    if time.time()-last_task2>=6: # publish data of task2 every 4 seconds
#        c.publish(...)
         print(press)
         last_task2=time.time()
        
#    time.sleep(1)

Post Reply