Example #1
0
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
Example #2
0
 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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
 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
Example #6
0
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
Example #7
0
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
Example #8
0
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")
Example #9
0
    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")
Example #10
0
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")