#This is my first Python program, so you folks who know Python well will most likley wonder why I do some of the things I did,the way I did them......... I don't know any better :)
#This is SMS based because I wanted to be able to control the device from any type of phone ( no app required)
# The commands are sent as CMD xyyy. the CMD must be the first three charactures followed by a space, then four digits. x=the Mode, and yyy is the data. This is detailed in the code below.
#The one item that you will need to complete the project is a sim card for the radio, and it's associated "phone" number. I used a Hologram sim. I used their easy tool kit and with a few commands, got it
#to send an sms from the Nova to my phone, thus capturing the phone number.
# to make it run at boot-up, type:
#sudo nano /etc/rc.local
#this will open the editor. Insert:
# sudo python /home/pi/python_games/Heatercode.py &
#NOTE: the program name will be yours.
#
# exit 0
#save it. Make sure you run the pi config and make tho boot up to the command prompt and dnot the GUI desktop. You can always type startx to bring up the desktop.
# Well, that's about it. Feel free to ask any questions. I can't guarantee I will have the answer, but I'll try.. :-)
# Oh, one last note. The relay is a single pole device. I used and inexpensive , 3 wire, extenstion coard. Make sure you break the "hot" (usually the black) wire with the relay. If no black, it will be the wire that connects to
# the smaller of the two blades on the plug.
import serial #this is the serial package that allows us to chat with the USB radio as a serial device.
import time # basic time functions
import os
import glob
import RPi.GPIO as GPIO #access to the IO pins
Minut = 0
GPIO.setwarnings(False)
Relay = 11
GPIO.setmode(GPIO.BOARD)
GPIO.setup(Relay, GPIO.OUT)
COMMAND = 0
Phnumber = 0
Action = 1
Msg = 0
Mode = 8
sentflag = 1
Timer = 0
Stime = 0
HighTemp = 55 # initial hightemp setting F
SendFlag=0
Temp = 0
TEST = 0 # if test = 1 then the device will NOT return SMS.This is to reduce cost. Strictly a test function.
TMode = 0
dret = "ON"
SigLevel = 0
remaining = 0
RelayFlag =0
Help = 0
os.system("modprobe w1-gpio") #this sets the i/o for the temp sensor
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"
#this proceedure returns the device temperture when called
#it will detect the DS18B20 sensor ID and retrieve the raw temperature
#thanks to Adafruit folks for the heart of this temperature proceedure
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= temp_raw()
temp_output = lines[1].find("t=")
if temp_output != -1:
temp_string = lines[1].strip()[temp_output+2:]
temp_c = int (temp_string) / 1000.0
temp_f = int (temp_c * 9 / 5 + 32)
Temp = temp_f
return temp_f
ser = serial.Serial("/dev/ttyACM2", baudrate=38400, timeout=1) #this sets the serial com for the Nova Radio
#time.sleep(30)
#this are the AT commands that set the radio and the SMS format. The documtation from the Halo folks is excellent. You can look up the commands easily. :)
ser.write("\x1a") #this is to flush any SMS that was lingering in the radio
ser.write("AT\r")
time.sleep(1)
ser.write("AT\r")
time.sleep(1)
ser.write("at+creg?\r\n")
rcs = ser.read(100)
print (rcs)
ser.write("at+csms=1\r")
rcs = ser.read(50)
print rcs
time.sleep(.1)
ser.write("at+cfun=1\r")
time.sleep(.1)
ser.write("at+cmgf=1\r")
time.sleep(.1)
ser.write("ate0\r\n")
time.sleep(.1)
ser.write("at+cfun=1\r")
time.sleep(.1)
ser.write("at+cpms=\"sm\",\"sm\",\"sm\"\r")
time.sleep(.5)
ser.write("at+cnmi=1,0,0,0\r")
time.sleep(.1)
ser.write("at+cmgr=1\r")
rcs = ser.read(150)
Tres = len(rcs)
startime = time.time() #this starts our basic time keeping
while True:
ser.write("at\r") #Just a basic AT wakeup command
time.sleep(.5)
ser.write("at+cpms?\r") #ask the radio for the status of message storage.( have we received any SMS)
rcs = ser.read(150)
ind = rcs.find("CPMS:") # ind will contain the number of SMS's received
if ind >= 2:
print "ind:",int(ind)
print "RCS",rcs[ind+11]
print (rcs)
try:
print "Point A:",rcs[ind+11]
except IndexError:
print "oops!"
ser.write("\x1a")
xd = int (rcs[ind+11])
# print "Point0",int(xd)
if xd >= 1:
ser.write("at+cmgl\r") # if we have received and SMS, read it and decode it
rct = ser.read(150)
ind = rct.find("READ")
print "point1:", (rct)
# print "Point2:", int(ind)
Phnumber = rct[ind+8:ind+19]
CMD = rct[ind+44:ind+54]
print "CMD:",CMD # we check for the actual "CMD" received
print "PHnumber:",Phnumber #extract the incomming phone number so we know who to reply to
ser.write("at+cmgd=1,1\r")
DCMD = CMD[2:5]
print DCMD
Good = 0 # this is where we check for the help request.
if DCMD == "hel":
Help = 1
if DCMD == "Hel":
Help = 1
if DCMD == "HEL":
Help = 1
if DCMD == "Cmd": # we accept upper and lower case "CMD"
Good =1
if DCMD == "CMD":
Good =1
if DCMD == "cmd":
Good =1
if Good:
COMMAND = CMD[6:10]
try:
Action = int (COMMAND)
except ValueError: # if the command is not the 4 digits it should be we allow the error and zero it
print "Number Error" # this keeps the program from halting on the error
Action = 0
print "New Command:",COMMAND
OldMode = Mode
TMode = Action/1000 # the command is 4 digits, 1240= Mode 1 for 240 minutes. Dividing by 1000 gives us the Mode
if TMode == 4: # mode 4 is the status request
Mode = OldMode # make sure we keep the prior mode , i.e. the unit was in mode 1 and is counting down to turn off.
else:
Mode = TMode
Timer = Action % 1000 #we divide by 1000 and take the remainder as the number of minutes we want to operate
Stime = Minut + Timer # i.e. 1040 /1000 = 1(mode) and the remainder is 40, the minutes to operate.
SendFlag=1 # this flage keeps track if we have sent an sms.
ser.write("\r")
time.sleep (1)
ser.write("at+csq\r") # this grabs the signal level from the radio
Sig = ser.read (50)
ind = Sig.find("Q")
print (Sig)
SigLevel = Sig[ind+3:ind+6] # this is where we extract the value from the string
print "Sig:", SigLevel
print(read_temp()) #go read the temperature
Temp = int(read_temp())
seconds = int (time.time() - startime)
print COMMAND,":",Phnumber, "Mode:", Mode, " On for:",Timer, "Minutes Stoptime:",Stime, "HighTemp:",HighTemp
Msg = 0
xc = "0"
xd = "0"
Minut = seconds / 60
if Mode == 1:
if Stime > Minut:
remaining = Stime - Minut
RelayFlag =1 #turn on the relay flag if time remains
else:
remaining =0
RelayFlag =0
if Mode == 2:
if Temp < HighTemp: #check to see if the ambient tempertature is below our high set point
if Stime > Minut: # if it is, then check the timer. turn on the relay flag if time ramains
remaining = Stime - Minut
RelayFlag =1
else:
remaining = 0
RelayFlag = 0
else:
Stime = Minut
remaining = 0
RelayFlag = 0
if Mode == 3: # if the ambient temperature is below our high temperature set point, turn on the relay flag
if Temp < HighTemp:
RelayFlag =1
else:
# Mode = 1
Stime = 0
RelayFlag =0
if TMode == 4:
Mode = Mode # this is a status request
if Mode == 5:
HighTemp = Timer # mode 5 takes the lower 3 digits of the comand and sets our high temperature limit
# i.e 5055 = Mode 5 and sets our high temp limit to 55 degrees F
if RelayFlag == 1:
GPIO.output(Relay, GPIO.HIGH) # this turns on the relay if the flag is set
dret = "ON"
sentflag=0
else:
GPIO.output(Relay, GPIO.LOW)
dret = "OFF"
if sentflag == 0:
sentflag = 1
SendFlag = 1
print "SendFlag:",SendFlag, ": Sentflag;",sentflag, " HelpFlag:", Help
print Phnumber,":",Mode,":",dret,":",remaining,":",Temp,":",HighTemp,":",SigLevel
if Help: # if we received an "Help" request, the following gets sent
ser.write("at+cmgs=\"") #set the radio to send an SMS
ser.write(Phnumber) #the phone number to send it to
ser.write("\"\r")
time.sleep(5) #the actual message
ser.write("Mode 1: 1240= on for 4hrs\n")
ser.write("Mode 2: 2300 on 5hrs OR HighTemp\n")
ser.write("Mode 3: On UNLESS HighTemp\n" )
ser.write("Mode 4: Request Status\n" )
ser.write("Mode 5: Set HighTemp:5055 sets HighTemp to 55f")
ser.write("\x1a") # this is the command to the radio to commence the sending of the SMS
Help = 0
SendFlag=0
if SendFlag:
if TEST == 0: # The test flag, if set, skips this section, resulting in NO sms being sent
print "Sending SMS"
ser.write("at+cmgs=\"")
ser.write(Phnumber)
ser.write("\"\r")
time.sleep(5)
ser.write("Mode:")
ser.write(str(Mode))
ser.write( " ")
ser.write(" Heater:")
ser.write(dret)
if dret == "ON":
ser.write(" For ")
ser.write(str(remaining))
ser.write(" Minutes")
ser.write(", Temp:")
ser.write(str(Temp))
ser.write(" HighTemp set to:")
ser.write(str(HighTemp))
ser.write(" Signal Level:")
ser.write(str(SigLevel))
ser.write("\x1a")
print "SMS complete"
SendFlag = 0
print Minut ,":", seconds % 60
time.sleep(5)
Comments