This program works partially. The part that i cannot get to work is combining the functions under a class. All i am looking for is to have a user input set float variable and compare it with a raw float variable from a temp sensor. I want to set a temperature (target) value THEN run a loop of temp reading in the background.
I am VERY new to programming. I have been reading alot but dont understand why the variable temp_c when under a class still comes up as not defined ?
How do i combine this program so that every variable is defined and i have one loop running after the temperature target is set.
After running program i see:
Enter Temp:22 Traceback (most recent call last):
File "/home/pi/Desktop/Trial 1.py", line 16,
in <module> class HotTub:
File "/home/pi/Desktop/Trial 1.py", line 40, in HotTub
temp_c=read_temp()
File "/home/pi/Desktop/Trial 1.py", line 27, in read_temp
lines = read_temp_raw() NameError: name
'read_temp_raw' is not defined
First code sample does not work, second does. :
import os
import glob
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(22, GPIO.OUT, initial=GPIO.LOW)
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'
class HotTub:
target=float(input("Enter Temp:" ))
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:
try:
temp_c=read_temp()
if temp_c>=target:
GPIO.setmode(GPIO.BOARD)
GPIO.output(22, GPIO.HIGH)
print ('Temp is higher than',target,temp_c)
else:
GPIO.setmode(GPIO.BOARD)
GPIO.output(22, GPIO.LOW)
print ('Temp is lower than',target,temp_c)
time.sleep(0.5)
except KeyboardInterrupt:
print("W: interrupt received, stopping…")
GPIO.cleanup()
print ("Exit")
import os
import glob
import time
import RPi.GPIO as GPIO
GPIO.setwarnings(False) # Ignore warning for now
GPIO.setmode(GPIO.BOARD) # Use physical pin numbering
GPIO.setup(22, GPIO.OUT, initial=GPIO.LOW) # Set pin 16 to be an output pin and set initial value to low (off)
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
def compare_temp():
temp_c=read_temp()
a=float(22)
if temp_c>a:
GPIO.setmode(GPIO.BOARD)
GPIO.output(22, GPIO.HIGH)
print ('Temp is higher than 22',temp_c)
else:
GPIO.setmode(GPIO.BOARD)
GPIO.output(22, GPIO.LOW)
print ('Temp is lower than 22',temp_c)
time.sleep(0.5)
while True:
try:
compare_temp()
except KeyboardInterrupt:
print("W: interrupt received, stopping…")
GPIO.cleanup()
print ("Exit")
When you convert module (2nd sample ) code to a class (1st) you need to call function via its class instance
so read_temp_raw() call becomes self.read_temp_raw() in class body or
#
myinstance = HotTub()
myinstance.read_temp_raw()
#
Classes are namespaces and can hold lot of objects, you could adress
variables the same way eg:
self.temp_c = some_value
or
print(myinstance.temp_c)
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'm trying to display the temperature from a temperature sensor on a 7 segment display. Both are connected to my Raspberry Pi. I need to store the current temperature in a variable, and of course that is always changing.
My problem is that the variable only prints what the temperature is at the point when the script is ran. It does not change as the temperature changes.
import os
import time
os.system('modprobe wl-gpio')
os.system('modprobe wl-therm')
temp_sensor = '/sys/bus/w1/devices/28-0316201553ff/w1_slave'
temp_f = 0
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
temp_f = temp_c * 9.0 // 5.0 + 32.0
global temp_f
temp_f = int(temp_f)
read_temp()
while True:
print(temp_f)
time.sleep(1)
# Below is what I will eventually need to run in order to display the digits on my 7-segment display.
'''
while True:
print( map(int,str(temp_f)) )
time.sleep(1)
'''
You are only reading the temperature once and displaying the same value over and over in your while loop. You should periodically re-read the temperature inside the loop:
while True:
read_temp()
print(temp_f)
time.sleep(1)
A larger sleep value may help if the temperature read operation requires too much power.
You're only calling read_temp() once, and printing the same value on each iteration. Change your loop to this:
while True:
read_temp()
print(temp_f)
time.sleep(1)
However, global variable usage like this tends to lead to maintainability problems down the road. I'd do it like this:
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
temp_f = temp_c * 9.0 // 5.0 + 32.0
return int(temp_f)
while True:
temp_f = read_temp()
print(temp_f)
time.sleep(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.
I have a problem with my project, I have a little python script to read my gas meter.
Every revolution of digits a small magnet inside the gas meter close to the reed switch makes an input for my raspberry. The problem is when the magnet stops close to the sensor circuit leaving on a high level, which cause false inputs, here my script.
Any suggestion? thanks to all
#!/usr/bin/env python
import time
import datetime
import os.path
import pycurl
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(10, GPIO.RISING, bouncetime = 5000)
def GetGas(arg):
time.sleep(0.01) # need to filter out the false positive of some power fluctuation
if GPIO.input(10) != GPIO.HIGH:
return
gastotale=0
if os.path.isfile('/var/www/myscripts/gas/gastotale.txt'):
file = open("/var/www/myscripts/gas/gastotale.txt","r")
gastotale = float(file.read())
file.close()
gastotale = gastotale+0.01
file = open("/var/www/myscripts/gas/gastotale.txt","w")
file.write(str(gastotale))
file.close()
now = datetime.datetime.now()
fileday = '/var/www/myscripts/gas/'+now.strftime("%Y-%m-%d")+'.txt'
gasday = 0
if os.path.isfile(fileday):
file = open(fileday,"r")
gasday = float(file.read())
file.close()
gasday = gasday+0.01
file = open(fileday,"w")
file.write(str(gasday))
file.close()
oem = pycurl.Curl()
oem.setopt(oem.URL, 'http://emoncms.org/input/post.json?node=0
csv=0,'+str(gasday)+',0,0,'+str(gastotale)+'&apikey=dfb6ccf')
oem.perform()
laststate = 0
while True:
if (GPIO.input(10) == 1 ):
if (laststate == 0):
gastotale = gastotale+0.01
laststate=1
else:
laststate=0
time.sleep(30)