def scan_groups(dali_driver, lamps): groups = dict.fromkeys(range(16), []) for lamp in lamps: try: logging.debug("Search for groups for Lamp {}".format(lamp)) group1 = dali_driver.send( gear.QueryGroupsZeroToSeven( address.Short(lamp))).value.as_integer group2 = dali_driver.send( gear.QueryGroupsEightToFifteen( address.Short(lamp))).value.as_integer lamp_groups = [] for i in range(8): if (group1 & 1 << i) != 0: groups[i].append(lamp) lamp_groups.append(i) for i in range(8): if (group2 & 1 << i) != 0: groups[i + 7].append(lamp) lamp_groups.append(i + 8) logging.debug("Lamp {} is in groups {}".format(lamp, lamp_groups)) except Exception as e: logger.warning("Can't get groups for lamp %s: %s", lamp, e) return groups
def test_with_integer_destination(self): """commands accept integer destination""" self.assertEqual( generalgear.DAPC(5, 100).destination, address.Short(5)) self.assertEqual(generalgear.Off(5).destination, address.Short(5)) self.assertRaises(ValueError, generalgear.Off, -1) self.assertRaises(ValueError, generalgear.Off, 64) self.assertRaises(ValueError, generalgear.Off, None)
def on_connect(client, dalic, flags, result, max_lamps=4, ha_prefix=DEFAULT_HA_DISCOVERY_PREFIX): client.subscribe([ (MQTT_COMMAND_TOPIC.format(MQTT_BASE_TOPIC, "+"), 0), (MQTT_BRIGHTNESS_COMMAND_TOPIC.format(MQTT_BASE_TOPIC, "+"), 0) ]) client.publish(MQTT_DALI2MQTT_STATUS.format(MQTT_BASE_TOPIC), MQTT_AVAILABLE, retain=True) lamps = dali_scan(dalic, max_lamps) for lamp in lamps: try: r = dalic.send(gear.QueryActualLevel(address.Short(lamp))) logger.debug("QueryActualLevel = %s", r.value) client.publish(HA_DISCOVERY_PREFIX.format(ha_prefix, lamp), gen_ha_config(lamp), retain=True) client.publish(MQTT_BRIGHTNESS_STATE_TOPIC.format( MQTT_BASE_TOPIC, lamp), r.value.as_integer, retain=True) client.publish(MQTT_STATE_TOPIC.format(MQTT_BASE_TOPIC, lamp), MQTT_PAYLOAD_ON if r.value.as_integer > 0 else MQTT_PAYLOAD_OFF, retain=True) except Exception as e: logger.error("While initializing lamp<%s>: %s", lamp, e)
def on_message_brightness_cmd(mosq, dalic, msg): logger.debug("Brightness Command on %s: %s", msg.topic, msg.payload) light = int( re.search( MQTT_BRIGHTNESS_COMMAND_TOPIC.format(MQTT_BASE_TOPIC, '(.+?)'), msg.topic).group(1)) try: level = int(msg.payload.decode("utf-8")) if not 0 <= level <= 255: raise ValueError logger.debug("Set light <%s> brightness to %s", light, level) r = dalic.send(gear.DAPC(address.Short(light), level)) if level == 0: # 0 in DALI is turn off with fade out mosq.publish(MQTT_STATE_TOPIC.format(MQTT_BASE_TOPIC, light), MQTT_PAYLOAD_OFF, retain=True) else: mosq.publish(MQTT_STATE_TOPIC.format(MQTT_BASE_TOPIC, light), MQTT_PAYLOAD_ON, retain=True) mosq.publish(MQTT_BRIGHTNESS_STATE_TOPIC.format( MQTT_BASE_TOPIC, light), level, retain=True) except ValueError as e: logger.error("Can't convert <%s> to interger 0..255: %s", level, e)
def scan(self): """Scan the bus for devices and ensure there are device objects for each discovered device. """ i = self.get_interface() for sa in range(64): if sa in self._devices: continue response = i.send(gear.QueryControlGearPresent(address.Short(sa))) if response.value: Device(address=sa, bus=self) self._bus_scanned = True
def dali_scan(dali_driver, max_range=4): lamps = [] for lamp in range(0, max_range): try: logging.debug("Search for Lamp {}".format(lamp)) r = dali_driver.send( gear.QueryControlGearPresent(address.Short(lamp))) if isinstance(r, YesNoResponse) and r.value: lamps.append(lamp) except Exception as e: logger.warning("%s not present: %s", lamp, e) return lamps
def dali_scan(driver): """Scan a maximum number of dali devices.""" lamps = [] for lamp in range(0, 63): try: logging.debug("Search for Lamp %s", lamp) present = driver.send(gear.QueryControlGearPresent(address.Short(lamp))) if isinstance(present, YesNoResponse) and present.value: lamps.append(lamp) except DALIError as err: logger.warning("%s not present: %s", lamp, err) return lamps
def on_message_cmd(mosq, dalic, msg): logger.debug("Command on %s: %s", msg.topic, msg.payload) light = int( re.search(MQTT_COMMAND_TOPIC.format(MQTT_BASE_TOPIC, '(.+?)'), msg.topic).group(1)) if msg.payload == MQTT_PAYLOAD_OFF: try: logger.debug("Set light <%s> to %s", light, msg.payload) dalic.send(gear.Off(address.Short(light))) mosq.publish(MQTT_STATE_TOPIC.format(MQTT_BASE_TOPIC, light), MQTT_PAYLOAD_OFF, retain=True) except: logger.error("Failed to set light <%s> to %s", light, "OFF")
def _check_destination(destination): """Check that a valid destination has been specified. destination can be a dali.device.Device object with _addressobj attribute, a dali.address.Address object with add_to_frame method, or an integer which will be wrapped in a dali.address.Address object. """ if hasattr(destination, "_addressobj"): destination = destination._addressobj if isinstance(destination, int): destination = address.Short(destination) if hasattr(destination, "add_to_frame"): return destination raise ValueError("destination must be an integer, dali.device.Device " "object or dali.address.Address object")
def initialize_lamps(data_object, client): driver_object = data_object["driver"] mqtt_base_topic = data_object["base_topic"] ha_prefix = data_object["ha_prefix"] log_level = data_object["log_level"] devices_names_config = data_object["devices_names_config"] devices_names_config.load_devices_names_file() lamps = dali_scan(driver_object) logger.info( "Found %d lamps", len(lamps), ) for lamp in lamps: try: short_address = address.Short(lamp) actual_level = driver_object.send(gear.QueryActualLevel(short_address)) physical_minimum = driver_object.send( gear.QueryPhysicalMinimum(short_address) ) min_level = driver_object.send(gear.QueryMinLevel(short_address)) max_level = driver_object.send(gear.QueryMaxLevel(short_address)) device_name = devices_names_config.get_friendly_name(short_address.address) lamp = device_name lamp_object = Lamp( log_level, driver_object, device_name, short_address, physical_minimum.value, min_level.value, actual_level.value, max_level.value, ) data_object["all_lamps"][lamp_object.device_name] = lamp_object lamp = lamp_object.device_name client.publish( HA_DISCOVERY_PREFIX.format(ha_prefix, lamp), lamp_object.gen_ha_config(mqtt_base_topic), retain=True, ) client.publish( MQTT_BRIGHTNESS_STATE_TOPIC.format(mqtt_base_topic, lamp), actual_level.value, retain=True, ) client.publish( MQTT_BRIGHTNESS_MAX_LEVEL_TOPIC.format(mqtt_base_topic, lamp), max_level.value, retain=True, ) client.publish( MQTT_BRIGHTNESS_MIN_LEVEL_TOPIC.format(mqtt_base_topic, lamp), min_level.value, retain=True, ) client.publish( MQTT_BRIGHTNESS_PHYSICAL_MINIMUM_LEVEL_TOPIC.format( mqtt_base_topic, lamp ), physical_minimum.value, retain=True, ) client.publish( MQTT_STATE_TOPIC.format(mqtt_base_topic, lamp), MQTT_PAYLOAD_ON if actual_level.value > 0 else MQTT_PAYLOAD_OFF, retain=True, ) logger.info( " - short address: %d, actual brightness level: %d (minimum: %d, max: %d, physical minimum: %d)", short_address.address, actual_level.value, min_level.value, max_level.value, physical_minimum.value, ) except DALIError as err: logger.error("While initializing lamp<%s>: %s", lamp, err) if devices_names_config.is_devices_file_empty(): devices_names_config.save_devices_names_file(data_object["all_lamps"]) logger.info("initialize_lamps finished")