Set qos=2, adapted to new fluffyd version

This commit is contained in:
Shy 2017-04-06 16:33:32 +02:00
parent 66fa06c11a
commit e64c157421

237
c4ctrl.py
View file

@ -1,15 +1,24 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# #
# c4ctrl: Command line client for AutoC4 # c4ctrl: Command line client for AutoC4
#
# Author: Shy
"""
This is a command line client for Autoc4, the home automation system of the C4.
Some parts of it **may** be useful as python module for simple tasks.
"""
import sys import sys
class C4Interface(): class C4Interface():
"""Interaction with the C4 home automation system.""" """ Interaction with the C4 home automation system. """
port = 1883 port = 1883
broker = "autoc4.labor.koeln.ccc.de" broker = "autoc4.labor.koeln.ccc.de"
qos = 0 qos = 2
retain = True retain = True
debug = False debug = False
@ -18,7 +27,10 @@ class C4Interface():
if topic: self.topic = topic if topic: self.topic = topic
def push(self, cmd, topic=None, retain=None): def push(self, cmd, topic=None, retain=None):
"""Send cmd to topic via the MQTT broker.""" """ Send a message to the MQTT broker.
cmd may a byte encoded payload or a list of byte encoded
payloads. """
from paho.mqtt import publish from paho.mqtt import publish
# Overwrite defaults # Overwrite defaults
@ -60,7 +72,9 @@ class C4Interface():
port=self.port) port=self.port)
def pull(self, topic=[]): def pull(self, topic=[]):
"""Return current state of topic.""" """ Return the state of a topic.
topic may be a list of topics or a single topic given as string. """
from paho.mqtt import subscribe from paho.mqtt import subscribe
topic = topic or self.topic topic = topic or self.topic
# <topic> must be a list # <topic> must be a list
@ -78,7 +92,7 @@ class C4Interface():
port=self.port) port=self.port)
def status(self): def status(self):
"""Print current status (open or closed) of C4.""" """ Returns current status (string "open" or "closed") of the club. """
st = self.pull("club/status") st = self.pull("club/status")
# Produce fake result to prevent errors if in debug mode # Produce fake result to prevent errors if in debug mode
@ -88,9 +102,9 @@ class C4Interface():
st.payload = b'\x00' st.payload = b'\x00'
if st.payload == b'\x01': if st.payload == b'\x01':
print("Club is open") return "open"
else: else:
print("Club is closed") return "closed"
def open_gate(self): def open_gate(self):
"""Open the gate.""" """Open the gate."""
@ -106,7 +120,7 @@ class C4Interface():
class Dmx: class Dmx:
"""Abstraction of the 3 channel LED cans in the club.""" """ Abstraction of the 3 channel LED cans in the club. """
template = "000000" template = "000000"
@ -115,13 +129,10 @@ class Dmx:
self.set_color(color or self.template) self.set_color(color or self.template)
self.is_master = topic.rfind("/master") == len(topic)-7 # 7 = len("/master") self.is_master = topic.rfind("/master") == len(topic)-7 # 7 = len("/master")
def __repr__(self):
return "<Dmx '{}: {}'>".format(self.topic, self.color)
def _pad_color(self, color): def _pad_color(self, color):
"""Merge hex color value into hex template. """ Merge hex color value into hex template.
Expand 4 bit hex code notation (eg. #f0f) and pad with template.""" Expand 4 bit hex code notation (eg. #f0f) and pad with template. """
if len(color) > len(self.template): if len(color) > len(self.template):
# Silently truncate # Silently truncate
return color[:len(self.template)] return color[:len(self.template)]
@ -142,9 +153,9 @@ class Dmx:
return color return color
def set_color(self, color): def set_color(self, color):
"""Set color (hex) for this instance. """ Set color (hex) for this instance.
The color is then available via its color variable.""" The color is then available via its color variable. """
color = self._pad_color(color) color = self._pad_color(color)
self.color = color self.color = color
@ -152,25 +163,19 @@ class Dmx:
class Dmx4(Dmx): class Dmx4(Dmx):
"""Abstraction of the 4 channel LED cans in the club.""" """ Abstraction of the 4 channel LED cans in the club. """
template = "000000ff" template = "000000ff"
def __repr__(self):
return "<Dmx4 '{}: {}'>".format(self.topic, self.color)
class Dmx7(Dmx): class Dmx7(Dmx):
"""Abstraction of the 7 channel LED cans in the club.""" """ Abstraction of the 7 channel LED cans in the club. """
template = "000000000000ff" template = "000000000000ff"
def __repr__(self):
return "<Dmx7 '{}: {}'>".format(self.topic, self.color)
class C4Room: class C4Room:
"""Base class for club rooms.""" """ Methods of rooms in the club. """
def __init__(self): def __init__(self):
self.c4 = C4Interface() self.c4 = C4Interface()
@ -205,7 +210,8 @@ class C4Room:
return userinput return userinput
def light_switch(self, userinput=""): def light_switch(self, userinput=""):
"""Switch lamps in this rooms on and off.""" """ Switch lamps in a room on or off. """
if not userinput: if not userinput:
userinput = self._interactive_light_switch() userinput = self._interactive_light_switch()
if userinput == "": return if userinput == "": return
@ -237,40 +243,42 @@ class C4Room:
return self.c4.push(cmd) return self.c4.push(cmd)
def set_colorscheme(self, colorscheme, magic): def set_colorscheme(self, colorscheme, no_magic):
"""Apply colorscheme to the LED Cans in this room.""" """ Apply colorscheme to the LED Cans in this room. """
cmd = [] cmd = []
for light in self.lights: for light in self.lights:
if colorscheme.color_for(light.topic): if colorscheme.color_for(light.topic):
if magic != "none" and magic != '0':
# Send color to ghost instead of the "real" light
mode_id, error = Fluffy().mode_id(magic)
if error:
print("Warning: unknown mode \"{}\". Using default.".format(
magic), file=sys.stderr)
# Update internal state of this Dmx object, so we can query
# <object>.payload later
light.set_color(colorscheme.color_for(light.topic)) light.set_color(colorscheme.color_for(light.topic))
cmd.append({
"topic" : Fluffy().ghostly_topic(light.topic), if no_magic:
"payload" : Fluffy().ghostly_payload(light.payload, mode_id) # Send data to the real lanterns, not fluffyd.
})
else:
light.set_color(colorscheme.color_for(light.topic))
cmd.append({ cmd.append({
"topic" : light.topic, "topic" : light.topic,
"payload" : light.payload "payload" : light.payload
}) })
else:
# Send color to ghost instead of the "real" light
# Generate the ghost topic for topic
ghost = "ghosts" + light.topic[light.topic.find('/'):]
cmd.append({
"topic" : ghost,
"payload" : light.payload
})
if cmd == []: return if cmd == []: return
if magic: # Do not retain "magic" messages if no_magic:
return self.c4.push(cmd, retain=(not magic))
else:
return self.c4.push(cmd) return self.c4.push(cmd)
else: # Do not retain "magic" messages
return self.c4.push(cmd, retain=False)
class Wohnzimmer(C4Room): class Wohnzimmer(C4Room):
"""The Wohnzimmer.""" """ Description of the Wohnzimmer. """
name = "Wohnzimmer" name = "Wohnzimmer"
switches = ( switches = (
@ -295,7 +303,7 @@ class Wohnzimmer(C4Room):
class Plenarsaal(C4Room): class Plenarsaal(C4Room):
"""The Plenarsaal.""" """ Description of the Plenarsaal. """
name = "Plenarsaal" name = "Plenarsaal"
switches = ( switches = (
@ -318,7 +326,7 @@ class Plenarsaal(C4Room):
class Fnordcenter(C4Room): class Fnordcenter(C4Room):
"""The Fnordcenter.""" """ Description of the Fnordcenter. """
name = "Fnordcenter" name = "Fnordcenter"
switches = ( switches = (
@ -336,7 +344,7 @@ class Fnordcenter(C4Room):
class Keller(C4Room): class Keller(C4Room):
"""The Keller.""" """ Description of the Keller. """
name = "Keller" name = "Keller"
switches = ( switches = (
@ -349,7 +357,7 @@ class Keller(C4Room):
class Kitchenlight: class Kitchenlight:
"""The Kitchenlight.""" """ The Kitchenlight. """
_END = "little" # Endianess _END = "little" # Endianess
_available_modes = """ _available_modes = """
@ -374,7 +382,7 @@ class Kitchenlight:
self.autopower = autopower # Power on on every mode change? self.autopower = autopower # Power on on every mode change?
def _switch(self, data, poweron=False, poweroff=False): def _switch(self, data, poweron=False, poweroff=False):
"""Send commands via a C4Interface to the MQTT broker.""" """ Send commands via a C4Interface to the MQTT broker. """
if self.autopower or poweron or poweroff: if self.autopower or poweron or poweroff:
c4 = C4Interface(self.topic) c4 = C4Interface(self.topic)
cmd = [] cmd = []
@ -384,11 +392,11 @@ class Kitchenlight:
if poweroff: if poweroff:
cmd.append({ cmd.append({
"topic" : self.powertopic, "topic" : self.powertopic,
"payload" : bytearray((0,))}) "payload" : b'\x00'})
elif self.autopower or poweron: elif self.autopower or poweron:
cmd.append({ cmd.append({
"topic" : self.powertopic, "topic" : self.powertopic,
"payload" : bytearray((1,))}) "payload" : b'\x01'})
c4.push(cmd) c4.push(cmd)
else: else:
c4 = C4Interface(self.topic) c4 = C4Interface(self.topic)
@ -421,13 +429,13 @@ class Kitchenlight:
return False return False
def empty(self): def empty(self):
"""Set to mode "empty" and turn off Kitchenlight.""" """ Set to mode "empty" and turn off Kitchenlight. """
# Screen 0 # Screen 0
d = int(0).to_bytes(4, self._END) d = int(0).to_bytes(4, self._END)
self._switch(d, poweroff=True) self._switch(d, poweroff=True)
def checker(self, delay=500, colA="0000ff", colB="00ff00"): def checker(self, delay=500, colA="0000ff", colB="00ff00"):
"""Set to mode "checker".""" """ Set to mode "checker". """
# Kind of a hack: lets treat the two colors as DMX lights # Kind of a hack: lets treat the two colors as DMX lights
ca = Dmx("checker/a", colA.lstrip('#')) ca = Dmx("checker/a", colA.lstrip('#'))
cb = Dmx("checker/b", colB.lstrip('#')) cb = Dmx("checker/b", colB.lstrip('#'))
@ -448,7 +456,7 @@ class Kitchenlight:
self._switch(d) self._switch(d)
def matrix(self, lines=8): def matrix(self, lines=8):
"""Set to mode "matrix".""" """ Set to mode "matrix". """
if int(lines) > 31: lines = 31 # Maximal line count if int(lines) > 31: lines = 31 # Maximal line count
d = bytearray(8) d = bytearray(8)
v = memoryview(d) v = memoryview(d)
@ -458,7 +466,7 @@ class Kitchenlight:
self._switch(d) self._switch(d)
def moodlight(self, mode=1): def moodlight(self, mode=1):
"""Set to mode "moodlight".""" """ Set to mode "moodlight". """
if mode == 1: # Mode "Colorwheel" if mode == 1: # Mode "Colorwheel"
d = bytearray(19) d = bytearray(19)
v = memoryview(d) v = memoryview(d)
@ -490,7 +498,7 @@ class Kitchenlight:
self._switch(d) self._switch(d)
def openchaos(self, delay=1000): def openchaos(self, delay=1000):
"""Set to mode "openchaos".""" """ Set to mode "openchaos". """
d = bytearray(8) d = bytearray(8)
v = memoryview(d) v = memoryview(d)
# Screen 4 # Screen 4
@ -499,13 +507,13 @@ class Kitchenlight:
self._switch(d) self._switch(d)
def pacman(self): def pacman(self):
"""Set to mode "pacman".""" """ Set to mode "pacman". """
# Screen 5 # Screen 5
d = int(5).to_bytes(4, self._END) d = int(5).to_bytes(4, self._END)
self._switch(d) self._switch(d)
def sine(self): def sine(self):
"""Set to mode "sine".""" """ Set to mode "sine". """
# Screen 6 # Screen 6
d = int(6).to_bytes(4, self._END) d = int(6).to_bytes(4, self._END)
self._switch(d) self._switch(d)
@ -514,7 +522,7 @@ class Kitchenlight:
# the Kitchenlight. Evil strobo! # the Kitchenlight. Evil strobo!
def text(self, text="Hello World", delay=250): def text(self, text="Hello World", delay=250):
"""Set to mode "text".""" """ Set to mode "text". """
text = text.encode("ascii", "ignore") text = text.encode("ascii", "ignore")
if len(text) > 256: # Maximum text length if len(text) > 256: # Maximum text length
print("Warning: text length must not exceed 256 characters!", file=sys.stderr) print("Warning: text length must not exceed 256 characters!", file=sys.stderr)
@ -529,22 +537,23 @@ class Kitchenlight:
self._switch(d) self._switch(d)
def flood(self): def flood(self):
"""Set to mode "flood".""" """ Set to mode "flood". """
# Screen 9 # Screen 9
d = int(9).to_bytes(4, self._END) d = int(9).to_bytes(4, self._END)
self._switch(d) self._switch(d)
def clock(self): def clock(self):
"""Set to mode "clock".""" """ Set to mode "clock". """
# Screen 11 # Screen 11
d = int(11).to_bytes(4, self._END) d = int(11).to_bytes(4, self._END)
self._switch(d) self._switch(d)
class ColorScheme: class ColorScheme:
"""Abstraction of a colorscheme.""" """ Abstraction of a colorscheme. """
# Names of virtual presets # Names of virtual presets. These are always listed as available and the
# user may not save presets under this name.
_virtual_presets = ["off", "random"] _virtual_presets = ["off", "random"]
def __init__(self, autoinit=""): def __init__(self, autoinit=""):
@ -574,7 +583,8 @@ class ColorScheme:
else: return False else: return False
def _get_cfg_dir(self, quiet=False, create=False): def _get_cfg_dir(self, quiet=False, create=False):
"""Returns path of the config dir.""" """ Returns path of the config dir. """
import os import os
# The name of our config directory # The name of our config directory
XDG_NAME = "c4ctrl" XDG_NAME = "c4ctrl"
@ -601,7 +611,7 @@ class ColorScheme:
return cfg_dir return cfg_dir
def _expand_preset(self, preset): def _expand_preset(self, preset):
"""Tries to expand given string to a valid preset name.""" """ Tries to expand given string to a valid preset name. """
import os import os
if not self.available: if not self.available:
cfg_dir = self._get_cfg_dir(quiet=True) cfg_dir = self._get_cfg_dir(quiet=True)
@ -620,11 +630,13 @@ class ColorScheme:
return preset return preset
def _topic_is_master(self, topic): def _topic_is_master(self, topic):
"""Does the given topic look like a master topic?""" """ Does the given topic look like a master topic? """
return topic.lower().rfind("/master") == len(topic)-7 # 7 = len("/master") return topic.lower().rfind("/master") == len(topic)-7 # 7 = len("/master")
def _random_color(self): def _random_color(self):
"""Returns a 3*4 bit pseudo random color in 6 char hex notation.""" """ Returns a 3*4 bit pseudo random color in 6 char hex notation. """
from random import randint, sample from random import randint, sample
chls = [15] chls = [15]
chls.append(randint(0,15)) chls.append(randint(0,15))
@ -660,9 +672,13 @@ class ColorScheme:
return color return color
def color_for(self, topic): def color_for(self, topic):
"""Returns the color (hex) this ColorScheme provides for the given topic.""" """ Returns the color (in hexadecimal notation) this ColorScheme assumes
for the given topic. """
# We need to take care not to return colors for both "normal" topics # We need to take care not to return colors for both "normal" topics
# and masters, as setting masters would override other settings # and masters, as setting masters would override other settings.
# If this ColorScheme has been read from a file though, we asssume that
# the user has taken care of this and apply what we are told to apply.
if self.mapping: if self.mapping:
if topic in self.mapping.keys(): if topic in self.mapping.keys():
return self.mapping[topic] return self.mapping[topic]
@ -676,7 +692,8 @@ class ColorScheme:
return None return None
def from_file(self, preset): def from_file(self, preset):
"""Load ColorScheme from file.""" """ Load ColorScheme from file. """
if preset == '-': if preset == '-':
fd = sys.stdin fd = sys.stdin
else: else:
@ -721,15 +738,15 @@ class ColorScheme:
fd.close() fd.close()
def from_color(self, color): def from_color(self, color):
"""Derive ColorScheme from a single hex color.""" """ Derive ColorScheme from a single hex color. """
self.single_color = color.lstrip('#').strip('-') self.single_color = color.lstrip('#').strip('-')
def from_random(self): def from_random(self):
"""Derive ColorScheme from random colors.""" """ Derive ColorScheme from random colors. """
self.return_random_color = True self.return_random_color = True
def list_available(self): def list_available(self):
"""List available presets.""" """ List available presets. """
import os import os
cfg_dir = self._get_cfg_dir() cfg_dir = self._get_cfg_dir()
if not cfg_dir: if not cfg_dir:
@ -745,7 +762,7 @@ class ColorScheme:
print(" " + entry) print(" " + entry)
def store(self, name): def store(self, name):
"""Store the current state of all lights as preset.""" """ Store the current state of all lights as preset. """
# First of all, refuse to override virtual presets # First of all, refuse to override virtual presets
if name in self._virtual_presets: if name in self._virtual_presets:
print("I'm sorry Dave. I'm afraid I can't do that. The name \"{}\" is reserved. Please choose a different one.".format(name)) print("I'm sorry Dave. I'm afraid I can't do that. The name \"{}\" is reserved. Please choose a different one.".format(name))
@ -809,39 +826,8 @@ class ColorScheme:
print("Wrote preset \"{}\"".format(name)) print("Wrote preset \"{}\"".format(name))
class Fluffy:
"""Fluffyd functions."""
modes = {
# Fluffy modes and their id's
"fade" : 1,
"wave" : 4,
"pulse" : 8,
"emp" : 9,
"flash" : 12
}
def ghostly_topic(self, topic):
# Return the ghost topic of topic
return "ghosts" + topic[topic.find('/'):]
def ghostly_payload(self, payload, mode_id):
return payload + int(mode_id).to_bytes(1, "little")
def mode_id(self, name):
if name.isdecimal() and int(name) <= 255:
# Let's trust the user with this
return (int(name), False)
else:
if name.lower() in self.modes.keys():
return (self.modes[name.lower()], False)
# Fallback
return (0, True)
class RemotePresets: class RemotePresets:
"""Remote preset control.""" """ Remote preset control. """
def __init__(self): def __init__(self):
self.map = { self.map = {
@ -878,7 +864,7 @@ class RemotePresets:
} }
def _expand_room_name(self, name): def _expand_room_name(self, name):
"""Try to expand partial names.""" """ Returns a valid room name expanded from the given name. """
if name in self.map.keys(): if name in self.map.keys():
# Return on exact match # Return on exact match
return name return name
@ -890,12 +876,15 @@ class RemotePresets:
return name return name
def _expand_preset_name(self, name, rooms, available): def _expand_preset_name(self, name, rooms, available):
"""Try to expand partial preset names. """ Returns a valid preset name expanded from the given name.
<rooms> must be a list of rooms to consider. Takes care to match only presets which are available for all rooms
<available> must be a dict as returned by query_available().""" specified.
# We need to take care to match only presets which are available for
# every room specified rooms is a list of rooms for which the preset should be a valid
option.
available is a dict containing valid presets for rooms as returned
by query_available(). """
# Strip every "global" out of the room list. We take special care of # Strip every "global" out of the room list. We take special care of
# "global" later on. # "global" later on.
@ -932,7 +921,7 @@ class RemotePresets:
return name return name
def query_available(self, rooms=["global"]): def query_available(self, rooms=["global"]):
"""Returns a dict of remotely available presets for [rooms].""" """ Returns a dict of remotely available presets for [rooms]. """
import json import json
# Presets in "global" are available everywhere and should always be included # Presets in "global" are available everywhere and should always be included
@ -961,7 +950,8 @@ class RemotePresets:
return available return available
def list_available(self, room="global"): def list_available(self, room="global"):
"""Print a list of available Presets.""" """ Print a list of available Presets. """
room = self._expand_room_name(room) room = self._expand_room_name(room)
available = self.query_available([room]) available = self.query_available([room])
@ -974,7 +964,8 @@ class RemotePresets:
print( " " + preset) print( " " + preset)
def apply_preset(self, preset, rooms=["global"]): def apply_preset(self, preset, rooms=["global"]):
"""Apply preset to given rooms.""" """ Apply preset to given rooms. """
# Strip spaces and expand rooms names # Strip spaces and expand rooms names
for i in range(len(rooms)): for i in range(len(rooms)):
rooms[i] = self._expand_room_name(rooms[i].strip()) rooms[i] = self._expand_room_name(rooms[i].strip())
@ -1015,6 +1006,7 @@ if __name__ == "__main__":
parser.add_argument( parser.add_argument(
"-d", "--debug", action="store_true", "-d", "--debug", action="store_true",
help="display what would be send to the MQTT broker, but do not actually connect") help="display what would be send to the MQTT broker, but do not actually connect")
# Various club functions # Various club functions
group_fn = parser.add_argument_group(title="various functions") group_fn = parser.add_argument_group(title="various functions")
group_fn.add_argument( group_fn.add_argument(
@ -1026,6 +1018,7 @@ if __name__ == "__main__":
group_fn.add_argument( group_fn.add_argument(
"-S", "--shutdown", action="count", "-S", "--shutdown", action="count",
help="shutdown (give twice to force shutdown)") help="shutdown (give twice to force shutdown)")
# Kitchenlight control # Kitchenlight control
group_kl = parser.add_argument_group(title="Kitchenlight control") group_kl = parser.add_argument_group(title="Kitchenlight control")
group_kl.add_argument( group_kl.add_argument(
@ -1034,6 +1027,7 @@ if __name__ == "__main__":
group_kl.add_argument( group_kl.add_argument(
"-i", "--list-kl-modes", action="store_true", "-i", "--list-kl-modes", action="store_true",
help="list available Kitchenlight modes and their options") help="list available Kitchenlight modes and their options")
# Ambient control # Ambient control
group_cl = parser.add_argument_group(title="ambient color control", group_cl = parser.add_argument_group(title="ambient color control",
description="PRESET may be either a preset name (which may be abbreviated), '#' followed by a color value in hex notation (eg. \"#ff0066\") or '-' to read from stdin.") description="PRESET may be either a preset name (which may be abbreviated), '#' followed by a color value in hex notation (eg. \"#ff0066\") or '-' to read from stdin.")
@ -1047,14 +1041,15 @@ if __name__ == "__main__":
"-f", "--fnordcenter", type=str, dest="f_color", metavar="PRESET", "-f", "--fnordcenter", type=str, dest="f_color", metavar="PRESET",
help="apply local colorscheme PRESET to Fnordcenter") help="apply local colorscheme PRESET to Fnordcenter")
group_cl.add_argument( group_cl.add_argument(
"-m", "--magic", type=str, default="fade", metavar="MODE", "-N", "--no-magic", action="store_true",
help="EXPERIMENTAL: blend into preset (needs a running instance of fluffyd on the network). MODE is either \"fade\", \"wave\", \"pulse\", \"emp\", \"flash\" or \"none\".") help="Do not use fluffyd to change colors.")
group_cl.add_argument( group_cl.add_argument(
"-l", "--list-presets", action="store_true", "-l", "--list-presets", action="store_true",
help="list locally available presets") help="list locally available presets")
group_cl.add_argument( group_cl.add_argument(
"-o", "--store-preset", type=str, dest="store_as", metavar="NAME", "-o", "--store-preset", type=str, dest="store_as", metavar="NAME",
help="store current state as preset NAME ('-' to write to stdout)") help="store current state as preset NAME ('-' to write to stdout)")
# Switch control # Switch control
group_sw = parser.add_argument_group(title="light switch control", group_sw = parser.add_argument_group(title="light switch control",
description="BINARY_CODE is a string of 0s or 1s for every light in the room. Accepts integers also. Will show some information and ask for input if omitted.") description="BINARY_CODE is a string of 0s or 1s for every light in the room. Accepts integers also. Will show some information and ask for input if omitted.")
@ -1070,6 +1065,7 @@ if __name__ == "__main__":
group_sw.add_argument( group_sw.add_argument(
"-K", nargs='?', dest="k_switch", const="", metavar="BINARY_CODE", "-K", nargs='?', dest="k_switch", const="", metavar="BINARY_CODE",
help="switch lights in Keller on/off") help="switch lights in Keller on/off")
# Remote presets # Remote presets
group_rp = parser.add_argument_group(title="remote preset functions", group_rp = parser.add_argument_group(title="remote preset functions",
description="Available room names are \"wohnzimmer\", \"plenar\", \"fnord\" and \"keller\". Preset and room names may be abbreviated.") description="Available room names are \"wohnzimmer\", \"plenar\", \"fnord\" and \"keller\". Preset and room names may be abbreviated.")
@ -1085,7 +1081,8 @@ if __name__ == "__main__":
if args.debug: if args.debug:
C4Interface.debug = True C4Interface.debug = True
if args.status: if args.status:
C4Interface().status() status = C4Interface().status()
print("Club is", status)
if args.gate: if args.gate:
C4Interface().open_gate() C4Interface().open_gate()
if args.shutdown: if args.shutdown:
@ -1113,15 +1110,15 @@ if __name__ == "__main__":
if args.w_color: if args.w_color:
if args.w_color not in presets: if args.w_color not in presets:
presets[args.w_color] = ColorScheme(autoinit=args.w_color) presets[args.w_color] = ColorScheme(autoinit=args.w_color)
if presets[args.w_color]: Wohnzimmer().set_colorscheme(presets[args.w_color], args.magic) if presets[args.w_color]: Wohnzimmer().set_colorscheme(presets[args.w_color], args.no_magic)
if args.p_color: if args.p_color:
if args.p_color not in presets: if args.p_color not in presets:
presets[args.p_color] = ColorScheme(autoinit=args.p_color) presets[args.p_color] = ColorScheme(autoinit=args.p_color)
if presets[args.p_color]: Plenarsaal().set_colorscheme(presets[args.p_color], args.magic) if presets[args.p_color]: Plenarsaal().set_colorscheme(presets[args.p_color], args.no_magic)
if args.f_color: if args.f_color:
if args.f_color not in presets: if args.f_color not in presets:
presets[args.f_color] = ColorScheme(autoinit=args.f_color) presets[args.f_color] = ColorScheme(autoinit=args.f_color)
if presets[args.f_color]: Fnordcenter().set_colorscheme(presets[args.f_color], args.magic) if presets[args.f_color]: Fnordcenter().set_colorscheme(presets[args.f_color], args.no_magic)
if args.list_presets: if args.list_presets:
ColorScheme().list_available() ColorScheme().list_available()