def normalise_filled(self, meta, val): if isinstance(val, list): val = tuple(val) if isinstance(val, tuple): return sb.tuple_spec(sb.optional_spec(sb.string_spec()), sb.required(sb.string_spec())).normalise( meta, val) task = sb.or_spec(sb.string_spec(), sb.none_spec()).normalise(meta, val) if not task: task = "list_tasks" target = "" if ":" in task: target, task = val.rsplit(":", 1) if "(" not in target: return target or sb.NotSpecified, task tokens = self.initial_parse(val) chosen_task = tokens.pop().string tokens.pop() collector = meta.everything["collector"] target_register = collector.configuration["target_register"] target_name = tokens.pop(0).string target_name = self.parse_overridden_target(meta, val, collector, target_register, target_name, tokens) return target_name, chosen_task
def normalise_filled(self, meta, val): options_spec = sb.set_options( filename=sb.required(sb.string_spec()), optional=sb.defaulted(sb.boolean(), False) ) lst_spec = sb.listof(sb.or_spec(sb.string_spec(), options_spec)) if isinstance(val, list): val = {"after": lst_spec.normalise(meta, val)} val = sb.set_options(after=lst_spec, before=lst_spec).normalise(meta, val) formatted = sb.formatted(sb.string_spec(), formatter=MergedOptionStringFormatter) for key in ("after", "before"): result = [] for i, thing in enumerate(val[key]): filename = thing optional = False if isinstance(thing, dict): filename = thing["filename"] optional = thing["optional"] filename = formatted.normalise(meta.at(key).indexed_at(i), filename) if optional and not os.path.exists(filename): log.warning(hp.lc("Ignoring optional configuration", filename=filename)) continue if not os.path.exists(filename): raise BadConfiguration( "Specified extra file doesn't exist", source=self.source, filename=filename, meta=meta, ) result.append(filename) val[key] = result return self.extras_spec.normalise(meta, val)
it "knows about listof": self.assertSignature(sb.listof(sb.integer_spec()), "[ integer , ... ]") self.assertSignature(sb.listof(sb.any_spec()), "[ <item> , ... ]") it "knows about dictof": self.assertSignature(sb.dictof(sb.string_spec(), sb.integer_spec()), "{ string : integer }") self.assertSignature(sb.dictof(sb.string_spec(), sb.any_spec()), "{ string : <item> }") it "knows about container_spec": class Container: def __init__(self, value): pass self.assertSignature(sb.container_spec(Container, sb.string_spec()), "string") it "knows about formatted": self.assertSignature(sb.formatted(sb.string_spec(), formatter=None), "string") it "knows about or_spec": self.assertSignature( sb.or_spec(sb.string_spec(), sb.dictionary_spec()), "string or dictionary" ) self.assertSignature(sb.or_spec(), "") self.assertSignature(sb.or_spec(sb.string_spec()), "string") self.assertSignature(sb.or_spec(sb.string_spec(), sb.any_spec()), "string or <item>") self.assertSignature( sb.or_spec(sb.string_spec(), sb.any_spec(), sb.boolean()), "string or <item> or boolean" )
class WSMessage(dictobj.Spec): path = dictobj.Field(sb.string_spec, wrapper=sb.required) message_id = dictobj.Field( sb.or_spec(sb.string_spec(), sb.tupleof(sb.string_spec())), wrapper=sb.required ) body = dictobj.Field(json_spec, wrapper=sb.required)
refresh_field = dictobj.NullableField( sb.boolean, help=""" Whether to refresh our idea of what is on the network If this is False then we will use the cached notion of what's on the network. """, ) timeout_field = dictobj.Field( sb.float_spec, default=20, help="The max amount of time we wait for replies from the lights") matcher_field = dictobj.NullableField( sb.or_spec(sb.string_spec(), sb.dictionary_spec()), help=""" What lights to target. If this isn't specified then we interact with all the lights that can be found on the network. This can be specfied as either a space separated key=value string or as a dictionary. For example, "label=kitchen,bathroom location_name=home" or ``{"label": ["kitchen", "bathroom"], "location_name": "home"}`` See https://delfick.github.io/photons-core/modules/photons_device_finder.html#valid-filters for more information on what filters are available. """,
from interactor.commander.command import DeviceChangeMixin from interactor.commander import helpers as ihp from interactor.commander.store import store from photons_control.transform import Transformer, PowerToggle from photons_canvas.theme import ApplyTheme from delfick_project.norms import dictobj, sb pkt_type_field = dictobj.Field( sb.or_spec(sb.integer_spec(), sb.string_spec()), wrapper=sb.required, help=""" The type of packet to send to the lights. This can be a number or the name of the packet as known by the photons framework. A list of what's available can be found at https://photons.delfick.com/interacting/packets.html """, ) pkt_args_field = dictobj.NullableField( sb.dictionary_spec(), help=""" A dictionary of fields that make up the payload of the packet we are sending to the lights. """, ) @store.command(name="status")