LED Sign: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 314: | Line 314: | ||
} | } | ||
?> | ?> | ||
</pre> | |||
The sign now "dings" with a physical alarm bell when updated. | |||
<pre> | |||
import serial,time,sys | |||
s = serial.Serial('/dev/ttyUSB0', baudrate = 9600, rtscts='rtscts', xonxoff='xonxoff', timeout=1000) | |||
time.sleep(1.5) | |||
s.setDTR(False) | |||
time.sleep(0.022) | |||
s.setDTR(True) | |||
t=sys.argv[1] | |||
s.write(str(t)+"\n") | |||
time.sleep((float(t))/1000) | |||
</pre> | </pre> | ||
Revision as of 15:06, 6 September 2011
http://wls.wwco.com/ledsigns/prolite/
Source Code
signDaemon.py By Textile Note... There is a known bug where control C does not work correctly you will have to kill the process if you need to stop it.
#support python 3.0 compliant print statement
from __future__ import print_function
#default imports
import socket,sys,threading,time,re
#pyserial imports
import serial
class server(threading.Thread):
def __init__(self,signNS,controllerNS,ip="0.0.0.0",port=9001):
threading.Thread.__init__(self)
self.ip = ip
self.port = port
self.sign = signNS #sign is the namespace of the led sign class
self.controller = controllerNS #namespace of the controller used catch request to kills
self.die = False
def OpenListener(self):
"""
Open socket to lisen for messages
"""
self.mySocket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
self.mySocket.bind((self.ip, self.port))
self.mySocket.listen(5)
def CloseListener(self):
"""
Close Socket
"""
self.mySocket.close()
print("Listen socket closed")
def GetMessage(self):
"""
Get a message from a client and append it to the Sign Buffer to be displayed
"""
try:
print("Waiting for Connections \r")
channel, details = self.mySocket.accept()
print("We have opened a Connection with "+str(details))
try:
message = channel.recv(1024)
self.sign.signBufHistory.append('%s,%s'%(details[0],message))
self.sign.signBuffer.append(message)
except Exception:
return False
print(len(self.sign.signBuffer))
return None
except KeyboardInterrupt:
if self.controller.running.is_set():
self.controller.cancel()
return
def recover(self):
"""
recover if the listener crashes
"""
try:
self.CloseListener()
self.OpenListener()
except Exception:
print("waiting for port to close:")
try:
self.CloseListener()
time.sleep(10)
self.OpenListener()
except Exception:
print("you broke it you dumb mook")
self.controller.cancel()
def run(self):
"""
Run the thread in a loop
"""
try:
self.OpenListener()
while True:
if not self.controller.running.is_set():
self.CloseListener()
break
else:
if self.GetMessage() == False:
self.recover()
except KeyboardInterrupt:
self.CloseListener()
print("The Listener Closed")
self.cancel()
self.exit(-1)
class ledSign:
def __init__(self, tty='/dev/ttyUSB0'):
self.tty = tty
self.baud = 9600
self.bytesize = serial.EIGHTBITS
self.parity = serial.PARITY_NONE
self.stopbit = serial.STOPBITS_ONE
self.timeout = 15
self.xonxoff = 0
self.rtscts = 0
self.signBuffer = [] #buffer to be written
self.signBufHistory = [] #buffer that was written
self.formatRE = re.compile('<ID\d\d><\w\w>.*') #match something that looks like <ID01><PA>
def formatMSG(self,msg,page='A'):
"""
Format a message with page and propper headers and footers
"""
if str(msg) == '': #clear each page
fmsg = '<ID01><P%s> %s \r\n'[:1016] %(page,msg)
elif self.formatRE.match(msg) != None: #use client supplied formatting
fmsg = str(msg)+'\r\n'[:1016]
else:
fmsg = "<ID01><P%s><CL> {0} %s \r\n"[:1016] %(page,msg)
return fmsg
def OpenSerial(self):
"""
Open led sign serial device
"""
try:
self.signObj = serial.Serial(self.tty,self.baud,self.bytesize,
self.parity,self.stopbit,self.timeout,self.xonxoff,self.rtscts)
self.signObj.flush() #flush serial connection
except Exception:
print("Open Failed")
return
def ClearSign(self):
"""
A function to blank out every page on the sign
"""
print("Clearing all sign Pages")
for x in range(65,91):
#time.sleep(.2)
self.CycleWriteMsg('',chr(x)) #1016 is max message len
def SendSTDMessage(self,message,page='A'):
"""
Send a standard text message to the LED screen
"""
STDMessage = self.formatMSG(message,page)
self.signObj.write(STDMessage) #1016 is max message len
def CloseSerial(self):
"""
Flush all data to serial device and then close connection
"""
if self.signObj.isOpen() is True:
self.signObj.flush()
self.signObj.close()
def CycleWriteMsg(self,message,page):
"""
Open serial device write message then close it
"""
if self.signObj.isOpen() is True:
self.CloseSerial()
self.OpenSerial()
self.SendSTDMessage(message,page)
self.CloseSerial()
else:
self.OpenSerial()
self.SendSTDMessage(message,page)
self.CloseSerial()
class controller:
"""
Class to controll the LCD sign
"""
def __init__(self,signConnector):
self.running = threading.Event() #used to kill thread
self.newMessage = ""
self.spaceSign = ledSign(signConnector)
self.spaceSign.OpenSerial()
self.spaceSign.ClearSign()
self.spaceSign.CloseSerial()
self.ledServer = server(self.spaceSign,self)
self.ledServer.start()
self.running.set() #mark that the server thread is running
self.safety = threading.RLock()
def cancel(self):
"will not exit cleanly need to shore this up a bit"
with self.safety:
if self.running.is_set():
print("\nTerminating...")
self.running.clear()
else:
return
def exitJob(self):
"""
Close out anything we had running and exit
THIS FUNCTION IS ALL FUCKED UP IGNORE THIS CODE
Ill fix the control C break later
"""
self.spaceSign.CloseSerial()
self.ledServer.mySocket.connect((self.ledServer.ip,self.ledserver.port))
self.ledServer.mySocket.close()
return
def writeHistory(self):
"""
Write out log file of every item written to sign
"""
#should check what page its written to?
try:
if len(self.spaceSign.signBufHistory) == 0:
pass
else:
current = self.spaceSign.signBufHistory[-1]
history = open('SignHistory.csv','a')
history.writelines(current)
history.close()
csign = open('/tmp/sign','w')# added by CP for bot stuff
csign.write(current[current.find(',')+1:])
csign.close()
except IOError:
print('Sign History file not found\n')
def readHistory(self):
"""
Read in log file to display last message update
"""
try:
history = open('SignHistory.csv','r')
x = history.readlines()[-1].strip()
if x == '':
history.seek(0)
x = history.readlines()[-2].strip()
history.close()
return x
except IOError:
print('Sign History file not found\n')
return " , "
def main(self):
"""
Control the LED sign from this function
"""
try:
#display the last updated message
self.spaceSign.OpenSerial()
self.spaceSign.SendSTDMessage(self.readHistory().split(',')[1])
self.spaceSign.CloseSerial()
while True:
if not self.running.is_set():
self.exitJob()
return
if len(self.spaceSign.signBuffer) != 0:
time.sleep(2)
self.spaceSign.OpenSerial()
self.newMessage = self.spaceSign.signBuffer.pop(0)
self.spaceSign.SendSTDMessage(self.newMessage)
print("Wrote to Sign: "+str(self.newMessage))
self.spaceSign.CloseSerial()
self.writeHistory()
else:
time.sleep(5)
except KeyboardInterrupt:
self.cancel()
#wait for threads to close out
time.sleep(20)
if __name__ == "__main__":
#test handler script
controller(sys.argv[1]).main()
Basic web page to send data to textiles python script. By C-P
<form>
<input type="text" name="message">
<button type="submit" value="go">go</button>
</form>
<?php
set_error_handler("ef", E_WARNING);
function ef($errno, $errstr) {echo"+";}
if($_GET['message'])
{
$message = $_GET['message'];
$host = "127.0.0.1";
$port = 9001;
set_time_limit(0);
$sSender = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
socket_connect($sSender, $host, $port) or die("Could not connect to sign\n");
socket_write($sSender, $message, strlen ($message)) or die("Could not write output\n");
echo socket_read($sSender, 1024);
socket_close($sSender);
echo socket_strerror(socket_last_error());
}
?>
The sign now "dings" with a physical alarm bell when updated.
import serial,time,sys
s = serial.Serial('/dev/ttyUSB0', baudrate = 9600, rtscts='rtscts', xonxoff='xonxoff', timeout=1000)
time.sleep(1.5)
s.setDTR(False)
time.sleep(0.022)
s.setDTR(True)
t=sys.argv[1]
s.write(str(t)+"\n")
time.sleep((float(t))/1000)