Initial Commit
						commit
						cf82fddbcb
					
				@ -0,0 +1,264 @@
 | 
			
		||||
#!/usr/bin/python3
 | 
			
		||||
 | 
			
		||||
from datetime import datetime
 | 
			
		||||
from datetime import timedelta
 | 
			
		||||
import sys
 | 
			
		||||
import time
 | 
			
		||||
import shlex
 | 
			
		||||
import subprocess
 | 
			
		||||
import toml
 | 
			
		||||
import os
 | 
			
		||||
import threading
 | 
			
		||||
import gpiozero
 | 
			
		||||
import signal
 | 
			
		||||
sys.path.append("/home/pi/rpi_ws281x")
 | 
			
		||||
from neopixel import *
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
# LED strip configuration:
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
LED_COUNT = 60      # Number of LED pixels.
 | 
			
		||||
LED_PIN = 18      # GPIO pin connected to the pixels (must support PWM!).
 | 
			
		||||
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
 | 
			
		||||
LED_DMA = 5       # DMA channel to use for generating signal (try 5)
 | 
			
		||||
LED_INVERT = False   # True to invert the signal (when using NPN transistor level shift)
 | 
			
		||||
LED_BRIGHTNESS = 4     # Set to 0 for darkest and 255 for brightest
 | 
			
		||||
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53
 | 
			
		||||
LED_STRIP = ws.WS2811_STRIP_GRB   # Strip type and colour ordering
 | 
			
		||||
 | 
			
		||||
standard_helligkeit = LED_BRIGHTNESS
 | 
			
		||||
 | 
			
		||||
# Zahl stellt den Wert in Minuten dar, wie lange kein Gerät erreichbar sein darf dass die Uhr "abgeschalten" wird
 | 
			
		||||
ABSCHALTWERT = 4
 | 
			
		||||
 | 
			
		||||
# LED Mapping
 | 
			
		||||
std0 = [0, 1, 59]
 | 
			
		||||
std1 = [4, 5, 6]
 | 
			
		||||
std2 = [9, 10, 11]
 | 
			
		||||
std3 = [14, 15, 16]
 | 
			
		||||
std4 = [19, 20, 21]
 | 
			
		||||
std5 = [24, 25, 26]
 | 
			
		||||
std6 = [29, 30, 31]
 | 
			
		||||
std7 = [34, 35, 36]
 | 
			
		||||
std8 = [39, 40, 41]
 | 
			
		||||
std9 = [44, 45, 46]
 | 
			
		||||
std10 = [49, 50, 51]
 | 
			
		||||
std11 = [54, 55, 56]
 | 
			
		||||
stdliste = [std0, std1, std2, std3, std4, std5, std6, std7, std8, std9, std10, std11]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
# GPIO:
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
I_MODE_TASTER = 3
 | 
			
		||||
I_PLUS_TASTER = 4
 | 
			
		||||
I_MINUS_TASTER = 14
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
# Funktionen
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
# Farbkonfiguration
 | 
			
		||||
