2012-12-29 1 views
1

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

Répondre

1

Si vous êtes à la recherche d'un moyen de changer une variable globale tandis que le script est en cours d'exécution,

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

Si vous le faites pas poster dans les commentaires .

EDIT: Peut-être inclure tout code excisting

+0

Pourquoi ne pas simplement 'global varname; varname = valeur'? Qu'avez-vous voulu dire par 'dans globals()'? – Kos

+0

1. 'exec' est mal utilisé 2.' exec() 'n'aidera pas dans ce cas de toute façon. – jfs

+0

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

0

Si vous avez besoin d'envoyer des commandes au démon LCD.py; vous pourriez aussi bien utiliser le protocole http pour le faire. Vous pouvez essayer quelque chose comme bottle pour implémenter la partie de l'application web.

Vous pouvez exécuter l'application Web en tant que démon distinct, mais vous devez implémenter une forme de IPC dans LCD.py de toute façon. Pourquoi appeller `exec` ici?

Questions connexes