Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/megalinter/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"Lunatone",
"membank",
"overvoltage",
"plugdev",
"portname",
"pytest",
"randomise",
Expand All @@ -39,13 +40,15 @@
"setuptools",
"Sven",
"testframe",
"udevadm",
"undervoltage",
"ungroup",
"usec",
"usermod",
"venv",
"Vrms"
],
"language": "en",
"noConfigSearch": true,
"version": "0.2"
}
}
3 changes: 1 addition & 2 deletions .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ jobs:

# MegaLinter
- name: MegaLinter
uses: oxsecurity/megalinter@v8.4.2
uses: oxsecurity/megalinter@v9.4.0
id: ml
env:
VALIDATE_ALL_CODEBASE: true
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MEGALINTER_CONFIG: .github/megalinter/mega-linter.yml
Comment thread
SvenHaedrich marked this conversation as resolved.

28 changes: 28 additions & 0 deletions 99-lunatone-dali.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Lunatone DALI USB udev rules
#
# Instructions:
# Copy this file to the udev rules
# sudo cp 99-lunatone-dali.rules /etc/udev/rules.d/
# Reload the udev rules
# sudo udevadm control --reload-rules
#
#
# By default, this file restricts the access to root and members of the `plugdev`
# group via MODE="0660". You can grant access to specific user accounts by
# adding them to the `plugdev` group.
# To grant yourself permission:
#
# sudo usermod -a -G plugdev `whoami`
#
# You will have to log out and then back in for the group change to take effect.
# To grant permission to a specific {user}:
#
# sudo usermod -a -G plugdev {user}
#
# replacing {user} with the actual username.
# If you really want everyone to have read/write access you can change MODE
# below to "0666". This is less secure.
#

# Lunatone DALI USB
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="17b5", ATTRS{idProduct}=="0020", MODE="0660", GROUP="plugdev"
30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Command line interface to control a DALI system.
> [!IMPORTANT]
> This application is still in development. Use with caution. Give ample feedback.

DALI is the digital addressable lighting interface as described [here](https://www.dali-alliance.org).
DALI is the digital addressable lighting interface as described by the [DALI-Alliance](https://www.dali-alliance.org).

## Usage

Expand Down Expand Up @@ -82,19 +82,43 @@ bit : description
## Tests

This script:

```bash
./test_dali_cli.sh
```

prepares a virtual environment, and then runs the tests. Optionally you can
add `--log-level=debug` for more detailed logging.


## Install from github

```shell
git clone git@github.com:SvenHaedrich/dali_cli.git
git clone https://github.com/SvenHaedrich/dali_cli.git
cd dali_cli
python3 -m venv --prompt dali venv
source venv/bin/activate
python3 -m pip install -e .
```

## HID-USB Support

For the Lunatone USB adapter you need to copy the file `99-lunatone-dali.rules` into
the `udev` folder and reload the `udev` rules.

```shell
sudo cp 99-lunatone-dali.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
```

By default, this rule uses `MODE="0660"`, which grants read/write access only to root
and members of the appropriate group (for example `plugdev`). If you really want to
allow all users to access the device, you can change `MODE` to `0666`. You can grant
access to specific user accounts by adding them to the `plugdev` group. Note that some
Linux distributions always require per-user permission. To grant permission to a user
named `<username>`:

```shell
sudo usermod -a -G plugdev <username>
```

You will have to log out and then back in for the group change to take effect.
9 changes: 1 addition & 8 deletions dali/DALI/device/device_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import click
from dali_interface import DaliFrame, DaliInterface
from typeguard import typechecked

from ..system.constants import DaliFrameLength
from .device_address import DeviceAddress, InstanceAddress
Expand All @@ -13,7 +12,6 @@
logger = logging.getLogger(__name__)


@typechecked
def query_instance_value(dali: DaliInterface, adr_parameter: str, instance_parameter: str, opcode: int) -> int | None:
"""Query a value from a control device instance"""
address = DeviceAddress(adr_parameter)
Expand All @@ -29,13 +27,11 @@ def query_instance_value(dali: DaliInterface, adr_parameter: str, instance_param
return None


@typechecked
def query_device_value(dali: DaliInterface, adr_parameter: str, opcode: int) -> int | None:
"""Query a value from a control device"""
return query_instance_value(dali, adr_parameter, "DEVICE", opcode)


@typechecked
def set_device_dtr0(dali: DaliInterface, value: int) -> None:
"""Set control device data transfer register 0"""
logger.debug("set_device_dtr0")
Expand All @@ -44,7 +40,6 @@ def set_device_dtr0(dali: DaliInterface, value: int) -> None:
dali.transmit(DaliFrame(length=DaliFrameLength.DEVICE, data=command), block=True)


@typechecked
def set_device_dtr1(dali: DaliInterface, value: int) -> None:
"""Set control device data transfer register 1"""
logger.debug("set_device_dtr1")
Expand All @@ -53,7 +48,6 @@ def set_device_dtr1(dali: DaliInterface, value: int) -> None:
dali.transmit(DaliFrame(length=DaliFrameLength.DEVICE, data=command), block=True)


@typechecked
def write_device_frame(
dali: DaliInterface,
address_byte: int = 0,
Expand All @@ -70,7 +64,6 @@ def write_device_frame(
)


@typechecked
def set_device_dtr2_dtr1(dali: DaliInterface, dtr2: int, dtr1: int) -> None:
"""Set control device data transfer registers 0 and 1 simultaneously"""
"""Set control device data transfer registers 2 and 1 simultaneously"""
write_device_frame(dali, DeviceSpecialCommandOpcode.DTR2_DTR1, dtr2, dtr1)
8 changes: 2 additions & 6 deletions dali/DALI/device/device_address.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

from enum import Enum, unique

from typeguard import typechecked

from ..system.constants import DaliMax


Expand All @@ -19,11 +17,10 @@ class DeviceAddressing(Enum):
SPECIAL = 5


@typechecked
class DeviceAddress:
"""Interfaces between DALI address mode and frame codes"""

def __init__(self, mode="BC") -> None:
def __init__(self, mode: str = "BC") -> None:
self.mode = DeviceAddressing.INVALID
self.byte = 0
if mode == "SPECIAL":
Expand Down Expand Up @@ -118,11 +115,10 @@ class InstanceAddressing(Enum):
DEVICE = 11


@typechecked
class InstanceAddress:
"""Interfaces between DALI addressing representation and command addressing format"""

def __init__(self, mode="DEVICE") -> None:
def __init__(self, mode: str = "DEVICE") -> None:
self.mode = InstanceAddressing.INVALID
self.byte = 0
if self.arg(mode):
Expand Down
9 changes: 8 additions & 1 deletion dali/DALI/device/device_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@
default="BC",
help="Address, can be a short address (0..63) or group address (G0..G15).",
)
def dump(dali: DaliInterface, adr, bank):
def dump(dali: DaliInterface, adr: str, bank: int) -> None:
"""
Dump the contents of a memory bank

:param dali: DALI interface to use
:param adr: Address information
:param bank: Memory bank number
"""
set_device_dtr1(dali, bank)
set_device_dtr0(dali, 0)
last_accessible_location = query_device_value(dali, adr, DeviceQueryCommandOpcode.READ_MEMORY)
Expand Down
Loading
Loading