def rgb_standard():
 | 
			
		||||
    rgb_leer = [0, 0, 0]
 | 
			
		||||
    rgb_s = [0, 180, 0]
 | 
			
		||||
    rgb_min = [32, 178, 170]
 | 
			
		||||
    rgb_std = [255, 0, 255]
 | 
			
		||||
    rgbconf = {"rgb_leer": rgb_leer, "rgb_s": rgb_s, "rgb_min": rgb_min, "rgb_std": rgb_std}
 | 
			
		||||
    return rgbconf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def alle_led(r, g, b, strip):
 | 
			
		||||
    for pos in range(strip.numPixels()):
 | 
			
		||||
        strip.setPixelColorRGB(pos, r, g, b)
 | 
			
		||||
        strip.show()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def led_calc(zeit, stdliste, rgbdict, led_gesetzt, strip):
 | 
			
		||||
    if zeit.hour > 11:
 | 
			
		||||
        index = zeit.hour - 12
 | 
			
		||||
    else:
 | 
			
		||||
        index = zeit.hour
 | 
			
		||||
    hour = stdliste[index]
 | 
			
		||||
    minute = zeit.minute
 | 
			
		||||
    second = zeit.second
 | 
			
		||||
 | 
			
		||||
    # Schnittfarben berechnen falls "Zeiger" übereinander liegen
 | 
			
		||||
    # Stunde mit Minute vergleichen
 | 
			
		||||
 | 
			
		||||
    if bool(set(hour) & {minute}):
 | 
			
		||||
        for counter in range(0, 3):
 | 
			
		||||
            rgbdict["rgb_min"][counter] = int((rgbdict["rgb_std"][counter] + rgbdict["rgb_min"][counter]) / 2)
 | 
			
		||||
    # Stunde mit Sekunde vergleichen
 | 
			
		||||
    if set(hour) & {second}:
 | 
			
		||||
        for counter in range(0, 3):
 | 
			
		||||
            rgbdict["rgb_s"][counter] = int((rgbdict["rgb_std"][counter] + rgbdict["rgb_s"][counter]) / 2)
 | 
			
		||||
    # Minute mit Sekunde vergleichen
 | 
			
		||||
    if {minute} & {second}:
 | 
			
		||||
        for counter in range(0, 3):
 | 
			
		||||
            rgbdict["rgb_s"][counter] = int((rgbdict["rgb_min"][counter] + rgbdict["rgb_s"][counter]) / 2)
 | 
			
		||||
    led_gesetzt = led_setzen(hour, minute, second, rgbdict, led_gesetzt, strip)
 | 
			
		||||
    return zeit.second, led_gesetzt
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def led_setzen(hour, minute, second, rgbdict, led_gesetzt, strip):
 | 
			
		||||
    if not isinstance(led_gesetzt, list):
 | 
			
		||||
        led_gesetzt = [led_gesetzt]
 | 
			
		||||
    # Stunden setzen
 | 
			
		||||
    for stunde in hour:
 | 
			
		||||
        strip.setPixelColorRGB(stunde, rgbdict["rgb_std"][0], rgbdict["rgb_std"][1], rgbdict["rgb_std"][2])
 | 
			
		||||
        # print("Stunden setzen")
 | 
			
		||||
        # print(stunde, rgbdict["rgb_std"][0], rgbdict["rgb_std"][1], rgbdict["rgb_std"][2])
 | 
			
		||||
    # Minute setzen
 | 
			
		||||
    strip.setPixelColorRGB(minute, rgbdict["rgb_min"][0], rgbdict["rgb_min"][1], rgbdict["rgb_min"][2])
 | 
			
		||||
    # print("Minute setzen")
 | 
			
		||||
    # print(minute, rgbdict["rgb_min"][0], rgbdict["rgb_min"][1], rgbdict["rgb_min"][2])
 | 
			
		||||
    # Sekunde setzen
 | 
			
		||||
    strip.setPixelColorRGB(second, rgbdict["rgb_s"][0], rgbdict["rgb_s"][1], rgbdict["rgb_s"][2])
 | 
			
		||||
    # print("Sekunde setzen")
 | 
			
		||||
    # print(second, rgbdict["rgb_s"][0], rgbdict["rgb_s"][1], rgbdict["rgb_s"][2])
 | 
			
		||||
    # Neue Leere LED berechnen
 | 
			
		||||
    led_gesetzt_neu = set(hour) | {minute} | {second}
 | 
			
		||||
    leerliste = list(set(led_gesetzt) - led_gesetzt_neu)
 | 
			
		||||
    for leer in leerliste:
 | 
			
		||||
        strip.setPixelColorRGB(leer, rgbdict["rgb_leer"][0], rgbdict["rgb_leer"][1], rgbdict["rgb_leer"][2]),
 | 
			
		||||
        # print("Leer setzen")
 | 
			
		||||
        # print(leer, rgbdict["rgb_leer"][0], rgbdict["rgb_leer"][1], rgbdict["rgb_leer"][2])
 | 
			
		||||
    strip.show()
 | 
			
		||||
    return list(led_gesetzt_neu)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def taster_callback(button):
 | 
			
		||||
    start = datetime.now()
 | 
			
		||||
    ende = datetime.now()
 | 
			
		||||
    while button.is_pressed:
 | 
			
		||||
        ende = datetime.now()
 | 
			
		||||
    dauer = ende - start
 | 
			
		||||
    dauer = dauer + timedelta(seconds=0.3)
 | 
			
		||||
    pin_num = check_taster(button)
 | 
			
		||||
 | 
			
		||||
    if pin_num == I_MODE_TASTER:
 | 
			
		||||
        handler_mode_taster(dauer)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def check_taster(button):
 | 
			
		||||
    pin_num = ""
 | 
			
		||||
    for i in str(button.pin):
 | 
			
		||||
        if i.isdigit():
 | 
			
		||||
            pin_num = pin_num + str(i)
 | 
			
		||||
    pin_num = int(pin_num)
 | 
			
		||||
    return pin_num
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def handler_mode_taster(dauer):
 | 
			
		||||
    if dauer > timedelta(seconds=3):
 | 
			
		||||
        shutdown()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def shutdown():
 | 
			
		||||
    cmd = "sudo shutdown now"
 | 
			
		||||
    cmd = shlex.split(cmd)
 | 
			
		||||
    subprocess.call(cmd)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
