Using python to read in data from file

I’m trying to use the BlynkLib for python (Running on a Raspberry pi 3) to read in data from multiple files and display it in a superchart on my smart phone. I’ve been confused by a lot of the documentation so far, as it’s unclear to me how to send the actual data using “blynk.run()”. Here is the code I’ve developed so far:

import datetime
import time
import BlynkLib




BLYNK_AUTH = "xxxxx"

# Initalize Blynk
blynk = BlynkLib.Blynk(BLYNK_AUTH)







#Read data from pH, Temp, Air Temp, and Humd files
pHDatafile = "/home/pi/Logs/LastpH.csv"
TempDatafile = "/home/pi/Logs/LastWaterTemp.csv"
AirTempDatafile = "/home/pi/Logs/LastAirTempHum.csv"

#Define function to write to each virtual pin
def pHBlynker(pHdata):
    blynk.virtual_write(2, pHdata)
    print(pHdata)

def TempBlynker(Tempdata):
    blynk.virtual_write(3, Tempdata)
    print(Tempdata)

def AirTempBlynker(AirTempdata):
    blynk.virtual_write(4, AirTempdata)
    print(AirTempdata)

def RHBlynker(RHdata):
    blynk.virtual_write(5, RHdata)
    print(RHdata)

while True:
        blynk.run()

        #Read in most recent pH data point
        pHFile = open(pHDatafile, 'r')
        pHData = pHFile.readline()
        pHData = float(pHData)
        pHFile.close()

        #Read in most recent barrel temp data point
       TempFile = open(TempDatafile, 'r')
       TempData = TempFile.readline()
       TempData = float(TempData)
       TempFile.close()

        #Read in most recent data point
        AirFile = open(AirTempDatafile, 'r')
        data = AirFile.readline()
        spliter =  data.split(',')
        AirTemp = float(spliter[0])
        RH = float(spliter[1])
        AirFile.close()

    
        pHBlynker(pHData)
        TempBlynker(TempData)
        AirTempBlynker(AirTemp)
        RHBlynker(RH)

        time.sleep(60)

Within the while loop, I’d like to read in each of these files, and push the data to my Blynk chart, but it looks like this code only sends the data once, and after running for a short amount of time returns a connection error

Probably because I think this is the equivalent to using delay(60000) (60 seconds) in the void loop() of C++ , which effectively stops Blynk from running and then time out after the 10 second heartbeat…

So just like the rule about not using delay() with Blynk and Arduino code… do NOT use time.sleep() and use Blynk Timer instead…

https://github.com/vshymanskyy/blynk-library-python/blob/master/examples/timer.py

1 Like

A quick point about the Blynk Timer, I have yet to be able to get this to work. Using

import BlynkLib
from BlynkTimer import BlynkTimer

I consistently get the error:

from BlynkTimer import BlynkTimer
ImportError: No module named BlynkTimer

Make sure you install the latest updated library version

OK- Thanks for the input. I tried wrapping my functions as a timer as suggested. When I now run the below code, it runs correctly for the first time. But after the first reading, the code returns an error:

TypeError: 'NoneType' object is not callable 

BLYNK_AUTH = "XXX"

# Initalize Blynk
blynk = BlynkLib.Blynk(BLYNK_AUTH)


# Create BlynkTimer Instance
timer = BlynkTimer()

#Read data from pH, Temp, Air Temp, and Humd files
pHDatafile = "/home/pi/Logs/LastpH.csv"
TempDatafile = "/home/pi/Logs/LastWaterTemp.csv"
AirTempDatafile = "/home/pi/Logs/LastAirTempHum.csv"


#Define function to write to each virtual pin
def pHBlynker():

    #Read in most recent pH data point
    pHFile = open(pHDatafile, 'r')
    pHData = pHFile.readline()
    pHData = float(pHData)
    pHFile.close()

    blynk.virtual_write(2, pHData)
    print(pHData)

