Zmiana zmiennych w trakcie działania skryptu

0

Cześć,
mam skrypt do obsługi matrycy LED WS2812b i chcę z niego zrobić zegarek. W ramach działania skryptu pojawia się parę zmiennych (np. kolor, jasność, prędkość, text), które są zdefiniowane na początku działania skryptu. Jednak chciałbym je później zmienić (np. kolor) w trakcie działania skryptu bez jego konieczności ponownego uruchamiania.

Najchętniej chciałbym to zrobić jakimś prostym zapytaniem HTTP: http://<adres_ip_kontrolera>:8080/?color=red

Czego potrzebuję? Czego szukać w Google? Moja znajomość Pythona jest dość podstawowa, jednak mam doświadczenie w programowaniu mikrokontorlerów.

Pozdrawiam
Jarek

2

Pytanie trochę mało czytelne, ale chyba wiem o co chodzi. Z tego co rozumiem to masz jeden skrypt mielący się w kółko - który steruje wyświetlaczem i chcesz zmienić jego ustawienia, ale bez ponownego odpalania/przeładowywania tego skryptu. Czyli żeby skrypt odpalany przez wejście na podany przez ciebie adres wywołał zmiane wartości zmiennych w chodzącym w kółko skrypcie od obsługi wyświetlacza.

Rzuć okiem na mmap - https://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/

Ewentualnie jeszcze wersja prostsza - trzymanie tych informacji w jakimś pliku. Skrypt w pętli sprawdza, czy zmienił się czas zapisu pliku i jeśli tak, to odczytuje go i na podstawie danych w nim zawartych zmienia ustawienia wyświetlania. Jeśli to są proste zmienne to po prostu je wrzuć do pliku, ale możesz skorzystać z modułu pickle - https://docs.python.org/3/library/pickle.html i sobie serializowac i deserializować całe obiekty do pliku.

Jednakże plik to taka lekka prowizorka, jeśli danych jest dużo albo ich sprawdzanie będzie częste, to mogą się nie zapisać do końca przed odczytem i powstanie zamieszanie. Dlatego można zamiast pliku skorzystać z sqlite i transakcji. W ten sposób zmiana danych w bazie będzie atomowa i nie mamy ryzyka, że część danych się pobierze starych, a część nowych. Jeszcze jest opcja Redis - czyli także baza, tylko trochę inna ;)

Jeszcze jest opcja memcached - tutaj pozwole sobie chamsko skopiować fragment z netu :p

sudo apt-get install memcached python-memcache

one.py

import memcache
shared = memcache.Client(['127.0.0.1:11211'], debug=0)
shared.set('Value', 'Hello')

two.py

import memcache
shared = memcache.Client(['127.0.0.1:11211'], debug=0)    
print shared.get('Value')

Poza tym mozna skorzystać z pipes - https://docs.python.org/3/library/multiprocessing.html#pipes-and-queues chociaż przyznaję się bez bicia, że nie jestem pewien, czy ten mechanizm działa w obrębie wątków jednego procesu, czy także między procesami.

1

@AnyKtokolwiek: Tak jak napisał @cerrato to mam skrypt, który definiuje zmienne i później pętle while True: , w której wykonuje się sterowanie diodami. Chodziło o to jak z zewnętrznego źródła (najlepiej zapytaniem HTTP) zmienić zmienne (takie jak kolor, jasność, opóźnienie). Finalnie użyłem memcache oraz drugiego skryptu z serwerem HTTP.

sterowanie_led.py

# ---
# STEROWANIE MATRYCY WS2812b DLA PYTHON. WRAZ ZE ZMIANĄ ZMIENNYCH
# ---

# apt-get install memcached python3-memcache -y
# pip3 install board
# pip3 install rpi_ws281x adafruit-circuitpython-neopixel
# pip3 install adafruit-circuitpython-pixel-framebuf
# python3 -m pip install --force-reinstall adafruit-blinka
# pip3 install adafruit-circuitpython-framebuf
# pip3 install adafruit-blinka
# pip3 install rpi_ws281x
# pip3 install adafruit-circuitpython-neopixel



import memcache
import board
import neopixel
import time
import sys, getopt
from adafruit_pixel_framebuf import PixelFramebuffer, VERTICAL
from datetime import datetime

# ---
# DEFINICJA MATRYCY WS2812b
# ---

pixel_pin = board.D18
pixel_width = 32
pixel_height = 8

