项目作者: alengwenus

项目描述 :
Asynchronous LCN-PCK library written in Python
高级语言: Python
项目地址: git://github.com/alengwenus/pypck.git
创建时间: 2018-10-27T11:58:06Z
项目社区:https://github.com/alengwenus/pypck

开源协议:Eclipse Public License 2.0

下载


pypck - Asynchronous LCN-PCK library written in Python

GitHub release (latest SemVer)
GitHub Workflow Status (dev branch)
Codecov branch
PyPI - Downloads
pre-commit

Buy Me A Coffee

Overview

pypck is an open source library written in Python which allows the connection to the LCN (local control network) system. It uses the vendor protocol LCN-PCK.
To get started an unused license of the coupling software LCN-PCHK and a hardware coupler is necessary.

pypck is used by the LCN integration of the Home Assistant project.

Example

  1. """Example for switching an output port of module 10 on and off."""
  2. import asyncio
  3. from pypck.connection import PchkConnectionManager
  4. from pypck.lcn_addr import LcnAddr
  5. async def main():
  6. """Connect to PCK host, get module object and switch output port on and off."""
  7. async with PchkConnectionManager(
  8. "192.168.2.41",
  9. 4114,
  10. username="lcn",
  11. password="lcn",
  12. settings={"SK_NUM_TRIES": 0},
  13. ) as pck_client:
  14. module = pck_client.get_address_conn(LcnAddr(0, 10, False))
  15. await module.dim_output(0, 100, 0)
  16. await asyncio.sleep(1)
  17. await module.dim_output(0, 0, 0)
  18. asyncio.run(main())

pypck REPL in ipython

pypck relies heavily on asyncio for talking to the LCN-PCHK software. This
makes it unusable with the standard python interactive interpreter.
Fortunately, ipython provides some support for asyncio in its interactive
interpreter, see
ipython autoawait.

Requirements

  • ipython at least version 7.0 (autoawait support)
  • pypck

Example session

  1. Python 3.8.3 (default, Jun 9 2020, 17:39:39)
  2. Type 'copyright', 'credits' or 'license' for more information
  3. IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
  4. In [1]: from pypck.connection import PchkConnectionManager
  5. ...: from pypck.lcn_addr import LcnAddr
  6. ...: import asyncio
  7. In [2]: connection = PchkConnectionManager(host='localhost', port=4114, username='lcn', password='lcn')
  8. In [3]: await connection.async_connect()
  9. In [4]: module = connection.get_address_conn(LcnAddr(seg_id=0, addr_id=10, is_group=False), request_serials=False)
  10. In [5]: await module.request_serials()
  11. Out[5]:
  12. {'hardware_serial': 127977263668,
  13. 'manu': 1,
  14. 'software_serial': 1771023,
  15. 'hardware_type': <HardwareType.UPU: 26>}
  16. In [6]: await module.dim_output(0, 100, 0)
  17. ...: await asyncio.sleep(1)
  18. ...: await module.dim_output(0, 0, 0)
  19. Out[6]: True

Caveats

ipython starts and stops the asyncio event loop for each toplevel command
sequence. Also it only starts the loop if the toplevel commands includes async
code (like await or a call to an async function). This can lead to unexpected
behavior. For example, background tasks run only while ipython is executing
toplevel commands that started the event loop. Functions that use the event
loop only internally may fail, e.g. the following would fail:

  1. In [4]: module = connection.get_address_conn(LcnAddr(seg_id=0, addr_id=10, is_group=False), request_serials=True)
  2. ---------------------------------------------------------------------------
  3. RuntimeError Traceback (most recent call last)
  4. <ipython-input-7-cd663974bde2> in <module>
  5. ----> 1 module = connection.get_address_conn(modaddr)
  6. /pypck/connection.py in get_address_conn(self, addr, request_serials)
  7. 457 address_conn = ModuleConnection(self, addr)
  8. 458 if request_serials:
  9. --> 459 self.request_serials_task = asyncio.create_task(
  10. 460 address_conn.request_serials()
  11. 461 )
  12. /usr/local/lib/python3.8/asyncio/tasks.py in create_task(coro, name)
  13. 379 Return a Task object.
  14. 380 """
  15. --> 381 loop = events.get_running_loop()
  16. 382 task = loop.create_task(coro)
  17. 383 _set_task_name(task, name)
  18. RuntimeError: no running event loop

See
ipython autoawait internals
for details.