# Threads
 | 
			
		||||
# # # # # # # # # #
 | 
			
		||||
def check_anwesenheit(strip):
 | 
			
		||||
    """Funktion, welche als eigener Thread laeuft, um selbststaendig in einem gewissenen Intervall
 | 
			
		||||
    alle Geraete in der Toml Liste zu pingen
 | 
			
		||||
    arg: Objekt des neopixel LED Ringes
 | 
			
		||||
    toml File: status "anwesend", ist kein Geraet von "anwesend" oder "dimmen" erreichbar, LED Helligkeit auf 0
 | 
			
		||||
    sobald eine Adresse von status "dimmen" erreichbar ist, wird die Helligkeit verringert"""
 | 
			
		||||
    def ping_wlan(ip):
 | 
			
		||||
        """pingt die IP 2x an
 | 
			
		||||
        return (0 | !0) 0 wenn erreichbar"""
 | 
			
		||||
        befehl = "ping -c2 -W1 {}".format(ip)
 | 
			
		||||
        cmd = shlex.split(befehl)
 | 
			
		||||
        return subprocess.call(cmd)
 | 
			
		||||
    
 | 
			
		||||
    def ping_bt(bt):
 | 
			
		||||
        """pingt die IP 2x an
 | 
			
		||||
        return (0 | !0) 0 wenn erreichbar"""
 | 
			
		||||
        befehl = "sudo /usr/bin/l2ping -c1 -t1 {}".format(bt)
 | 
			
		||||
        cmd = shlex.split(befehl)
 | 
			
		||||
        return subprocess.call(cmd)    
 | 
			
		||||
    
 | 
			
		||||
    # Tomlfile mit den IP Adressen einlesen
 | 
			
		||||
    pfad = os.path.abspath(os.path.dirname(__file__))
 | 
			
		||||
    configfile = os.path.join(pfad, "bt_wlan.toml")
 | 
			
		||||
    with open(configfile) as conffile:
 | 
			
		||||
        wlanliste = toml.loads(conffile.read())   
 | 
			
		||||
    status_anwesend_liste = [] 
 | 
			
		||||
    delta = timedelta(seconds=301)
 | 
			
		||||
    last = datetime.now()
 | 
			
		||||
    status = {}
 | 
			
		||||
    global standard_helligkeit
 | 
			
		||||
    while True:
 | 
			
		||||
        now = datetime.now()
 | 
			
		||||
        # Status der IP Adressen ermitteln
 | 
			
		||||
        if delta.seconds > 300:
 | 
			
		||||
            for key_status in wlanliste.keys():
 | 
			
		||||
                for key_funkart in wlanliste[key_status].keys():
 | 
			
		||||
                    for ip in wlanliste[key_status][key_funkart]:
 | 
			
		||||
                        if key_funkart == "wlan":
 | 
			
		||||
                            status_return = ping_wlan(ip)
 | 
			
		||||
                        elif key_funkart == "bt":
 | 
			
		||||
                            status_return = ping_bt(ip)
 | 
			
		||||
                        else:
 | 
			
		||||
                            status_return = False
 | 
			
		||||
                        if not status_return:
 | 
			
		||||
                            status[key_status] = True
 | 
			
		||||
                            break
 | 
			
		||||
                        else:
 | 
			
		||||
                            status[key_status] = False
 | 
			
		||||
            if status["anwesend"]:
 | 
			
		||||
                status_anwesend_liste = []  # Geraet von anwesend erreichbar
 | 
			
		||||
                helligkeit = standard_helligkeit
 | 
			
		||||
            elif not status["anwesend"] and not status["dimmen"]:  # Wenn kein Geraet erreichbar ist
 | 
			
		||||
                if len(status_anwesend_liste) < ABSCHALTWERT + 1:
 | 
			
		||||
                    status_anwesend_liste.append(status["anwesend"])
 | 
			
		||||
                print("Nichts los daheim die ", len(status_anwesend_liste), ".")
 | 
			
		||||
                if len(status_anwesend_liste) > ABSCHALTWERT: 
 | 
			
		||||
                    helligkeit = 0  
 | 
			
		||||
            if status["dimmen"]:
 | 
			
		||||
                helligkeit = standard_helligkeit * 0.5
 | 
			
		||||
            if now.hour < 5 and not status["dimmen"]:
 | 
			
		||||
                helligkeit = 0
 | 
			
		||||
            strip.setBrightness(int(helligkeit))
 | 
			
		||||
            last = datetime.now()
 | 
			
		||||
        delta = now - last
 | 
			
		||||
        time.sleep(30)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main():
 | 
			
		||||
    mode_taster = gpiozero.Button(I_MODE_TASTER, hold_time=0.3)
 | 
			
		||||
    mode_taster.when_pressed = taster_callback
 | 
			
		||||
 | 
			
		||||
    lastsecond = None
 | 
			
		||||
    led_gesetzt = 0
 | 
			
		||||
    rgbconf = rgb_standard()
 | 
			
		||||
    strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS,
 | 
			
		||||
                              LED_CHANNEL, LED_STRIP)
 | 
			
		||||
    strip.begin()
 | 
			
		||||
    strip.setBrightness(255)
 | 
			
		||||
    thread_check_wlan = threading.Thread(target=check_anwesenheit, args=(strip,))
 | 
			
		||||
    thread_check_wlan.start()
 | 
			
		||||
    alle_led(rgbconf["rgb_leer"][0], rgbconf["rgb_leer"][1], rgbconf["rgb_leer"][2], strip)
 | 
			
		||||
    while True:
 | 
			
		||||
        try:
 | 
			
		||||
            rgbconf = rgb_standard()
 | 
			
		||||
            now = datetime.now()
 | 
			
		||||
            if lastsecond != now.second:
 | 
			
		||||
                lastsecond, led_gesetzt = led_calc(now, stdliste, rgbconf, led_gesetzt, strip)
 | 
			
		||||
            time.sleep(0.2)
 | 
			
		||||
        except KeyboardInterrupt:
 | 
			
		||||
            print("KeyboardInterrupt")
 | 
			
		||||
            strip.setBrightness(0)
 | 
			
		||||
            alle_led(0, 0, 0, strip)
 | 
			
		||||
            sys.exit()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    main()
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue