Skip to content

Commit

Permalink
move dali driver interation to lamp
Browse files Browse the repository at this point in the history
  • Loading branch information
dgomes committed Apr 24, 2022
1 parent 250fded commit cc9d353
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 42 deletions.
1 change: 1 addition & 0 deletions dali2mqtt/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""DALI 2 MQTT package."""
5 changes: 3 additions & 2 deletions dali2mqtt/consts.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"""Constants common the various modules."""

import logging

"""Constants common the various modules."""
__author__ = "Diogo Gomes"
__version__ = "0.0.1"
__version__ = "0.0.3"
__email__ = "[email protected]"

HASSEB = "hasseb"
Expand Down
40 changes: 17 additions & 23 deletions dali2mqtt/dali2mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@
logger = logging.getLogger(__name__)


def dali_scan(driver):
def dali_scan(dali_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)))
present = dali_driver.send(
gear.QueryControlGearPresent(address.Short(lamp))
)
if isinstance(present, YesNoResponse) and present.value:
lamps.append(lamp)
logger.debug("Found lamp at address %d", lamp)
Expand Down Expand Up @@ -126,13 +128,13 @@ def scan_groups(dali_driver, lamps):
def initialize_lamps(data_object, client):
"""Initialize all lamps and groups."""

driver_object = data_object["driver"]
driver = 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)
lamps = dali_scan(driver)
logger.info(
"Found %d lamps",
len(lamps),
Expand All @@ -142,15 +144,9 @@ def create_mqtt_lamp(address, name):
try:
lamp_object = Lamp(
log_level,
driver_object,
driver,
name,
address,
min_physical_level=driver_object.send(
gear.QueryPhysicalMinimum(address)
).value,
min_level=driver_object.send(gear.QueryMinLevel(address)).value,
max_level=driver_object.send(gear.QueryMaxLevel(address)).value,
level=driver_object.send(gear.QueryActualLevel(address)).value,
)

data_object["all_lamps"][name] = lamp_object
Expand Down Expand Up @@ -205,7 +201,7 @@ def create_mqtt_lamp(address, name):
devices_names_config.get_friendly_name(short_address.address),
)

groups = scan_groups(driver_object, lamps)
groups = scan_groups(driver, lamps)
for group in groups:
logger.debug("Publishing group %d", group)

Expand Down Expand Up @@ -234,7 +230,7 @@ def on_message_cmd(mqtt_client, data_object, msg):
try:
lamp_object = data_object["all_lamps"][light]
logger.debug("Set light <%s> to %s", light, msg.payload)
data_object["driver"].send(gear.Off(lamp_object.short_address))
lamp_object.off()
mqtt_client.publish(
MQTT_STATE_TOPIC.format(data_object["base_topic"], light),
MQTT_PAYLOAD_OFF,
Expand Down Expand Up @@ -280,7 +276,7 @@ def on_message_brightness_cmd(mqtt_client, data_object, msg):
lamp_object.level = int(msg.payload.decode("utf-8"))
if lamp_object.level == 0:
# 0 in DALI is turn off with fade out
data_object["driver"].send(gear.Off(lamp_object.short_address))
lamp_object.off()
logger.debug("Set light <%s> to OFF", light)

mqtt_client.publish(
Expand Down Expand Up @@ -316,27 +312,25 @@ def on_message_brightness_get_cmd(mqtt_client, data_object, msg):
lamp_object = get_lamp_object(data_object, light)

try:
level = data_object["driver"].send(
gear.QueryActualLevel(lamp_object.short_address)
)
logger.debug("Get light <%s> results in %d", light, level.value)
lamp_object.actual_level()
logger.debug("Get light <%s> results in %d", light, lamp_object.level)

mqtt_client.publish(
MQTT_BRIGHTNESS_STATE_TOPIC.format(data_object["base_topic"], light),
level.value,
lamp_object.level,
retain=False,
)

mqtt_client.publish(
MQTT_STATE_TOPIC.format(data_object["base_topic"], light),
MQTT_PAYLOAD_ON if level.value != 0 else MQTT_PAYLOAD_OFF,
MQTT_PAYLOAD_ON if lamp_object.level != 0 else MQTT_PAYLOAD_OFF,
retain=False,
)

except ValueError as err:
logger.error(
"Can't convert <%s> to integer %d..%d: %s",
str(level),
lamp_object.level,
lamp_object.min_level,
lamp_object.max_level,
err,
Expand Down Expand Up @@ -374,7 +368,7 @@ def on_connect(


def create_mqtt_client(
driver_object,
driver,
mqtt_server,
mqtt_port,
mqtt_username,
Expand All @@ -389,7 +383,7 @@ def create_mqtt_client(
mqttc = mqtt.Client(
client_id="dali2mqtt",
userdata={
"driver": driver_object,
"driver": driver,
"base_topic": mqtt_base_topic,
"ha_prefix": ha_prefix,
"devices_names_config": devices_names_config,
Expand Down
2 changes: 1 addition & 1 deletion dali2mqtt/devicesnamesconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def load_devices_names_file(self):
except yaml.YAMLError as error:
logger.error("In devices file %s: %s", self._path, error)
raise DevicesNamesConfigLoadError()
except Exception as err:
except Exception:
logger.error(
"Could not load device names config <%s>, a new one will be created after successfull start",
self._path,
Expand Down
27 changes: 17 additions & 10 deletions dali2mqtt/lamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
MQTT_NOT_AVAILABLE,
MQTT_PAYLOAD_OFF,
MQTT_STATE_TOPIC,
__author__,
__email__,
__version__,
)
from slugify import slugify
Expand All @@ -33,20 +31,19 @@ def __init__(
driver,
friendly_name,
short_address,
min_physical_level,
min_level,
level,
max_level,
):
"""Initialize Lamp."""
self.driver = driver
self.short_address = short_address
self.friendly_name = friendly_name

self.device_name = slugify(friendly_name)
self.min_physical_level = min_physical_level
self.min_level = min_level
self.max_level = max_level
self.level = level

self.min_physical_level = driver.send(gear.QueryPhysicalMinimum(short_address)).value
self.min_level = driver.send(gear.QueryMinLevel(short_address)).value
self.max_level = driver.send(gear.QueryMaxLevel(short_address)).value
self.level = driver.send(gear.QueryActualLevel(short_address)).value

logger.setLevel(ALL_SUPPORTED_LOG_LEVELS[log_level])

def gen_ha_config(self, mqtt_base_topic):
Expand Down Expand Up @@ -79,13 +76,18 @@ def gen_ha_config(self, mqtt_base_topic):
}
return json.dumps(json_config)

def actual_level(self):
"""Retrieve actual level from ballast."""
self.__level = self.driver.send(gear.QueryActualLevel(self.short_address))

@property
def level(self):
"""Return brightness level."""
return self.__level

@level.setter
def level(self, value):
"""Commit level to ballast."""
if not self.min_level <= value <= self.max_level and value != 0:
raise ValueError
self.__level = value
Expand All @@ -94,5 +96,10 @@ def level(self, value):
"Set lamp <%s> brightness level to %s", self.friendly_name, self.level
)

def off(self):
"""Turn off ballast."""
self.driver.send(gear.Off(self.short_address))

def __str__(self):
"""Serialize lamp information."""
return f"{self.device_name} - address: {self.short_address.address}, actual brightness level: {self.level} (minimum: {self.min_level}, max: {self.max_level}, physical minimum: {self.min_physical_level})"
15 changes: 9 additions & 6 deletions tests/test_lamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@
MIN_BRIGHTNESS = 2
MAX_BRIGHTNESS = 250

def generate_driver_values(results):
for res in results:
result = mock.Mock()
result.value = res
print(result.value)
yield result

@pytest.fixture
def fake_driver():
drive = mock.Mock()
drive.send = lambda x: 0x00
yield drive
drive.dummy = generate_driver_values([MIN_BRIGHTNESS, MIN_BRIGHTNESS, MAX_BRIGHTNESS, 100, 100])
drive.send = lambda x: next(drive.dummy)
return drive


@pytest.fixture
Expand All @@ -37,10 +44,6 @@ def test_ha_config(fake_driver, fake_address):
driver=fake_driver,
friendly_name=friendly_name,
short_address=addr,
min_physical_level=2,
min_level=MIN_BRIGHTNESS,
level=100,
max_level=MAX_BRIGHTNESS,
)

assert lamp1.device_name == slugify(friendly_name)
Expand Down

0 comments on commit cc9d353

Please sign in to comment.