title: How to change a variable in a running Python script/service from a web page?
body: <p>I am using Raspbian on a Raspberry Pi. I have a Python script (LCD.py) that controls an LCD running as a service using supervisord.</p>
  
  <p>I would like to able to enter a message on my web page and have it displayed on the LCD. I think this means I would have to change some variables that my LCD.py script reads, probably a flag to change mode and then the message itself using another Python script (CGI.py) executed by my server.</p>
  
  <p>What's the best way to do this? Or should I be doing something completely different? I think it is different from normal CGI type stuff as I cannot have a script being executed on each page load, it needs to run in the background (for scrolling, flashing etc)</p>
  
  <p>EDIT:
  Thanks for your help so far, I'll post my LCD daemon code tonight when i get home.</p>
  
  <p>I have got a little further with this, I tried to use SimpleXMLRPCServer and threads, currently this dosn't work. I think its because threads don't actually run concurrently. This is my server code i was testing with:</p>
  
  <pre><code>    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()
  </code></pre>
  
  <p>and my client code:</p>
  
  <pre><code>import xmlrpclib
  
  s = xmlrpclib.ServerProxy('http://localhost:8000')
  
  
  print s.setMessage("hello world")
  </code></pre>
  
  <p>If I un comment my lcdThread().start() line i think it is getting stuck in the lcd while loop and the server is not responding. Would multiProcessing make any difference?
  Please could you elaborate on the exec() function, how would i use exec() to change a global variable in a different script?</p>
  
  <p>EDIT: Here is my LCD.py code that is a daemon, the message variable im trying to set is about half way down.</p>
  
  <pre><code>#!/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()
  </code></pre>
  
  <p>Thanks
  Joe</p>