I have created a temperature sensor (using DS18B20 temperature sensor) and wrote the python program to read and display the temperature every 10 seconds. It worked fine. Later, I modified the code to save the recordings of each 10 sec to a MySQL database. Now, the problem is that it records AND uploads the data to the databse for the first time it reads. Then, I get an error message. So basically, the program reads and uploads to the database for once and then quits after the error.
Please tell me how to fix this!
Thanks a lot!
Here is the code:
import os
import time
import MySQLdb
import datetime
i = datetime.datetime.now()
db = MySQLdb.connect(host = "localhost", user = "root", passwd = "bb9125ap", db = "PY1")
cur = db.cursor()
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
temp_sensor = '/sys/bus/w1/devices/28-00042d6745ff/w1_slave'
def temp_raw():
f = open(temp_sensor,'r')
lines = f.readlines()
f.close
return lines
def read_temp():
lines = temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = temp_raw()
temp_output = lines[1].find('t=')
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string) / 1000.0
return temp_c
while True:
print "recording data into database(period = 5s.)....press ctrl+Z to stop!"
valT = str(read_temp())
year = str(i.year)
month = str(i.month)
day = str(i.day)
date = day + "-" + month + "-" + year
hour = str(i.hour)
minute = str(i.minute)
second = str(i.second)
time = hour + ":" + minute + ":" + second
try:
cur.execute("""INSERT INTO PY1.DUMP1(temp_c,rec_time,rec_date) VALUES(%s,%s,%s)""",(valT,time,date))
db.commit()
except:
db.rollback()
time.sleep(10)
cur.close()
db.close()
Program name is temp1.py and line 54 according to my editor is db.rollback()
Here is the error message I get
Traceback (most recent call last):
File "temp1.py" , line 54 , in time.sleep(10)
Attribute:'str' object has no attribute 'sleep'
You're overwriting your imported time with a local variable time, converting it to a string.
time = hour + ":" + minute + ":" + second
Related
As soon as I run this python code that includes some mysql, all I get are the three greater or less signs(>>>). Any help would be much appreciated!
My code consists of trying to obtain temperatures through a ds18b20 connected to my raspberry pi 3 and sending that data into a mysql database that I have created.
Here is the python/mysql code :
import os
import glob
import time
import MySQLdb
import datetime
i = datetime.datetime.now()
db = MySQLdb.connect(host = "127.0.0.1", user = "root", passwd = "test", db = "temp_pi")
cur = db.cursor()
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c
while True:
print ("recording data into database(period = 5s.)....press ctrl+Z to stop!")
valT = str(read_temp())
year = str(i.year)
month = str(i.month)
day = str(i.day)
date = day + "-" + month + "-" + year
hour = str(i.hour)
minute = str(i.minute)
second = str(i.second)
timestr = hour + ":" + minute + ":" + second
try:
cur.execute("""INSERT INTO TAB_CLASSROOM(temp_c,T_Date,T_Time) VALUES(%s,%s,%s)""",(valT,date,time))
db.commit()
except:
db.rollback()
time.sleep(10)
cur.close()
db.close()
You've never run anything inside that code. The bulk of your code is inside read_temp() and it isn't called anywhere in it. The >>> means the program has ended and it's entered interpreter mode. Add some code after it for it to work the way you want it to.
You are not, in fact running anything. Assuming you do
python myscript.py
python will load the file and run it - which means execute the code line-by-line. You will find that the first few lines outside of functions are simply executed. Then you define some functions, but never call them.
You should probably add
read_temp()
at the end of the script.
I am running this code on Python 3(IDLE) on my raspberry pi 3 whith the latest raspbian software. With this code I am trying to obtain temperature data through ds18b20 sensor and sending that same data towards the mysql database I created.
From the try: to the end of the if connection.is_connected(), I am establishing the connection to the mysql database.
From the if os.system('modprobe w1-gpio') to return temp_c, I am obtaining the temperature data through the ds18b20 sensor.
From the Whiletrue to the end of my code, I try to send the temperature data into a specific table intitled TAB_CLASSROOM.
Help would be very much appreciated!
HERE IS THE FULL ERROR!:
Traceback (most recent call last):
File "/home/pi/Desktop/mysqlfinal1test.py", line 74
db.close()
^
SyntaxError: unexpected EOF while parsing
Here is the python including mysql code :
import os
import glob
import time
import MySQLdb
import datetime
import mysql.connector
from mysql.connector import Error
i = datetime.datetime.now()
try:
connection = mysql.connector.connect(host='127.0.0.1',
database='temp_pi',
user='root',
password='test')
if connection.is_connected():
db_Info = connection.get_server_info()
print("Connected to MySQL database... MySQL Server version on ",db_Info)
cursor = connection.cursor()
cursor.execute("select database();")
record = cursor.fetchone()
print ("Your connected to - ", record)
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c
while True:
print("recording data into database(period = 5s.)....press ctrl+Z to stop!")
valT = str(read_temp())
year = str(i.year)
month = str(i.month)
day = str(i.day)
date = day + "-" + month + "-" + year
hour = str(i.hour)
minute = str(i.minute)
second = str(i.second)
timestr = hour + ":" + minute + ":" + second
try:
cur.execute("""INSERT INTO TAB_CLASSROOM(temp_c,T_Date,T_Time) VALUES(%s,%s,%s)""",(valT,date,time))
db.commit()
except:
db.rollback()
time.sleep(10)
cur.close()
db.close()
Most of posted program is a huge try block with no except clause. Thus, when the parser hits the bottom of the file, it has no way to finish off the open control block.
The try is at line 11; we run out of input after line 74, without any except for that try.
I suspect that your indentation is faulty (among other things), since this try includes two function definitions. Still, you have two try statements, and only the one except.
I am trying to send temperature data over onto one of my website currently online. This code consists of measuring the temperature through a sensor(ds18b20), sending that data onto a mysql databse entitled temp_pi and specifically onto a table intitled TAB_CLASSROOM and lastly sending that data onto a webpage of mine. Everything in this code runs except for the sendDataToServer() part. I specify the error right before this particular line. I have the PHP set up on my website for this to work.
import os
import glob
import time
import MySQLdb
import datetime
import mysql.connector
from mysql.connector import Error
#define db and cur
db = MySQLdb.connect(host = "127.0.0.1", user = "root", passwd = "xB7O4fXmuMpF6M0u", db = "temp_pi")
cur = db.cursor()
#connection to the database
try:
connection = mysql.connector.connect(host='127.0.0.1',
database='temp_pi',
user='root',
password='xB7O4fXmuMpF6M0u')
if connection.is_connected():
db_Info = connection.get_server_info()
print("Connected to MySQL database... MySQL Server version on ",db_Info)
cursor = connection.cursor()
cursor.execute("select database();")
record = cursor.fetchone()
print ("Your connected to - ", record)
except Error as e :
print ("Error while connecting to MySQL", e)
#obtaining the temperature through the ds18b20 sensor
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c
#Defining sendDataToServer() and trying to send this data towards my website
def sendDataToServer():
global temperature
threading.Timer(600,sendDataToServer).start()
print("Mesuring...")
read_temp()
temperature = read_temp()
print(temperature)
temp= read_temp()
urllib3.urlopen("http://francoouesttemp.tech/weather/add_data.php?temp="+temp).read()
#insertion of data into the mysql database
while True:
print("putting temperature data into temp_pi database")
i = datetime.datetime.now()
year = str(i.year)
month = str(i.month)
day = str(i.day)
date = day + "-" + month + "-" + year
hour = str(i.hour)
minute = str(i.minute)
second = str(i.second)
timestr = hour + ":" + minute + ":" + second
valT = str(read_temp())
try:
cur.execute("""INSERT INTO TAB_CLASSROOM(temp_c,T_Date,T_Time) VALUES(%s,%s,%s)""",(valT,i,timestr))
db.commit()
except:
db.rollback()
time.sleep(5)
#this is the part where my code tells me : NameError : name 'urllib3' is not defined ----- I want this part of the code to send the temperature, date and time over to my website.
sendDataToServer()
cur.close()
db.close()
import urllib
import requests
url = '....'
response = urllib.request.urlopen(url)
If you want to send requests using urllib3, you need to create a pool manager first.
Alternatively, you could use the HTTP client in the Python standard library. Its urlopen function is called urllib.request.urlopen. Depending on what you are trying to do, the requests package might also be an option, but it has certain disadvantages when it comes to certificate management for HTTPS URLs (the built-in client will automatically use the system certificate store).
Why python give Sytanx error ''RETURN OUTSIDE FUNCTION''
Error line 35 :>>>> return round(temp_c,1) ? I'm beginner programmer and i want to store my sensor data mysql . As you see my return round(temp_c,1) in my function and if statement.
Here is my full code
import os
import time
import datetime
import glob
import mysql.connector
from mysql.connector import errorcode
from time import strftime
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
temp_sensor = '/sys/bus/w1/devices/28-000008a43c0e/w1_slave'
#Connect MySQL
#-----------------------------------------------------------------------------------
cnx = mysql.connector.connect(user='root',password='invoker',
host='localhost',
database='temp-at-interrupt')
cnx.close()
#
#Get Temperature Values.
#-----------------------------------------------------------------------------------
def tempRead():
t = open(temp_sensor, 'r')
lines = t.readlines()
t.close()
temp_output = lines[1].find('t=')
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string)/1000.0
return round(temp_c,1)
#Insert new data
#-----------------------------------------------------------------------------------
while True:
print(temp)
datatimeWrite = (time.strftime("%Y-%m-%d ") + time.strftime("%H:%M:%S"))
print (datetimeWrite)
sql = ("""INSERT INTO tempLog (datetime,temperature) VALUES (%s,%s)""",(datetimeWrite,temp))
try:
print ("Writing to database...")
# Execute the SQL command
cur.execute(*sql)
# Commit your changes in the database
db.commit()
print ("Write Complete")
except:
# Rollback in case there is any error
db.rollback()
print ("Failed writing to database")
cur.close()
db.close()
break
You use return not inside a function, which is illegal Python (and most programming languages) syntax.
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string)/1000.0
return round(temp_c,1) # <---- problematic return statement outside a function
I believe that this if block is part of tempRead() function, so a fix is to delete the empty line before the if block, and ident all the code in the if block by 4 spaces:
def tempRead():
t = open(temp_sensor, 'r')
lines = t.readlines()
t.close()
temp_output = lines[1].find('t=')
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = float(temp_string)/1000.0
return round(temp_c,1)
I have been working on a weather station, which I want to be able to automatically post current weather to twitter. So far, I have been able to easily post regular strings such as t.statuses.update(status= 'twitter post!')
but whenever I attempt to post a variable, the current temperature for instance, I get this error:
Traceback (most recent call last): File
"/home/pi/Desktop/Python2Projects/MAIN.py", line 79, in
t.statuses.update (status= 'Current temperature in dowd house: %d F \n Windspeed: %d mph' %(temp, vmph) ) AttributeError: 'int' object
has no attribute 'statuses'
Here is my code so far, the twitter post line is at the very bottom:
#sets up libraries
from sys import argv
import os
import glob
import subprocess
import RPi.GPIO as GPIO
import time
import datetime
#Sets up twitter library
from twitter import *
access_token = 'secret'
access_token_secret = 'cant tell you'
consumer_key = 'i have to change all these'
consumer_secret = 'they usually have my twitter access keys'
t = Twitter(auth=OAuth(access_token, access_token_secret, consumer_key, consumer_secret))
#sets up GPIO for windspeed Hall effect sensor
GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN)
#sets up GPIO for temperature probe
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
#usus probe to take temperature
def read_temp_raw():
catdata = subprocess.Popen(['cat',device_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out,err = catdata.communicate()
out_decode = out.decode('utf-8')
lines = out_decode.split('\n')
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return float(temp_f) #float(temp_c)
temp = read_temp()
#setup for windspeed sensor
timy = datetime.datetime.now()
timx = datetime.datetime.now()
rotations = 0
#radious of windspeed sensor in meters
r = .1
#time in seconds you want sensor to collect data for average speed
t = 5
#main windspeed loop
timeout = time.time() + t
while True:
GPIO.wait_for_edge(27, GPIO.BOTH)
hallActive = GPIO.input(27)
if time.time() > timeout:
break
elif( hallActive == False ):
rotations = rotations + 1
elif( hallActive == True ):
pass
#function that converts rotations/s to mph
vmph = (r*6.28*rotations*2.2369) / t
GPIO.cleanup()
print 'Current temperature: %d F \n Windspeed: %d mph \n' %(temp, vmph)
t.statuses.update (status= 'Current temperature: %d F \n Windspeed: %d mph' %(temp, vmph) )
end of code
Thanks so much for any help or suggestions! It's greatly appreciated.
You are getting this problem because you assigned t to the value 5 here:
#time in seconds you want sensor to collect data for average speed
t = 5
After that point, you try to do t.statues but of course that won't work, since t is an integer and not a reference to the twitter api.
The easy way to solve this problem is to change the name of the twitter api handle at the very top of your script:
twitter_api = Twitter(auth=OAuth(access_token,
access_token_secret,
consumer_key, consumer_secret))
Then at the bottom, adjust your code accordingly:
temp_line = 'Current temperature: %d F \n Windspeed: %d mph \n' %(temp, vmph)
print(temp_line)
twitter_api.statuses.update(status=temp_line)
As a general rule, try to avoid single character named variables. They just add confusion to your code (as in this example) plus they make your code difficult to maintain in the future (for your, or anyone else that has to maintain it).
Python provides an excellent style guide, called PEP-8 which has some guidelines on how to format your code.