J'utilise Raspbian sur un Raspberry Pi. J'ai un script Python (LCD.py) qui contrôle un LCD fonctionnant comme un service en utilisant supervord.Comment modifier une variable dans un script/service Python en cours d'exécution à partir d'une page Web?
J'aimerais pouvoir entrer un message sur ma page Web et l'afficher sur l'écran LCD. Je pense que cela signifie que je devrais changer certaines variables que mon script LCD.py lit, probablement un drapeau pour changer de mode, puis le message lui-même en utilisant un autre script Python (CGI.py) exécuté par mon serveur.
Quelle est la meilleure façon de le faire? Ou devrais-je faire quelque chose de complètement différent? Je pense qu'il est différent des choses normales de type CGI car je ne peux pas avoir un script en cours d'exécution sur chaque chargement de page, il doit fonctionner en arrière-plan (pour défilement, clignotant etc.) , Je posterai mon code daemon LCD ce soir quand je rentre à la maison.
Je suis allé un peu plus loin avec ceci, j'ai essayé d'utiliser SimpleXMLRPCServer et les threads, actuellement cela ne marche pas. Je pense que c'est parce que les threads ne fonctionnent pas simultanément. Ceci est mon code serveur je testais avec:
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()
et mon code client.
import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:8000')
print s.setMessage("hello world")
Si je un commentaire mon lcdThread() ligne start() Je pense qu'il est coincé dans la lcd while loop et le serveur ne répond pas. Multiprocessing ferait-il une différence? Pourriez-vous développer la fonction exec(), comment utiliser exec() pour changer une variable globale dans un script différent?
EDIT: Voici mon code LCD.py qui est un démon, la variable de message que j'essaie de définir est à peu près à mi-chemin.
#!/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()
Merci Joe
Pourquoi ne pas simplement 'global varname; varname = valeur'? Qu'avez-vous voulu dire par 'dans globals()'? – Kos
1. 'exec' est mal utilisé 2.' exec() 'n'aidera pas dans ce cas de toute façon. – jfs
Kos, en faisant 'global varname; varname = valeur' vous créez une copie locale de la variable et la changez, toutes les variables globales sont stockées dans globals() – MichaelvdNet