#!/usr/bin/env python3 import smbus import time import paho.mqtt.client as mqt from datetime import datetime import _thread bus = smbus.SMBus(1) mqtc = mqt.Client() access = {} # [ code : [last_access, penalty] ] bus_use = True def allowed(code): print (access) if code in access: if millis_since(access[code][0]) > 3000 + access[code][1]: access[code] = [datetime.now(), 0] return True else: access[code] = [datetime.now(), access[code][1] + 3000] return False else: access[code] = [datetime.now(), 0] return True def millis_since(start_time): dt = datetime.now() - start_time ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0 return ms def on_connect(mosq, obj, foo ,bar ): print( "Connected" ) def on_message(mosq, obj, msg): #print( "Received on topic: " + msg.topic + " Message: "+str(msg.payload) ); msgs(msg.payload, msg.topic) def on_subscribe(mosq, obj, mid, granted_qos): print("Subscribed OK") #Funktion Setze Bit in Variable / Function Set Bit in byte def set_bit(value, bit): return value | (1< 7 and i < 16: o = set_bit(o, i - 8) bus.write_byte(0x3f, 255 - o) time.sleep(speed) o = clear_bit(o, i - 8) bus.write_byte(0x3f, 255 - o) elif i < 8: o = set_bit(o, i) bus.write_byte(0x21, 255 - o) time.sleep(speed) o = clear_bit(o, i) bus.write_byte(0x21, 255 - o) bus_use = True def strobo_switch(switch_list, speed=0.5): global bus_use bus_use = False for i in switch_list: o = 0 if i > 7: o = set_bit(o, i - 8) bus.write_byte(0x3f, 255 - o) time.sleep(speed) o = clear_bit(o, i - 8) bus.write_byte(0x3f, 255 - o) else: o = set_bit(o, i) bus.write_byte(0x21, 255 - o) time.sleep(speed) o = clear_bit(o, i) bus.write_byte(0x21, 255 - o) bus_use = True services = ["strom", "licht"] state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] inputs = (0x23, 0x21) states = {0: "off", 1: "on"} commands = {"flur": 0, "baellebad": 1, "lounge-front": 2, "lounge-back": 3, "baellebad-ein": 4, "lounge-ein": 5, "cantina-ein": 6, "zentral-aus": 7, "cantina": 8, "flur-strobo": 100, "cantina-strobo": 99, "deineelternhabenneziemlichepartygefeiert": 101} i2c_input = [{0xFE: 4, 0xFD: 5, 0xFB: 8, 0xF7: 0}, {}] names = { 7: ["zentral", 0], 4: ["baellebad", 0], 5: ["lounge", 0], 6: ["cantina", 0], 0: ["flur", 1], 1: ["baellebad", 1], 2: ["lounge-front", 1], 3: ["lounge-back", 1], 8: ["cantina", 1]} power = {"zentral": 7, "baellebad": 4, "lounge": 5, "cantina": 6} light = {"flur": 0, "baellebad": 1, "lounge-front": 2, "lounge-back": 3, "cantina": 8} # foobar/aerie/lounge /licht/action # cantina /strom/status # flur # baellebad # zentral def zentral_aus(): for i in state: state[i] = 0 for k,v in names.items(): mqtc.publish("foobar/aerie/" + v[0] + "/" + services[v[1]] + "/status", "off" ) def switch_state(i, state_, speed=0.5): if state[i] != state_: # changed switch(i,speed=0.5) state[i] = state_ return state[i] def switch_toggle(i,speed=0.5): switch(i, speed=speed) # power can only be switched on, and centrally shutdown #if i in [ 4,5,6]: # state[i] = 1 # not anymore if i == 7: state[i] = 0 elif i < 16: state[i] = 0 if state[i] == 1 else 1 mqtc.publish("foobar/aerie/" + names[i][0] + "/" + services[names[i][1]] + "/status", states[state[i]]) def decode_topic(topic, state): clist = topic.split('/') if clist[3] == "strom" and clist[2] == "zentral": zentral_aus() if clist[3] == "licht" and clist[2] in light: ns = switch_state(light[clist[2]], state) mqtc.publish(topic.replace("action", "status"), states[ns], qos=0, retain=False) if clist[3] == "strom" and clist[2] in power: ns = switch_state(power[clist[2]], state) mqtc.publish(topic.replace("action", "status"), states[ns], qos=0, retain=False) def msgs(inp, topic): c = inp.decode("utf-8") l = len(c) # supporting number commands if c == "on" or c == "off": if c.find("on") >= 0: decode_topic(topic, 1) elif c.find("off") >= 0: decode_topic(topic, 0) return elif l < 3: try: msg = int(inp) switch_toggle(msg) except ValueError: return #supporting string commmands with dimming parameters else: cmds = c.split(",") if len(cmds) > 1: command = 9001 #error checking if cmds[0] in commands: command = commands[cmds[0]] else: return try: arg = int(cmds[1]) except ValueError: return #strobo if ((command == 100 or command == 99) and arg < 100): for i in range(arg): switch((100 - command) * 8, speed=0.05) time.sleep(0.06) elif command == 101 and arg < 100: for i in range(arg): strobo_switch([0, 8], speed=0.05) time.sleep(0.01) #command with parameter used for dimming else: if arg < 100 : switch(command, speed=4 * arg / 100 + 1) if state[command] == 0: state[command] = 1 mqtc.publish("foobar/aerie/" + names[command][0] + "/" + services[names[command][1]] + "/status", states[state[command]]) #single string command without parameter else: print ("One Command") if commands[c] == 7: zentral_aus() if c in commands: switch_toggle(commands[c]) return def init_mqtt(): mqtc.connect("10.42.0.244", 1883, 60) mqtc.subscribe("foobar/aerie/licht", 0) mqtc.subscribe("foobar/aerie/lounge-back/licht/action", 0) mqtc.subscribe("foobar/aerie/lounge-front/licht/action", 0) mqtc.subscribe("foobar/aerie/lounge/strom/action", 0) mqtc.subscribe("foobar/aerie/baellebad/licht/action", 0) mqtc.subscribe("foobar/aerie/baellebad/strom/action", 0) mqtc.subscribe("foobar/aerie/cantina/licht/action", 0) mqtc.subscribe("foobar/aerie/cantina/strom/action", 0) mqtc.subscribe("foobar/aerie/flur/licht/action", 0) mqtc.subscribe("foobar/aerie/strom/zentral/licht/action", 0) mqtc.on_message = on_message mqtc.on_connect = on_connect mqtc.on_subscribe = on_subscribe _thread.start_new_thread(i2c_status_thread_new, ()) mqtc.loop_start() while True: #try: # print("Err") # mqtc.loop_forever() #except: # pass time.sleep(2) init_mqtt() # vim: noai:ts=4:sw=4