1

我在树莓派上使用 Raspbian。我有一个 Python 脚本 (LCD.py),它使用 supervisord 控制作为服务运行的 LCD。

我希望能够在我的网页上输入一条消息并将其显示在 LCD 上。我认为这意味着我必须更改 LCD.py 脚本读取的一些变量,可能是更改模式的标志,然后使用服务器执行的另一个 Python 脚本 (CGI.py) 更改消息本身。

最好的方法是什么?还是我应该做一些完全不同的事情?我认为它与普通 CGI 类型的东西不同,因为我不能在每个页面加载时执行脚本,它需要在后台运行(用于滚动、闪烁等)

编辑:到目前为止,感谢您的帮助,今晚我回家后将发布我的 LCD 守护程序代码。

我对此有了更进一步的了解,我尝试使用 SimpleXMLRPCServer 和线程,目前这不起作用。我认为这是因为线程实际上并不同时运行。这是我正在测试的服务器代码:

    from SimpleXMLRPCServer import SimpleXMLRPCServer
    from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
    import threading
    import time

    globalMessage = "Hi, I havnt been changed!"

    # Restrict to a particular path.
    class RequestHandler(SimpleXMLRPCRequestHandler):
        rpc_paths = ('/RPC2',)

    # Create server
    server = SimpleXMLRPCServer(("localhost", 8000),
                                requestHandler=RequestHandler)
    server.register_introspection_functions()

    # Register an instance; all the methods of the instance are
    # published as XML-RPC methods (in this case, just 'div').
    class serverFunctions:
        def setMessage(self, message):
                global globalMessage
                globalMessage = message
                print(globalMessage)


    class serverThread(threading.Thread):
            def run(self):
                    server.register_instance(serverFunctions())

                    # Run the server's main loop
                    server.serve_forever()
                    print("test");

    class lcdThread(threading.Thread):
            def run(self):
                    global globalMessage
                    while(1):
                            oldMessage = globalMessage
                            if(oldMessage != globalMessage): print("Message has changed")
                            else: print ("Message has not changed")
                            print(globalMessage)
                            time.sleep(1)

    serverThread().start()
    #lcdThread().start()

和我的客户代码:

import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8000')


print s.setMessage("hello world")

如果我取消注释我的 lcdThread().start() 行,我认为它卡在 lcd while 循环中并且服务器没有响应。多处理会有什么不同吗?请您详细说明 exec() 函数,我将如何使用 exec() 更改不同脚本中的全局变量?

编辑:这是我的 LCD.py 代码,它是一个守护进程,我试图设置的消息变量大约是一半。

#!/usr/bin/python
from Adafruit_CharLCD import Adafruit_CharLCD
from subprocess import * 
from time import sleep, strftime
from datetime import datetime
from datetime import timedelta
from os import system
from os import getloadavg
from glob import glob
import RPi.GPIO as GPIO

#Variables
lcd = Adafruit_CharLCD() #Stores LCD object
cmdIP = "ip addr show eth0 | grep inet | awk '{print $2}' | cut -d/ -f1" #Current IP
cmdHD = "df -h /dev/sda1 | awk '{print $5}'" # Available hd space
cmdSD = "df -h / | awk '{print $5}'" # Available sd space
cmdRam = "free -h"
temp = 0

#Run shell command
def run_cmd(cmd):
    p = Popen(cmd, shell=True, stdout=PIPE)
    output = p.communicate()[0]
    return output

#Initalises temp device     
def initialise_temp():
    #Initialise
    system("sudo modprobe w1-gpio")
    system("sudo modprobe w1-therm")
    #Find device
    devicedir = glob("/sys/bus/w1/devices/28-*")
    device = devicedir[0]+"/w1_slave"
    return device