def TempBlynker():
    #Read in most recent barrel temp data point
    TempFile = open(TempDatafile, 'r')
    TempData = TempFile.readline()
    TempData = float(TempData)
    TempFile.close()

    blynk.virtual_write(3, TempData)
    print(TempData)

def AirTempBlynker():
    #Read in most recent data point
    AirFile = open(AirTempDatafile, 'r')
    data = AirFile.readline()
    spliter =  data.split(',')
    AirTemp = float(spliter[0])
    RH = float(spliter[1])
    AirFile.close()
    blynk.virtual_write(4, AirTemp)
    print(AirTemp)
    blynk.virtual_write(5, RH)
    print(RH)


# Add Timers
timer.set_interval(10, pHBlynker())
timer.set_interval(10, TempBlynker())
timer.set_interval(10, AirTempBlynker())

while True:
    blynk.run()
    timer.run()

I don’t know about the error… but your timers should not all run at the same time… stager the times a bit so they don’t try to call their respective functions at concurrent times.

I’ve seen all of these errors, years ago.
Are you writing python 2.7 code for a python3.6 interpreter ? (or vise-versa?)

on your console, type python -V

Here’s mine as an example

root@ub:/srv# python -V
Python 2.7.15rc1
root@ub:/srv#

I’m running python 2.7.13 (on a Mac). Though as part of my troubleshooting I’ve run this same code using python 2.7 and python 3, and still get the same error.

python MyCode.py

python3 MyCode.py

Is there something about the way I’ve written my code that could be giving me problems? I’ve included my entire code above (except for some commented out lines in the beginning and the shebang line at top).

#!/usr/bin/python

I’ve also changed the timers as well (spaced them out 2 seconds apart), and I still get the same error

I know it’s not the intended use of this library, but unless I hear differently, the only way I can get the above code to work is to add a quit() statement at the end so it only runs once, then run it every minute from crontab.

Try a single timer with each of the functions called in turn.

Thanks for the input @Costas. I believe I tried to follow your advice and changed my code to this:

#One Function to Rule them All
def MasterBlynk():
    pHBlynker()
    TempBlynker()
    AirTempBlynker()

# Add Timers
timer.set_interval(10, MasterBlynk())
while  True:
    blynk.run()
    timer.run()

But I’m still getting the same error. The code runs correctly once, and updates my Blynk app. But after the interval period I get this error message:

TypeError: 'NoneType' object is not callable

Have you tried Googling your error, as it is Python specific, not Blynk. There should also be a line number?

https://www.google.com/search?q=TypeError%3A+'NoneType'+object+is+not+callable

Thanks again for the input @Gunner. I realize it’s a Python specific error, but I only get the error when using it with the blynk (the functions do not return an error when used outside of blynk).

I don’t have a good understanding of what is happening during the blynk.run and timer.run call, but I’m assuming the issue results from the functions being called by blynk. The fact that the functions run correctly once using the above code makes me think the problem is how the functions are interacting with the blynk call.

It’s worth noting that the above functions do not return an error when used in a while loop (but blynk will not receive data sent using a normal loop structure- only using the blynk timer).

It is still a Python type of syntax error… so what line or your code is the error referring too?

@Gunner - The entire error message:

Traceback (most recent call last):
  File "Blynker3.py", line 94, in <module>
    timer.run()
  File "/home/pi/blynk-library-python/BlynkTimer.py", line 87, in run
    [t.run() for t in self.timers]
  File "/home/pi/blynk-library-python/BlynkTimer.py", line 128, in run
    self.func()
TypeError: 'NoneType' object is not callable

Can you also post the current code that generates that error. I can test it on my end.

@Gunner- Here is the complete code and error message (minus the lines specific to my local machine)

#!/usr/bin/python

import sys
import datetime
import time
import BlynkLib
from BlynkTimer import BlynkTimer
import os