pixels = neopixel.NeoPixel(
    pixel_pin,
    pixel_width * pixel_height,
    brightness=0.1,
    auto_write=False,
)

pixel_framebuf = PixelFramebuffer(
    pixels, pixel_width, pixel_height, orientation=VERTICAL, rotation=2
)

# ---
# ZMIENNE DO STEROWANIA WYŚWIETLANIEM TEKSTU NA MATRYCY WS2812b
# ---

xpos = 1
delta = -1

# ---
# DOMYŚLNE WARTOŚCI ZMIENNYCH
# ---

color = 0x1a0000
delay = 150/1000
time_period = 60
time_visible = 0
move = 0

shared = memcache.Client(['127.0.0.1:11211'], debug=0)    

arguments = sys.argv
for arg in arguments:
    
    if arg.startswith('-c'):
        color = arg.split('=')[1]
        color = int(color, 16)
    elif arg.startswith('-d'):
        delay = arg.split('=')[1]
        delay = int(delay)/1000
    elif arg.startswith('-tp'):
        time_period = arg.split('=')[1]
        time_period = int(time_period)
    elif arg.startswith('-tv'):
        time_visible = arg.split('=')[1]
        time_visible = int(time_visible)
    elif arg.startswith('-m'):
        print (arg)
        move = arg.split('=')[1]
        move = int(move)
    

shared.set('color',color)
shared.set ('delay',delay)
shared.set ('time_period',time_period)
shared.set ('time_visible',time_visible)
shared.set ('move',move)

print ('Lista zmiennych')
print ('Color',color)
print ('Delay',delay)
print ('Time_period',time_period)
print ('Time_visible',time_visible)
print ('Move',move)

while True:

    now = datetime.now()
    epochtime = int(time.time())

    if (epochtime%time_period < time_visible):
        text = shared.get('text')
        text = str(text)
        text = text[2:-1]
        text = text.replace("_"," ")
        print(text)
        
        if len(text) > 4:
            move = 1
        else:
            move = 0
        
    else:
        text = now.strftime("%H:%M")
        move = 0
        xpos = 1

    minxpos = int((len(text)*5)*0.9)

    pixel_framebuf.fill(0x000000)
    pixel_framebuf.text(text, xpos, 0, color)
    pixel_framebuf.display()

    print (now.strftime("%H:%M:%S"),",",int(time.time()),",",xpos,",",delta,",",epochtime%time_period)

    time.sleep(delay)

    if move == 1:
        xpos = xpos + delta
    if (abs(xpos) > abs(minxpos)):
        delta = delta * -1
    
    color = shared.get('color')

serwer_www.py

#!/usr/bin/env python

import time

import memcache
from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse, json

shared = memcache.Client(['127.0.0.1:11211'], debug=0)


class GetHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        parsed_path = urlparse.urlparse(self.path)
        message = '\n'.join([
            'CLIENT VALUES:',
            'client_address=%s (%s)' % (self.client_address,
                self.address_string()),
            'command=%s' % self.command,
            'path=%s' % self.path,
            'real path=%s' % parsed_path.path,
            'query=%s' % parsed_path.query,
            'request_version=%s' % self.request_version,
            '',
            'SERVER VALUES:',
            'server_version=%s' % self.server_version,
            'sys_version=%s' % self.sys_version,
            'protocol_version=%s' % self.protocol_version,
            '',
            ])
        self.send_response(200)
        self.end_headers()
        self.wfile.write(message)
        
        URLrequestpath=self.path
        if URLrequestpath.startswith('/pdp/color='):
            color = URLrequestpath.split('=')[1]
            color = int(color, 16)
            shared.set('color',color)
        elif URLrequestpath.startswith('/pdp/text='):
            text = URLrequestpath.split('=')[1]
            shared.set('text',text)
            print(text)
        
        return

    def do_POST(self):
        content_len = int(self.headers.getheader('content-length'))
        post_body = self.rfile.read(content_len)
        self.send_response(200)
        self.end_headers()

        data = json.loads(post_body)

        self.wfile.write(data['foo'])
        return

if __name__ == '__main__':
    from BaseHTTPServer import HTTPServer
    server = HTTPServer(('localhost', 8080), GetHandler)
    print ('Starting server at http://localhost:8080')
    server.serve_forever()

1 użytkowników online, w tym zalogowanych: 0, gości: 1