sde1000 / python-dali

Library for controlling DALI lighting systems
Other
150 stars 73 forks source link

Question about connections between DALI device and Tridonic adapter #46

Closed gabiSRC closed 6 years ago

gabiSRC commented 6 years ago

Hello again :) First and to be completely honnest, I am 100% new to DALI and DALI connection, so, please indulge me for my ignorance.

I have a LED connected to my OSRAM OPTOTRONIC 15/220-240-1A0 LT2 and I connected DA 3 and DA 4 to one of my Tridonic DALI port: https://ibb.co/jQasPd

And now I want to control the LED. Are my connections OK?

I really feel dumb asking that but I would like to avoid killing my devices :)

Anyway, thank you

gabiSRC commented 6 years ago

Just a little precision, I ask this because I have the following error:

$python3 find-ballast.py 
Traceback (most recent call last):
  File "find-ballast.py", line 93, in <module>
    ballasts = find_ballasts(d)
  File "find-ballast.py", line 58, in find_ballasts
    i.send(Terminate())
  File "/usr/local/lib/python3.4/dist-packages/python_dali-0.6.dev0-py3.4.egg/dali/driver/tridonic.py", line 232, in send
  File "/usr/local/lib/python3.4/dist-packages/python_dali-0.6.dev0-py3.4.egg/dali/driver/base.py", line 184, in read
  File "/usr/local/lib/python3.4/dist-packages/usb/core.py", line 402, in read
    return self.device.read(self, size_or_buffer, timeout)
  File "/usr/local/lib/python3.4/dist-packages/usb/core.py", line 988, in read
    self.__get_timeout(timeout))
  File "/usr/local/lib/python3.4/dist-packages/usb/backend/libusb1.py", line 851, in intr_read
    timeout)
  File "/usr/local/lib/python3.4/dist-packages/usb/backend/libusb1.py", line 936, in __read
    _check(retval)
  File "/usr/local/lib/python3.4/dist-packages/usb/backend/libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out

And my find-ballast.py file is:

#!/usr/bin/env python

from __future__ import print_function
from __future__ import division

from dali.gear.general import Compare
from dali.gear.general import Initialise
from dali.gear.general import Randomise
from dali.gear.general import SetSearchAddrH
from dali.gear.general import SetSearchAddrL
from dali.gear.general import SetSearchAddrM
from dali.gear.general import Terminate
from dali.gear.general import Withdraw
from dali.gear.general import QueryActualLevel
from dali.driver.tridonic import SyncTridonicDALIUSBDriver
import signal
import sys
import time
import logging
from logging.handlers import RotatingFileHandler

def set_search_addr(i, addr):
    i.send(SetSearchAddrH((addr >> 16) & 0xff))
    i.send(SetSearchAddrM((addr >> 8) & 0xff))
    i.send(SetSearchAddrL(addr & 0xff))

def find_next(i, low, high):
    """Find the ballast with the lowest random address.  The caller
    guarantees that there are no ballasts with an address lower than
    'low'.
    """
    print("Searching from {} to {}...".format(low, high))
    if low == high:
        set_search_addr(i, low)
        response = i.send(Compare())

        if response.value is True:
            print("Found ballast at {}; withdrawing it...".format(low))
            i.send(Withdraw())
            return low
        return None

    set_search_addr(i, high)
    response = i.send(Compare())

    if response.value is True:
        midpoint = (low + high) // 2
        return find_next(i, low, midpoint) or find_next(i, midpoint + 1, high)

def find_ballasts(interface):
    i = interface
    _ballasts = []
    _ballastsData = []

    i.send(Terminate())
    i.send(Initialise(broadcast=True, address=None))
    i.send(Randomise())
    time.sleep(0.1)  # Randomise may take up to 100ms

    low = 0
    high = 0xffffff
    while low is not None:
        low = find_next(i, low, high)
        if low is not None:
            _ballasts.append(low)
            low += 1

    i.send(Terminate())
    return _ballasts

if __name__ == "__main__":

    logger = logging.getLogger('TridonicDALIDriver')

    logger.setLevel(logging.DEBUG)
    handler = RotatingFileHandler('/tmp/ipe-dali-findballast.log', mode='a', maxBytes=5*1024*1024, backupCount=2, encoding=None, delay=0)
    handler.setLevel(logging.DEBUG)
    handler.setFormatter(logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    ))
    logger.addHandler(handler)

    d = SyncTridonicDALIUSBDriver()

    d.logger = logger
    d.debug = True

    ballasts = find_ballasts(d)

    print("{} ballasts found:".format(len(ballasts)))

    for ballast in ballasts:
        ballastActualLevel = d.send(QueryActualLevel(Short(ballast)))
        ballastType = d.send(QueryDeviceType(Short(ballast)))
        ballastData = {"addr": ballast, "type": ballastType, "level": ballastActualLevel}
        _ballastsData.append(ballastData)

    print(_ballastsData)
sde1000 commented 6 years ago

Sorry about the delay in replying - I am away from home. I may have a chance to have a look this weekend.

gabiSRC commented 6 years ago

No problem at all I just thought adding a little context would not hurt :)

Thank you!

gabiSRC commented 6 years ago

Hi, After several connections tests I got it working :)

But now I have another question: how can I get the "real" address of the ballast? I got 2697578 when I run find-ballast but the real address is 0 (when in use set_single I put 0 as address and it is working) I really do not understand how to get the address and the utility of the Randomize.

Thank you.

sde1000 commented 6 years ago

You don't find the short addresses, you set them - they are stored in nvram in the ballasts. (find-ballasts is just a test, really - it omits the code for setting the addresses)

Have a look in dali/bus.py for code that sets addresses.

gabiSRC commented 6 years ago

Great, all was there even if there is an error when I run it with python3 as the import sets is no longer supported as it is included by default.

Thank you very much for all your time and help!