BLYNK_AUTH = "MyAuthCode"

# Initalize Blynk
blynk = BlynkLib.Blynk(BLYNK_AUTH)


# Create BlynkTimer Instance
timer = BlynkTimer()

#Read data from pH, Temp, Air Temp, and Humd files
pHDatafile = "/home/pi/Logs/LastpH.csv"
TempDatafile = "/home/pi/Logs/LastWaterTemp.csv"
AirTempDatafile = "/home/pi/Logs/LastAirTempHum.csv"


#Define function to write to each virtual pin
def pHBlynker():

    #Read in most recent pH data point
    pHFile = open(pHDatafile, 'r')
    pHData = pHFile.readline()
    pHData = float(pHData)
    pHFile.close()

    blynk.virtual_write(2, pHData)
    print(pHData)

def TempBlynker():
    #Read in most recent barrel temp data point
    TempFile = open(TempDatafile, 'r')
    TempData = TempFile.readline()
    TempData = float(TempData)
    TempFile.close()

    blynk.virtual_write(3, TempData)
    print(TempData)

def AirTempBlynker():
    #Read in most recent data point
    AirFile = open(AirTempDatafile, 'r')
    data = AirFile.readline()
    spliter =  data.split(',')
    AirTemp = float(spliter[0])
    RH = float(spliter[1])
    AirFile.close()


    blynk.virtual_write(4, AirTemp)
    print(AirTemp)



def RHBlynker():
    #Read in most recent data point
    AirFile = open(AirTempDatafile, 'r')
    data = AirFile.readline()
    spliter =  data.split(',')
    AirTemp = float(spliter[0])
    RH = float(spliter[1])
    AirFile.close()

    blynk.virtual_write(5, RH)
    print(RH)



# Add Timers (Set to 10 secs for testing, will use 60 for normal use)
timer.set_interval(10, pHBlynker())
timer.set_interval(10, TempBlynker())
timer.set_interval(10, AirTempBlynker())
timer.set_interval(10, RHBlynker())


while  True:
    blynk.run()
    timer.run()

When I run the above code, I will get the expected print results once, and my Blynk phone app will be updated. But after the 10 second delay, I will get this error:

Traceback (most recent call last):
  File "MyBlink.py", line 88, in <module>
    timer.run()
  File "/home/pi/Vinny/blynk-library-python/BlynkTimer.py", line 87, in run
    [t.run() for t in self.timers]
  File "/home/pi/Vinny/blynk-library-python/BlynkTimer.py", line 128, in run
    self.func()
TypeError: 'NoneType' object is not callable

Note- if I run just the function directly from the while loop without timers like this:

# Add Timers
#timer.set_interval(10, pHBlynker())
#timer.set_interval(10, TempBlynker())
#timer.set_interval(10, AirTempBlynker())
#timer.set_interval(10, RHBlynker())


while  True:
    blynk.run()
    #timer.run()
    pHBlynker()

    time.sleep(10)

The function works as expected and updates my Blynk phone app. But if I extend the sleep to 30 seconds, I loose my ability to update Blynk after the first measurement.

In the end, I can successfully update Blynk by either running the above program (with a quit statement at the end so it only runs once) from crontab every 1 min, or I can run the functions from a while loop if I keep the time.sleep rest period below 10 seconds. But neither of these methods seem like the suggested “Blynk” way to do things. I’d prefer to use the blynk timer functions, but I continue to get the above error.

OK, stagger your timers else they all run at exact same time. And remove the () from each function name in your timers…

# Add Timers
#timer.set_interval(10, pHBlynker)
#timer.set_interval(11, TempBlynker)
#timer.set_interval(12, AirTempBlynker)
#timer.set_interval(13, RHBlynker)

Then it will run just fine.

I edited the code on my RPi and just printed the name of each function as I obviously do not have your data

@Gunner for the win!

Thanks- that seems to have done the trick!