#Gets temp  
def get_temp(device):
    f = open (device, 'r')
    sensor = f.readlines()
    f.close()

    #parse results from the file
    crc=sensor[0].split()[-1]
    temp=float(sensor[1].split()[-1].strip('t='))
    temp_C=(temp/1000.000)
    temp_F = ( temp_C * 9.0 / 5.0 ) + 32

    #output
    return temp_C

#Gets time
def get_time():
    return datetime.now().strftime('%b %d  %H:%M:%S\n')

#Gets uptime
def get_uptime():
    with open('/proc/uptime', 'r') as f:
        seconds = float(f.readline().split()[0])
        array = str(timedelta(seconds = seconds)).split('.')
        string = array[0]
    return string

#Gets average load
def get_load():
    array = getloadavg()
    average = 0
    for i in array:
        average += i
    average = average / 3
    average = average * 100
    average = "%.f" % average
    return str(average + "%")

#def get_ram():
def get_ram():
    ram = run_cmd(cmdRam)
    strippedRam = ram.replace("\n"," ");
    splitRam = strippedRam.split(' ')
    totalRam = int(splitRam[52].rstrip("M"))
    usedRam = int(splitRam[59].rstrip("M"))
    percentage = "%.f" % ((float(usedRam) / float(totalRam)) * 100)
    return percentage + "%"

#Gets the SD usage
def get_sd():
    sd = run_cmd(cmdSD)
    strippedSD = sd.lstrip("Use%\n")
    return strippedSD

#Gets the HD usage
def get_hd():
    hd = run_cmd(cmdHD)
    strippedHD = hd.lstrip("Use%\n")
    return strippedHD

#This is the variable im trying to set  
#def get_message():
#   message = "hello"
#   return message

def scroll():
    while(1):
        lcd.scrollDisplayLeft()
        sleep(0.5)

#Message and IP - PERFECT
def screen1():
    ipaddr = run_cmd(cmdIP)
    lcd.message('Raspberry Pi\n')
    lcd.message('IP: %s' % (ipaddr))

#Uptime - tick
def screen2():
    uptime = get_uptime()
    lcd.message('Total Uptime\n') 
    lcd.message('%s' % (uptime))

#Ram and load - PERFECT
def screen3():
    ram = get_ram()
    lcd.message('Ram Used: %s\n' % (ram))
    load = get_load()
    lcd.message('Avg Load: %s' % (load))

#Temp and time - tick time
def screen4():
    time = get_time();
    lcd.message('Temp %s\n' % (temp))
    lcd.message('%s' % (time))

#HD and SD usage - PERFECT
def screen5():
    sd = get_sd()
    lcd.message('SD Used: %s\n' % (sd))
    hd = get_hd()
    lcd.message('HD Used: %s' % (hd))

#Web message    
#def screen6():
#   message = get_message()
#   lcd.message(message)

#Pause and clear
def screenPause(time):
    sleep(time)
    #In here to reduce lag
    global temp
    temp = str(get_temp(device));
    lcd.clear()
###########################################################################################################

try:
    #Initialise
    lcd.begin(16,2)
    device = initialise_temp()
    lcd.clear()

    #Main loop
    while(1):
        screen1()
        screenPause(5)
        screen2()
        screenPause(5)
        screen3()
        screenPause(5)
        screen5()
        screenPause(5)
        screen4()
        screenPause(5)

except KeyboardInterrupt:
    GPIO.cleanup()

谢谢乔

4

2 回答 2

1

如果您正在寻找一种在脚本运行时更改全局变量的方法,

exec("<varname> = <newvar> in globals()")

如果您不在评论中发布它。

编辑:也许包括任何现有代码

于 2012-12-29T10:38:21.593 回答
0

如果需要向 LCD.py 守护进程发送命令;你也可以使用http协议来做到这一点。你可以尝试像瓶子这样的东西来实现网络应用程序部分。

您可以将 Web 应用程序作为单独的守护程序运行,但无论如何您都需要在 LCD.py中实现某种形式的IPC 。

于 2012-12-29T19:48:40.283 回答