I have 3 files lcdtest.py, lcd.py and alarmfunctionr.py. I am trying to control the attached lcd display on my raspberry pi with the lcdtest.py script.
!/usr/bin/env python import paho.mqtt.client as paho import globals import time from alarmfunctionsr import SendToLCD from lcd import noDisplay from lcd import message globals.init() SendToLCD(12, "test lcd" ,1) #Test time.sleep(5) lcd.message("test with message") time.sleep(5) noDisplay
The import from alarmfunctionsr seem to work ok but i get an cannot import name error when i try the same for the lcd script.
lcd.py:
#!/usr/bin/python # # based on code from lrvick and LiquidCrystal # lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py # LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp # from time import sleep class CharLCD(object): # commands LCD_CLEARDISPLAY = 0x01 LCD_RETURNHOME = 0x02 LCD_ENTRYMODESET = 0x04 LCD_DISPLAYCONTROL = 0x08 LCD_CURSORSHIFT = 0x10 LCD_FUNCTIONSET = 0x20 LCD_SETCGRAMADDR = 0x40 LCD_SETDDRAMADDR = 0x80 # flags for display entry mode LCD_ENTRYRIGHT = 0x00 LCD_ENTRYLEFT = 0x02 LCD_ENTRYSHIFTINCREMENT = 0x01 LCD_ENTRYSHIFTDECREMENT = 0x00 # flags for display on/off control LCD_DISPLAYON = 0x04 LCD_DISPLAYOFF = 0x00 LCD_CURSORON = 0x02 LCD_CURSOROFF = 0x00 LCD_BLINKON = 0x01 LCD_BLINKOFF = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 # flags for display/cursor shift LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 LCD_MOVERIGHT = 0x04 LCD_MOVELEFT = 0x00 # flags for function set LCD_8BITMODE = 0x10 LCD_4BITMODE = 0x00 LCD_2LINE = 0x08 LCD_1LINE = 0x00 LCD_5x10DOTS = 0x04 LCD_5x8DOTS = 0x00 def __init__(self, pin_rs=25, pin_e=24, pins_db=[23, 17, 27, 22], GPIO=None): # Emulate the old behavior of using RPi.GPIO if we haven't been given # an explicit GPIO interface to use if not GPIO: import RPi.GPIO as GPIO GPIO.setwarnings(False) self.GPIO = GPIO self.pin_rs = pin_rs self.pin_e = pin_e self.pins_db = pins_db self.GPIO.setmode(GPIO.BCM) self.GPIO.setup(self.pin_e, GPIO.OUT) self.GPIO.setup(self.pin_rs, GPIO.OUT) for pin in self.pins_db: self.GPIO.setup(pin, GPIO.OUT) self.write4bits(0x33) # initialization self.write4bits(0x32) # initialization self.write4bits(0x28) # 2 line 5x7 matrix self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor self.write4bits(0x06) # shift cursor right self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS self.displayfunction |= self.LCD_2LINE # Initialize to default text direction (for romance languages) self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode self.clear() def begin(self, cols, lines): if (lines > 1): self.numlines = lines self.displayfunction |= self.LCD_2LINE def home(self): self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero self.delayMicroseconds(3000) # this command takes a long time! def clear(self): self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time def setCursor(self, col, row): self.row_offsets = [0x00, 0x40, 0x14, 0x54] self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row])) def noDisplay(self): """ Turn the display off (quickly) """ self.displaycontrol &= ~self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def display(self): """ Turn the display on (quickly) """ self.displaycontrol |= self.LCD_DISPLAYON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noCursor(self): """ Turns the underline cursor off """ self.displaycontrol &= ~self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def cursor(self): """ Turns the underline cursor on """ self.displaycontrol |= self.LCD_CURSORON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def noBlink(self): """ Turn the blinking cursor off """ self.displaycontrol &= ~self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def blink(self): """ Turn the blinking cursor on """ self.displaycontrol |= self.LCD_BLINKON self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol) def DisplayLeft(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT) def scrollDisplayRight(self): """ These commands scroll the display without changing the RAM """ self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT) def leftToRight(self): """ This is for text that flows Left to Right """ self.displaymode |= self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def rightToLeft(self): """ This is for text that flows Right to Left """ self.displaymode &= ~self.LCD_ENTRYLEFT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def autoscroll(self): """ This will 'right justify' text from the cursor """ self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def noAutoscroll(self): """ This will 'left justify' text from the cursor """ self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) def write4bits(self, bits, char_mode=False): """ Send command to LCD """ self.delayMicroseconds(1000) # 1000 microsecond sleep bits = bin(bits)[2:].zfill(8) self.GPIO.output(self.pin_rs, char_mode) for pin in self.pins_db: self.GPIO.output(pin, False) for i in range(4): if bits[i] == "1": self.GPIO.output(self.pins_db[::-1][i], True) self.pulseEnable() for pin in self.pins_db: self.GPIO.output(pin, False) for i in range(4, 8): if bits[i] == "1": self.GPIO.output(self.pins_db[::-1][i-4], True) self.pulseEnable() def delayMicroseconds(self, microseconds): seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds sleep(seconds) def pulseEnable(self): self.GPIO.output(self.pin_e, False) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns self.GPIO.output(self.pin_e, True) self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns self.GPIO.output(self.pin_e, False) self.delayMicroseconds(1) # commands need > 37us to settle def message(self, text): """ Send string to LCD. Newline wraps to second line""" for char in text: if char == '\n': self.write4bits(0xC0) # next line else: self.write4bits(ord(char), True) def DisplayLCD(msg): lcd = CharLCD() lcd.clear() x=msg.find("**") if x>0: line1=msg[0:x] line2=msg[x+2:len(msg)] else: line1=msg line2="" lcd.message(line1+"\n"+line2)
alarmfunctionsr.py:
#!/usr/bin/env python """ import globals import urllib2 import smtplib import serial import time import sys import thread import RPi.GPIO as GPIO import os, glob, time, operator from email.mime.text import MIMEText from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from time import sleep def find_all(a_str, sub): start = 0 cnt=0 while True: start = a_str.find(sub, start) if start == -1: return cnt start += len(sub) cnt=cnt+1 def isNumber(x): # Test whether the contents of a string is a number try: val = int(x) except ValueError: return False return True def get_latest_photo(files): lt = operator.lt if not files: return None now = time.time() latest = files[0], now - os.path.getctime(files[0]) for f in files[1:]: age = now - os.path.getctime(f) if lt(age, latest[1]): latest = f, age return latest[0] def UpdateHostThread(function,opcode): try: thread.start_new_thread(UpdateHostThread, (function,opcode, ) ) except: print "Error: unable to start thread" def UpdateHost(function,opcode): # Sends data to the server script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function) i=0 for x in opcode: script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i]) i=i+1 if globals.PrintToScreen: print "Host Update: "+script_path try: rt=urllib2.urlopen(script_path) except urllib2.HTTPError: if globals.PrintToScreen: print "HTTP Error" return False time.sleep(.2) temp=rt.read() if globals.PrintToScreen: print temp l = find_all(temp,"/n"); RecordSet = temp.split(',') c=[] y=0 c.append([]) for x in RecordSet: if x=="/n": y=y+1 if y < l: c.append([]) else: if isNumber(x): c[y].append(int(x)) else: c[y].append(x) rt=ProcessActions(c) if rt==False: return(False) else: return(c) def ProcessActions(ActionList): FalseInd=True for x in ActionList: if x[0]=="/EMAIL": SendEmailAlertFromRule(x[1], x[2],0) x.remove if x[0]=="/SEMAIL": SendEmailAlert(x[1]) x.remove if x[0]=="/CHIME": StartChimeThread() x.remove if x[0]=="/rn588": exit() if x[0]=="/FALSE": FalseInd=False if x[0]=="/SIREN": StartSirenThread(x[2]) x.remove if x[0]=="/PHOTO": SendEmailAlertFromRule(x[1], x[2],1) x.remove if x[0]=="/RELAYON": SwitchRelay(1) x.remove if x[0]=="/RELAYOFF": SwitchRelay(0) x.remove if x[0]=="/WRELAYON": SwitchRFRelay(1) x.remove if x[0]=="/WRELAYOFF": SwitchRFRelay(0) x.remove return(FalseInd) def StartSirenThread(Zone): try: thread.start_new_thread(Siren, (Zone, ) ) except: print "Error: unable to start thread" def SwitchRelay(onoff): GPIO.setmode(GPIO.BOARD) GPIO.setup(globals.RelayPin, GPIO.OUT) GPIO.output(globals.RelayPin,onoff) def SwitchRFRelay(onoff): # declare to variables, holding the com port we wish to talk to and the speed port = '/dev/ttyAMA0' baud = 9600 # open a serial connection using the variables above ser = serial.Serial(port=port, baudrate=baud) # wait for a moment before doing anything else sleep(0.2) for i in range(0,3): if (onoff==True): ser.write('a{}RELAYAON-'.format(globals.WRelayPin)) else: ser.write('a{}RELAYAOFF'.format(globals.WRelayPin)) time.sleep(2) ser.close def SendToLCD(GPIOnumber, Location, status): import paho.mqtt.client as paho if status==0: ActionStr="_" topic="alarm_activity" else: if status==1: ActionStr="_" topic="alarm_activity" else: topic="temperature" if status==2: ActionStr=str(GPIOnumber)+","+Location else: ActionStr="Undefined" #client = mosquitto.Mosquitto('privateeyepi') client = paho.Client() client.connect(globals.lcd_ip) if status <= 1: if globals.PrintToScreen: print str(Location)+"**"+str(ActionStr) client.publish(topic, str(Location)+"**"+str(ActionStr)) else: if globals.PrintToScreen: print str(ActionStr) client.publish(topic, ActionStr) client.disconnect() def Siren(Zone): GPIO.setmode(GPIO.BOARD) if globals.UseSiren == True: GPIO.setup(globals.SirenGPIOPin, GPIO.OUT) #Siren pin setup else: return if globals.SirenDelay>0: globals.SirenStartTime = time.time() while time.time() < globals.SirenStartTime + globals.SirenDelay: if globals.BeepDuringDelay: GPIO.output(globals.SirenGPIOPin,True) time.sleep(1) GPIO.output(globals.SirenGPIOPin,False) time.sleep(4) GPIO.output(globals.SirenGPIOPin,True) globals.SirenStartTime = time.time() if globals.PrintToScreen: print "Siren Activated" while time.time() < globals.SirenStartTime + globals.SirenTimeout: time.sleep(5) if CheckForSirenDeactivation(Zone) == True: break GPIO.output(globals.SirenGPIOPin,False) if globals.PrintToScreen: print "Siren Deactivated" def CheckForSirenDeactivation(Zone): # Routine to fetch the location and zone descriptions from the server RecordSet = GetDataFromHost(16,[Zone]) if globals.PrintToScreen: print RecordSet ZoneStatus=RecordSet[0][0] if ZoneStatus=="FALSE": return (True) def StartChimeThread(): try: thread.start_new_thread(SoundChime, ()) except: print "Error: unable to start thread" def SoundChime(): if globals.ChimeDuration>0: GPIO.setmode(GPIO.BOARD) GPIO.setup(globals.ChimeGPIOPin, GPIO.OUT) #Siren pin setup GPIO.output(globals.ChimeGPIOPin,True) time.sleep(globals.ChimeDuration) GPIO.output(globals.ChimeGPIOPin,False) def GetDataFromHost(function,opcode): # Request data and receive reply (request/reply) from the server script_path = "https://www.privateeyepi.com/alarmhostr.php?u="+globals.user+"&p="+globals.password+"&function="+str(function) i=0 for x in opcode: script_path=script_path+"&opcode"+str(i)+"="+str(opcode[i]) i=i+1 if globals.PrintToScreen: print script_path try: rt = urllib2.urlopen(script_path) except urllib2.HTTPError: return False temp=rt.read() if globals.PrintToScreen: print temp l = find_all(temp,"/n"); RecordSet = temp.split(',') c=[] y=0 c.append([]) for x in RecordSet: if x=="/n": y=y+1 if y < l: c.append([]) else: if isNumber(x): c[y].append(int(x)) else: c[y].append(x) rt=ProcessActions(c) if rt==False: return(False) else: return(c) return(c) def BuildMessage(SensorNumber): # Routine to fetch the location and zone descriptions from the server RecordSet = GetDataFromHost(6,[SensorNumber]) if globals.PrintToScreen: print RecordSet if RecordSet==False: return zonedesc=RecordSet[0][0] locationdesc = RecordSet[0][1] messagestr="This is an automated email from your house alarm system. Alarm activated for Zone: "+zonedesc+" ("+locationdesc+")" return messagestr def BuildMessageFromRule(SensorNumber, smartruleid): RecordSet = GetDataFromHost(7,[smartruleid, SensorNumber]) if RecordSet==False: return numrows = len(RecordSet) messagestr="This is an automated email from PrivateEyePi. Rule triggered for Zone(s): "+RecordSet[0][3]+", Location: "+RecordSet[0][4]+" and for rule " for i in range(0,numrows,1): if RecordSet[i][0]==1: messagestr=messagestr+"Alarm Activated" if RecordSet[i][0]==2: messagestr=messagestr+"Alarm Deactivated" if RecordSet[i][0]==3: messagestr=messagestr+"Circuit Open" if RecordSet[i][0]==4: messagestr=messagestr+"Circuit Closed" if RecordSet[i][0]==5: messagestr=messagestr+"Open for " + str(RecordSet[i][1]) + " Minutes" if RecordSet[i][0]==6: messagestr=messagestr+"Closed for " + str(RecordSet[i][1]) + " Minutes" if RecordSet[i][0]==7: messagestr=messagestr+"Where sensor value (" + str(RecordSet[i][5]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2]) if RecordSet[i][0]==8: messagestr=messagestr+"Tamper" if RecordSet[i][0]==9: messagestr=messagestr+"Day Of Week is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2]) if RecordSet[i][0]==10: messagestr=messagestr+"Hour Of Day is between " + str(RecordSet[i][1]) + " and " + str(RecordSet[i][2]) if RecordSet[i][0]==11: messagestr=messagestr+"Where secondary sensor value (" + str(RecordSet[i][6]) + ") is between " + str(RecordSet[i][1]) + " " + str(RecordSet[i][2]) if i<numrows-1: messagestr=messagestr + " AND " return messagestr def SendEmailAlertFromRule(ruleid, SensorNumber, photo): try: thread.start_new_thread(SendEmailAlertThread, (SensorNumber, ruleid, True, photo, ) ) except: print "Error: unable to start thread" def SendEmailAlert(SensorNumber): try: thread.start_new_thread(SendEmailAlertThread, (SensorNumber,0 , False, False) ) except: print "Error: unable to start thread" def SendEmailAlertThread(SensorNumber, smartruleid, ruleind, photo): # Get the email addresses that you configured on the server RecordSet = GetDataFromHost(5,[0]) if RecordSet==False: return numrows = len(RecordSet) if globals.smtp_server=="": return if ruleind: msgtext = BuildMessageFromRule(SensorNumber, smartruleid) else: msgtext = BuildMessage(SensorNumber) for i in range(numrows): # Define email addresses to use addr_to = RecordSet[i][0] addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP # Construct email if (photo==1): files = 0 files = glob.glob(globals.photopath) latestphoto = get_latest_photo(files) msg = MIMEMultipart() else: msg = MIMEText(msgtext) msg['To'] = addr_to msg['From'] = addr_from msg['Subject'] = 'Alarm Notification' #Configure to whatever subject line you want #attach photo if (photo==1): msg.preamble = 'Multipart message.\n' part = MIMEText(msgtext) msg.attach(part) part = MIMEApplication(open(latestphoto,"rb").read()) part.add_header('Content-Disposition', 'attachment', filename=latestphoto) msg.attach(part) # Send the message via an SMTP server #Option 1 - No Encryption if globals.email_type==1: s = smtplib.SMTP(globals.smtp_server) elif globals.email_type==2: #Option 2 - SSL s = smtplib.SMTP_SSL(globals.smtp_server, 465) elif globals.email_type==3: #Option 3 - TLS s = smtplib.SMTP(globals.smtp_server,587) s.ehlo() s.starttls() s.ehlo() else: s = smtplib.SMTP(globals.smtp_server) s.login(globals.smtp_user,globals.smtp_pass) s.sendmail(addr_from, addr_to, msg.as_string()) s.quit() if globals.PrintToScreen: print msg; def SendCustomEmail(msgText, msgSubject): # Get the email addresses that you configured on the server RecordSet = GetDataFromHost(5,[0]) if RecordSet==False: return numrows = len(RecordSet) if globals.smtp_server=="": return for i in range(numrows): # Define email addresses to use addr_to = RecordSet[i][0] addr_from = globals.smtp_user #Or change to another valid email recognized under your account by your ISP # Construct email msg = MIMEText(msgText) msg['To'] = addr_to msg['From'] = addr_from msg['Subject'] = msgSubject #Configure to whatever subject line you want # Send the message via an SMTP server #Option 1 - No Encryption if globals.email_type==1: s = smtplib.SMTP(globals.smtp_server) elif globals.email_type==2: #Option 2 - SSL s = smtplib.SMTP_SSL(globals.smtp_server, 465) elif globals.email_type==3: #Option 3 - TLS s = smtplib.SMTP(globals.smtp_server,587) s.ehlo() s.starttls() s.ehlo() else: s = smtplib.SMTP(globals.smtp_server) s.login(globals.smtp_user,globals.smtp_pass) s.sendmail(addr_from, addr_to, msg.as_string()) s.quit() if globals.PrintToScreen: print msg;