diff --git a/.gitignore b/.gitignore index d8975633..1bfc589d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.o *.pyc *.log +.idea /openzwave/ build/ dists/ @@ -25,8 +26,9 @@ examples/pyozw.db examples/zwcfg_* examples/zwscene.xml examples/zwbutton.xml +examples/pyozw.sqlite install.files -src-lib/libopenzwave.so +src-lib/libopenzwave*.so src-lib/libopenzwave.egg-info/ src-lib/libopenzwave/libopenzwave.cpp src-api/openzwave.egg-info/ @@ -39,8 +41,30 @@ debian/files debian/*.debhelper debian/*.debhelper.log debian/*.substvars +debian/python-openzwave/ debian/python-openzwave-api/ debian/python-openzwave-doc/ debian/python-openzwave-lib/ debian/python-openzwave-manager/ debian/python-openzwave-web/ +debian/debhelper-build-stamp +debian/python3-openzwave/ +pybind +lib.txt +log.txt +pyozw.sqlite +venv2/ +venv3/ +.pybuild/ +.pypirc +open-zwave-master/ +openzwave-git/ +openzwave-embed/ +tmp/ +dist/ +docs/html/ +docs/joomla/ +libopenzwave*.so +.pipcache +options.xml +dynamic.dockerfile diff --git a/.travis.yml b/.travis.yml index 32b8cff9..0b787937 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,39 @@ -language: cpp -cache: - - apt +language: python +sudo: required python: - - "2.7" -# - "3.2" -# - "3.3" -# - "3.4" -install: -# - env -# - make pip - - make update - - make build - - sudo make install -# command to run tests -script: - - make autobuild-tests -# package dependencies +- '3.5' +env: + matrix: + - DOCKER_BASE=ubuntu:latest + - DOCKER_BASE=debian:latest + - DOCKER_BASE=i386/ubuntu:xenial + #~ - DOCKER_BASE=arm32v7/ubuntu:xenial + #~ - DOCKER_BASE=arm64v8/ubuntu:xenial + #~ - DOCKER_BASE=resin/rpi-raspbian:latest + - DOCS="true" + global: + - secure: "LdXdleVnh5s6HRPWLh3LcYo+s2IpvxwjFOQSJdMM1/svpstBu+pqAy6y6ivn4u7RUgG1Hva+iImMmqoBw4MUl+CTvK1RTLsOFFa0z37XSdWJbHSA+SmH9Dith1iHjaHTnkMNRaJugfJoLm2RXsii4ksMZcncm0gQLChyH+kxzX+ytoz8ofKk6f8zKqa+8YYhTlsV+BtnaEJOli22FKmLI8glOYiJpJj9UG8xQkwzNlIxR0PNZxvXnfVLeIw4sF9R3h6fkM/PZGbEfn1roZYDsdepl6SwumfmY+gOB74Ze7oObeJjmXA1HC8NSrsivIDB+gfAzKE01Jk2LyNZ+T2u7Zlqjf9pV0HhkYuBhc38BkpeBKkMKliJwuSIwEdsGWR71rC7VmegSbKp/I3Ev3oWy3h0k/J/W4SIxhN4mc8DAhaIC5TPdMHHTBSWyh494PEjX5zrinq4w6K7qjWpUB6rEUpHTHIE/F5f46QRTwFb5bhusIH8Hjo7GceEtYy1h8vGJ16GnAqvvrBJBU5QKCSfJicMiOUPELl3iD86vOdrJyYiiU+jALvgQH70D7KA9igIGRjmOdv71D09bEOVAYSNOaBsiCtyZqyx8kDMSETJ92VwhLO/aKazoGqlgiI8bEqSHA7Tjah6vyeTdnZeWRg7Fh2RM4W1T7lkXqzICNbUdW0=" +services: +- docker before_install: - #- env - #- sudo -E env - - sudo apt-get update -y -qq - - sudo -E make python-deps - - sudo -E make autobuild-deps +- if [[ "${DOCKER_BASE}x" != "x" ]]; then + docker pull ${DOCKER_BASE}; + fi +- if [[ "${DOCS}" == "true" ]]; then + sudo apt-get update; + sudo make common-deps; + fi +script: +- if [[ "${DOCKER_BASE}x" != "x" ]]; then + sed -e "s#ubuntu:latest#${DOCKER_BASE}#" Dockerfile > dynamic.dockerfile && docker build -t python-openzwave -f dynamic.dockerfile .; + fi +- if [[ "${DOCS}" == "true" ]]; then + set -e; + make doc-deps; + make install-api; + cd docs; + make html; + cd ..; + pip3 install doctr; + doctr deploy --built-docs docs/_build/html .; + fi diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 9f72ed1f..1b504fd0 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,13 +1,146 @@ - Changelog ********* +python_openzwave 0.4.18.x: + * Fix python 2.7/appveyor + + * Add serial port auto-detection + +python_openzwave 0.4.17.x: + * Add wheels for Windows + +python_openzwave 0.4.16.x: + * Fix appveyor build for windows + +python_openzwave 0.4.15.x: + * Update embeded package + +python_openzwave 0.4.14.x: + * Use Cython 0.28.6 + + * Update embeded package + +python_openzwave 0.4.12.x: + * Improve support Windows + + * COMMAND_CLASS_ZWAVE_PLUS_INFO renamed to + COMMAND_CLASS_ZWAVEPLUS_INFO + + * Update thermostat + + * Update embeded package + +python_openzwave 0.4.11.x: + * Update embeded package + +python_openzwave 0.4.10.x: + * Improve support Windows in pip + + * Improve tests Windows + + * Update contructors for scenes and groups + +python_openzwave 0.4.9.x: + * Improve support Windows in pip + + * Update tests + +python_openzwave 0.4.6.x: + * First try to support Windows in pip + +python_openzwave 0.4.5.x: + * Fix bug in node statistics and add test. + + * Update Makefile to build flavor dev + + * Update pyozw_check. + + * Update default flavor : check cython is here before choosing + shared + + * Fix controller.update_ozw_config when directory isn't writable + +python_openzwave 0.4.4.x: + * Add new options to pyozw_check to list nodes on network. + +python_openzwave 0.4.3.x: + * Fix bug in default flavor. + +python_openzwave 0.4.1.x: + * Update the default flavor : try to use a precompiled library. + If can't find one, use the embeded package. + + * Add method to controller to get new config from github. + +python_openzwave 0.4.0.x: + + * New installation process via pip + + * Update your install_requires : both libopenzwave, openzwave and + the manager are merged in python_openzwave package on pypi. Don't + need to update your imports in code. + + * There will be major updates in the next releases, it's safe to + use python_openzwave>0.4.0 and python_openzwave<0.5 in your + requires. + + * Remove old versions of libopenzwave and openzwave before you + update your installation with new pip process ... or not. + + * You can use the old installation process (via github), it's the + one I use to develop. + + * Installation via archive method is no longer suppored (no + release for 0.4.0). Use pip instead with --flavor embed option. + + * Default mode is embed now. + + * Update config path discovery : check for 'device_classes.xml' + in /etc/openzwave/, /usr/local/etc/openzwave/ and finally in + ozw_config in python_openzwave module. + + * Add flavor : different ways of building and installing + openzwave / python_openzwave. + + * Add infos on flavor / build date to getPythonLibraryVersion + + * Improve installation on micro machines : embed_shared build and + install openzwave/python_openzwave in 8 minutes on a raspberry pi + 3 + + * Add ozwdev and ozwdev_shared flavors : use openzwave dev branch + instead of master + + * Rename to COMMAND_CLASS_MULTI_CHANNEL_V2 to + COMMAND_CLASS_MULTI_INSTANCE/CHANNEL + + * Add tests for c++ library sync + + * Add door locks helpers + + * Add helpers for config parameters + + * Add data_items to value's dict + +python-openzwave 0.3.3: + + * Openzwave update + + * Update values getter in nodes. See #70 + + * Fix setvalue for string types in python3 + python-openzwave 0.3.2: * Openzwave update * Add thermostat + * Add patch from https://github.com/ebisso/python- + openzwave/commit/8776daccc730cb5d7f71a178e9e0cc1d191ad115 + + * Can compile dynamically + python-openzwave 0.3.1: * Fix bugs and openzwave update diff --git a/DEVEL.txt b/DEVEL.txt index bd172b8c..f2d8f06b 100644 --- a/DEVEL.txt +++ b/DEVEL.txt @@ -1,4 +1,3 @@ - Developers information ********************** @@ -6,88 +5,44 @@ Developers information How to develop for python-openzwave =================================== -Get the sources +Fork the project on Github. + +Get the sources : - git clone https://github.com/OpenZWave/python-openzwave + git clone https://github.com/yourname/python-openzwave You can install all the dependances to develop for python-openzwave using the command : - sudo make developper-deps + sudo make developer-deps + +You must now install python-openzwave in develop mode. Depending on +which python version you prefer, use : + + make venv2-dev -You must now install python-openzwave in develop mode +or - make develop + make venv2-dev -Your password will be asked (by sudo) for installing eggs in your -local directory. +Keep in mind that your updates must be python 2 / python 3 compatible. Develop, test, debug, test, ... :) Update the documentation if needed. You surely found the documentation useful, so please keep it up to date. -You can create an account on travis or docker to run the tests. - -At last but not least, submit your request. - - -How to develop for libopenzwave (was python-openzwave-lib) -========================================================== - -After updating the pyx, you need to reinstall it. Otherwise, your -changes will not be applied : - - make develop - - -Tests -===== - -First, install the dependances : - - sudo make tests-deps +It a good idea to add automatic tests. -To launch all the tests suite (about 140 tests), use the followind -command : +Launch the full test suite (for python 2 and python 3) : - make tests + make venv-tests -To launch on ly some tests : +At last but not least, submit your request with the result of tests in +the comment. - nosetests --verbosity=2 tests/api/test_controller_command.py - -Some tests need manual operations (ie to add a node, to remove one, -...). For example, to test the remove node, use : - - export MANUALSKIP='False' && nosetests --verbosity=2 tests/api/test_controller_command.py -m test_150 && unset MANUALSKIP - test_150_command_remove_node_and_wait_for_user (tests.api.test_controller_command.TestControllerCommand) ... ok - - ---------------------------------------------------------------------- - Ran 1 test in 16.031s - - OK - -You should push the inclusion button of the node before the end of the -test. - -Some tests don't need a ZWave Stick to be launched, so they can be run -on the autobuilders (travis, docker, ...). Place them in the autobuild -directory. - -Travis-ci, Docker Hub, nosetests and pylint are used to test quality -of code. There reports are here : - - * Docker : https://registry.hub.docker.com/u/bibi21000/python- - openzwave/ - - * Travis : https://travis-ci.org/bibi21000/python-openzwave - - * Nosetests report - - * Coverage report - - * Pylint report +If you don't follow the previous steps, your PR will be refused or +letting in pending state until I've got time to test it. Documentation @@ -97,97 +52,7 @@ First, install the dependances : sudo make doc-deps -Documentation is managed with sphinx. Don't utpdate txt files (README, -INSTALL, ...), update the RST sources in docs. Use the following -commands to generate all docs files (txt, html and joomla) - -You need to have installed python-openzwave (in either develop or -install mode) before generating the documentation. - - make docs - - -Static vs dynamic (or shared) -============================= - -The openzwave (c++) lib needs to run as a singleton : it means that it -MUST have only one instance of the manager running on your computer. - -There is 2 ways of linking libraries with a program : - - * static : includes a copy of the library in your binary program. - This means that your program has its own instance of the library. - This the way the install.sh runs. So you CAN'T have another - program (like the control-panel) running when using the python- - openzwave library - - * dynamic or shared : includes a link to the library in your - binary program. This means that your program share the library - with other programs. In this case, the instance is owned directly - by the library. This the way the debian package works. So you CAN - have another program running when using the python-openzwave - library. Of course, this program MUST use the shared library too. - - -About sudo -========== - -If you are like me and don't like root (and sudo), you can use the -following tip to install packages via pip : - -Look at your python local library, it should looks like : - - ls -lisa /usr/local/lib/python2.7/dist-packages/ - total 2428 - 1445174 12 drwxrwsr-x 115 root staff 12288 avril 9 21:35 . - 1445172 4 drwxrwsr-x 4 root staff 4096 mai 2 2014 .. - 1457164 4 drwxr-sr-x 5 root staff 4096 nov. 26 2013 actdiag - 1715480 4 drwxr-sr-x 2 root staff 4096 nov. 26 2013 actdiag-0.5.1.egg-info - 1457163 4 -rw-r--r-- 1 root staff 1004 nov. 26 2013 actdiag_sphinxhelper.py - 1457172 4 -rw-r--r-- 1 root staff 620 nov. 26 2013 actdiag_sphinxhelper.pyc - .... - -So, add your common user to the staff group : - - sudo usermod -a -G staff userName - -Add the write right to the group staff - - sudo chmod -Rf g+w /usr/local/lib/python2.7/dist-packages/ - -And now, it's time log off and log on. Groups are checked when you -open the session. - -You can now install your packages without sudo. - - -Python3 and virtualenv -====================== - -Python 3 is actually not supported. - -A branch (python3) has been created with a special Dockerfile. It -build python-openzwave and launch some tests. This branch is -automatically merged from master at "make commit". - -So please, do not directly push under python3 branch. Make your -developments under master or another branch. - -It's important for me have python2/python3 compatibilty in the master -branch. cython can help for this : -http://docs.cython.org/src/tutorial/strings.html - -The Makefile sill try to automatically configure your version of -python (running python --version). - -If you want to install python-openzwave in a python virtual -environnement, you should use something like : - - make VIRTUAL_ENV=/path/to/my/venv ... - -If you use python 3 and your python executable is called python3 : - - make PYTHON_EXEC=python3 ... +Documentation is managed with sphinx. -You can also put these variables in a CONFIG.make file instead of -passing them to the command line +Don't update txt and rst files (README, INSTALL, ...) in the root +directory, update the RST sources in docs. diff --git a/Dockerfile b/Dockerfile index e89e30e6..0fa0cc47 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,15 @@ -FROM debian:wheezy +FROM ubuntu:latest MAINTAINER bibi21000 -ADD . /home/docker-py2 -WORKDIR /home/docker-py2 -RUN apt-get update && apt-get install -y make python sudo -RUN make python-deps -RUN make autobuild-deps -RUN env -RUN make update -RUN make build -RUN make install -RUN make autobuild-tests +ENV PYOZW_DOCKER 1 +RUN apt-get update && apt-get dist-upgrade -y >/dev/null +RUN apt-get install -y --no-install-recommends make sudo apt-utils >/dev/null +ADD . /home/pyozw +WORKDIR /home/pyozw +RUN make docker-deps >/dev/null +RUN make openzwave.gzip >/dev/null +RUN make venv-dev-autobuild-tests +#RUN make venv-pypi-autobuild-tests +#RUN apt-get install --force-yes -y pkg-config >/dev/null +#RUN make venv-git_shared-autobuild-tests +#RUN apt-get remove --force-yes -y pkg-config >/dev/null +RUN make venv-pypilive-autobuild-tests diff --git a/EXAMPLES.txt b/EXAMPLES.txt index 011ab2d0..a219c666 100644 --- a/EXAMPLES.txt +++ b/EXAMPLES.txt @@ -1,4 +1,3 @@ - python-openzwave **************** @@ -8,14 +7,14 @@ You need to install and build python-openzwave to test examples. pyozwman ======== -A shell manager for your ZWave network : *PyOzwMan documentation* +A shell manager for your ZWave network : PyOzwMan documentation pyozwweb ======== A Flask + socket.io + jquery web application framework for your ZWave -network : *PyOzwWeb documentation* +network : PyOzwWeb documentation api_demo diff --git a/INSTALL_ARCH.rst b/INSTALL_ARCH.rst index d4065a7a..6a5ff8aa 100755 --- a/INSTALL_ARCH.rst +++ b/INSTALL_ARCH.rst @@ -4,7 +4,9 @@ Installing python-openzwave from archive ======================================== -This is the simplest (and the fastest) way to install python-openzwave. It cames with openzwave source files and is already cythonized. +This method is deprecated for 0.4.X. Use pip with --embed flavor. Look at README. + +This is the simplest (and the fastest) way to install python-openzwave. It comes with openzwave source files and is already cythonized. This is surely the best solution to install python-openzwave on a raspberry pi. diff --git a/INSTALL_MAC.rst b/INSTALL_MAC.rst index 9ded5e53..6369ee7f 100755 --- a/INSTALL_MAC.rst +++ b/INSTALL_MAC.rst @@ -4,6 +4,4 @@ Installing python-openzwave on MacOs ==================================== -To be done - -Looking for volunteers +Look at README for 0.4.X installation. diff --git a/INSTALL_REPO.rst b/INSTALL_REPO.rst index 06f1f3a9..14145af0 100755 --- a/INSTALL_REPO.rst +++ b/INSTALL_REPO.rst @@ -4,6 +4,8 @@ Installing python-openzwave from repository =========================================== +This method is deprecated for 0.4.X. Use pip with --git flavor. Look at README. + Install the needed tools ======================== diff --git a/INSTALL_WIN.rst b/INSTALL_WIN.rst index 05d7846f..6ced83fc 100755 --- a/INSTALL_WIN.rst +++ b/INSTALL_WIN.rst @@ -5,76 +5,183 @@ Installing python-openzwave on Windows ====================================== -How To Build python-openzwave on Windows with VS2015 -==================================================== +Install Microsoft tools +======================= -Assuming Python 3.5 is set in PATH -Assuming your python environment has pip, cython, setuptools +This package use MSBuild.exe to build openzwave code. +You can find it in Visual Studio 2017 or Visual Studio 2015. -Get sources ------------ +It's also possible to get it as a separate package. -.. code-block:: bash - - git clone https://github.com/openzwave/python-openzwave.git +Only release 14.0 and 15.0 of Microsft Build Tools are tested. - cd python-openzwave - git clone git://github.com/OpenZWave/open-zwave.git openzwave +You nust use the C++ compiler used to build your version of python : https://wiki.python.org/moin/WindowsCompilers - cd openzwave - git checkout Dev - cd .. - git checkout python3 +Install other tools +=================== -Build open-zwave ----------------- +You need git to clone the repository and python (32 bits or 64 bits). Add it to your PATH. -Open openzwave/cpp/build/windows/vs2010/OpenZWave.sln in Visual Studio +Install dependencies : -When asked, accept the project upgrade to VS2015 + - for python 2.7 : -Build Win32|Release + .. code-block:: bash + (venvX) pip install Cython six Louie -Build python-openzwave lib --------------------------- + - for python 3 : -Patch libopenzwave.pyx + .. code-block:: bash -Cause: ValueID has no default constructor and cython needs one for allocating objects on the stack + (venvX) pip install Cython six PyDispatcher -Fix: Allocate object on the the heap as a workaround +clone repositories +================== -Open test/python-openzwave/src-lib/libopenzwave/libopenzwave.pyx +Clone python-openzwave: -Go to line 437 and change: .. code-block:: bash - values_map.insert(pair[uint64_t, ValueID](v.GetId(), v)) + git clone https://github.com/OpenZWave/python-openzwave.git -To: +And clone open-zwave inside python-openzwave : .. code-block:: bash - newPair = new pair[uint64_t, ValueID](v.GetId(), v) - values_map.insert(deref(newPair)) - del newPair - -From a Command Prompt, build it : + cd python-openzwave + git clone https://github.com/OpenZWave/open-zwave.git openzwave -.. code-block:: bash +It's mandatory to clone the previous repository in a directory called openzwave (not open-zwave) - python setup-lib.py build - python setup-api.py build +Visual studio +============= -And install it (in a virtualenv if needed) : +Copy vs2010 in a new directory vs2017 (or vs2015 depending of which Visual Studio you use) : .. code-block:: bash - python setup-lib.py install - python setup-api.py install + xcopy openzwave\cpp\build\windows\vs2010 openzwave\cpp\build\windows\vs2017 /s /e /h + +Open the project (openzwave\cpp\build\windows\vs2017\OpenZWave.sln) in your Visual Studio. +If you want to build for 64bits, add a new target for it. And finally close it. + +Python-openzwave +================ + +Build and install python-openzwave : + + .. code-block:: bash + + python setup.py install --flavor=dev + + .. code-block:: bash + + sysargv ['setup.py', 'install'] + thon setup.py install --flavor=dev + Requirement already satisfied: Cython in c:\program files (x86)\python36-32\lib\site-packages + {'name': 'libopenzwave', 'sources': ['src-lib/libopenzwave/libopenzwave.pyx'], 'include_dirs': ['openzwave/cpp/src', 'openzwave + /cpp/src/value_classes', 'openzwave/cpp/src/platform', 'openzwave/cpp/build/windows', 'src-lib/libopenzwave', 'openzwave/cpp/bu + ild/windows/vs2017/Release/'], 'define_macros': [('PY_LIB_VERSION', '0.4.4'), ('PY_SSIZE_T_CLEAN', 1), ('PY_LIB_FLAVOR', 'dev') + , ('PY_LIB_BACKEND', 'cython')], 'libraries': ['setupapi', 'msvcrt', 'ws2_32', 'dnsapi'], 'extra_objects': ['openzwave/cpp/buil + d/windows/vs2017/Release//OpenZWave.lib'], 'extra_compile_args': [], 'extra_link_args': [], 'language': 'c++'} + ['six', 'PyDispatcher>=2.0.5', 'Cython'] + Requirement already satisfied: Cython in c:\program files (x86)\python36-32\lib\site-packages + running install + flavor --flavor=dev c:\program files (x86)\python36-32\lib\site-packages + running build_openzwave + Found MSBuild.exe : c:/Program Files (x86)/Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe + Found arch : Win32 wave + Found Visual Studio project : vs2017 (x86)/Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe + Found build path : openzwave/cpp/build/windows/vs2017/Release/ + ... + ... + byte-compiling C:\Program Files (x86)\Python36-32\Lib\site-packages\python_openzwave\scripts\__init__.py to __init__.cpython-36 + .pyc + running install_egg_info + running egg_info + writing python_openzwave.egg-info\PKG-INFO + writing dependency_links to python_openzwave.egg-info\dependency_links.txt + writing entry points to python_openzwave.egg-info\entry_points.txt + ================================================================ + .\scripts\allusers.bat + this script is executed for all users + delete/rename it if you dont need it + ================================================================ + Page de codes active�: 437 + +And finally, test it : + + .. code-block:: bash + + pyozw_check -l -d COM2 -t 30 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Define options for device COM2 + Start network + Wait for network awake (30s) + ------------------------------------------------------------------------------- + Network is awaked. Talk to controller. + Get python_openzwave version : 0.4.4 + Get python_openzwave config version : Original Z-Wave 2.78 + Get python_openzwave flavor : dev + Get openzwave version : 1.4.2942 + Get config path : C:\Program Files\Python36\lib\site-packages\python_openzwave\ozw_config + Controller capabilities : {'primaryController', 'staticUpdateController'} + Controller node capabilities : {'listening', 'primaryController', 'beaming', 'staticUpdateController'} + Nodes in network : 4 + ------------------------------------------------------------------------------- + Wait for network ready (30s) + ------------------------------------------------------------------------------- + Network is ready. Get nodes + ------------------------------------------------------------ + 1 - Name : ( Location : ) + 1 - Ready : True / Awake : True / Failed : False + 1 - Manufacturer : Aeotec ( id : 0x0086 ) + 1 - Product : DSA02203 Z-Stick S2 ( id : 0x0001 / type : 0x0002 / Version : 3) + 1 - Command classes : set() + 1 - Capabilities : {'listening', 'primaryController', 'beaming', 'staticUpdateController'} + 1 - Neighbors : {4} / Power level : None + 1 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 2 - Name : ( Location : ) + 2 - Ready : True / Awake : True / Failed : False + 2 - Manufacturer : ( id : 0x0000 ) + 2 - Product : ( id : 0x0000 / type : 0x0000 / Version : 2) + 2 - Command classes : set() + 2 - Capabilities : {'listening', 'routing'} + 2 - Neighbors : {3} / Power level : None + 2 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 3 - Name : ( Location : ) + 3 - Ready : False / Awake : True / Failed : True + 3 - Manufacturer : ( id : 0x0000 ) + 3 - Product : ( id : 0x0000 / type : 0x0000 / Version : 3) + 3 - Command classes : set() + 3 - Capabilities : {'listening', 'routing', 'beaming'} + 3 - Neighbors : set() / Power level : None + 3 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 4 - Name : ( Location : ) + 4 - Ready : True / Awake : True / Failed : False + 4 - Manufacturer : GreenWave ( id : 0x0099 ) + 4 - Product : PowerNode 6 port ( id : 0x0004 / type : 0x0003 / Version : 4) + 4 - Command classes : {'COMMAND_CLASS_MANUFACTURER_SPECIFIC', 'COMMAND_CLASS_ASSOCIATION', 'COMMAND_CLASS_NO_OPERATION', 'COMM + AND_CLASS_VERSION', 'COMMAND_CLASS_SWITCH_BINARY', 'COMMAND_CLASS_MULTI_INSTANCE/CHANNEL', 'COMMAND_CLASS_CRC_16_ENCAP', 'COMMA + ND_CLASS_PROTECTION', 'COMMAND_CLASS_CONFIGURATION', 'COMMAND_CLASS_BASIC', 'COMMAND_CLASS_METER', 'COMMAND_CLASS_SWITCH_ALL'} + 4 - Capabilities : {'listening', 'routing', 'beaming'} + 4 - Neighbors : {1} / Power level : None + 4 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + Driver statistics : {'SOFCnt': 49, 'ACKWaiting': 0, 'readAborts': 0, 'badChecksum': 0, 'readCnt': 49, 'writeCnt': 46, 'CANCnt': + 0, 'NAKCnt': 1, 'ACKCnt': 30, 'OOFCnt': 0, 'dropped': 17, 'retries': 0, 'callbacks': 0, 'badroutes': 0, 'noack': 4, 'netbusy': + 0, 'nondelivery': 0, 'routedbusy': 0, 'broadcastReadCnt': 0, 'broadcastWriteCnt': 9} + ------------------------------------------------------------ + Stop network + Exit -Reference : https://github.com/OpenZWave/python-openzwave/issues/53 diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..83ea5ef6 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +This file is part of python-openzwave project +https://github.com/OpenZWave/python-openzwave. + + +License +******* + +python-openzwave is free software: you can redistribute it and/or +modify it under the terms of the GNU General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +python-openzwave is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +author: bibi21000 author: maarten damen license: +GPL(v3) diff --git a/Makefile b/Makefile index c7b34aa3..9bb1a49b 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,6 @@ ARCHBASE = archive ARCHIVES = archives BUILDDIR = build DISTDIR = dists -NOSE = $(shell which nosetests) NOSEOPTS = --verbosity=2 NOSECOVER = --cover-package=openzwave,pyozwman,pyozwweb --with-coverage --cover-inclusive --cover-tests --cover-html --cover-html-dir=docs/html/coverage --with-html --html-file=docs/html/nosetests/nosetests.html PYLINT = $(shell which pylint) @@ -18,6 +17,10 @@ ifndef PYTHON_EXEC PYTHON_EXEC=python endif +ifndef NOSE_EXEC +NOSE_EXEC=$(shell which nosetests) +endif + ifdef VIRTUAL_ENV python_version_full := $(wordlist 2,4,$(subst ., ,$(shell ${VIRTUAL_ENV}/bin/${PYTHON_EXEC} --version 2>&1))) else @@ -35,21 +38,24 @@ ifeq (${python_version_major},3) PIP_EXEC=pip3 endif +WHL_PYTHON2 := $(shell ls dist/*.whl 2>/dev/null|grep ${python_openzwave_version}|grep [0-9]-cp2) +WHL_PYTHON3 := $(shell ls dist/*.whl 2>/dev/null|grep ${python_openzwave_version}|grep [0-9]-cp3) + ARCHNAME = python-openzwave-${python_openzwave_version} ARCHDIR = ${ARCHBASE}/${ARCHNAME} -.PHONY: help clean all update develop install install-api uninstall clean-docs docs autobuild-tests tests pylint commit developper-deps python-deps autobuild-deps arch-deps common-deps cython-deps merge-python3 check +.PHONY: help clean all update develop install install-api uninstall clean-docs docs autobuild-tests tests pylint commit developer-deps python-deps autobuild-deps arch-deps common-deps cython-deps check venv-clean venv2 venv3 help: @echo "Please use \`make ' where is one of" @echo " build : build python-openzwave and openzwave" - @echo " develop : install python-openzwave for developpers" + @echo " develop : install python-openzwave for developers" @echo " install : install python-openzwave for users" @echo " install-api : install python-openzwave (API only) for users" @echo " uninstall : uninstall python-openzwave" - @echo " developper-deps : install dependencies for developpers" + @echo " developer-deps : install dependencies for developers" @echo " deps : install dependencies for users" - @echo " docs : make documentation" + @echo " docs : make documentation" @echo " tests : launch tests" @echo " commit : publish python-openzwave updates on GitHub" @echo " clean : clean the development directory" @@ -63,7 +69,9 @@ clean: clean-docs clean-archive ${PYTHON_EXEC} setup-api.py clean --all --build-base $(BUILDDIR)/api ${PYTHON_EXEC} setup-manager.py clean --all --build-base $(BUILDDIR)/manager ${PYTHON_EXEC} setup-web.py clean --all --build-base $(BUILDDIR)/web - -rm lib/libopenzwave.cpp + ${PYTHON_EXEC} setup.py clean --all --build-base $(BUILDDIR)/python_openzwave + -rm -f lib/libopenzwave.cpp + -rm -f libopenzwave.so -rm src-lib/libopenzwave/libopenzwave.cpp -rm -rf debian/python-openzwave-api/ -rm -rf debian/python-openzwave-doc/ @@ -74,6 +82,13 @@ clean: clean-docs clean-archive -rm debian/*.debhelper -rm debian/*.debhelper.log -rm debian/*.substvars + -rm -rf .tests_user_path/ + -rm -rf openzwave-git + -rm -rf openzwave-embed + -rm -rf open-zwave-master + -rm -rf dist + -rm -rf tmp + -rm -rf venv2 venv3 uninstall: -rm -rf $(BUILDDIR) @@ -84,17 +99,20 @@ uninstall: -yes | ${PIP_EXEC} uninstall openzwave -yes | ${PIP_EXEC} uninstall pyozwman -yes | ${PIP_EXEC} uninstall pyozwweb - ${PYTHON_EXEC} setup-lib.py develop --uninstall + -yes | ${PIP_EXEC} uninstall python_openzwave + ${PYTHON_EXEC} setup-lib.py develop --uninstall --flavor=dev ${PYTHON_EXEC} setup-api.py develop --uninstall ${PYTHON_EXEC} setup-manager.py develop --uninstall ${PYTHON_EXEC} setup-web.py develop --uninstall + ${PYTHON_EXEC} setup.py develop --uninstall --flavor=dev -rm -f libopenzwave.so - -rm -f src-lib/libopenzwave.so + -rm -f src-lib/libopenzwave*.so -rm -f libopenzwave/liopenzwave.so -rm -Rf python_openzwave_api.egg-info/ -rm -Rf src-api/python_openzwave_api.egg-info/ -rm -Rf src-api/openzwave.egg-info/ -rm -Rf src-manager/pyozwman.egg-info/ + -rm -Rf python_openzwave.egg-info/ -rm -Rf src-lib/python_openzwave_lib.egg-info/ -rm -Rf src-lib/libopenzwave.egg-info/ -rm -Rf src-web/pyozwweb.egg-info/ @@ -107,14 +125,9 @@ uninstall: -rm -Rf /usr/local/share/python-openzwave -rm -Rf /usr/local/share/openzwave -check: .git - -.git: - @echo "Invalid git repository" && exit 1 - -developper-deps: common-deps cython-deps tests-deps pip-deps doc-deps +developer-deps: common-deps cython-deps tests-deps pip-deps doc-deps @echo - @echo "Dependencies for developpers of python-openzwave installed (python ${python_version_full})" + @echo "Dependencies for developers of python-openzwave installed (python ${python_version_full})" repo-deps: common-deps cython-deps tests-deps pip-deps @echo @@ -142,18 +155,23 @@ ifeq (${python_version_major},2) apt-get install --force-yes -y cython endif ifeq (${python_version_major},3) - apt-get install --force-yes -y cython3 + apt-get install --force-yes -y cython3 endif +ci-deps: + apt-get install --force-yes -y python-pip python-dev python-docutils python-setuptools python-virtualenv + -apt-get install --force-yes -y python3-pip python3-docutils python3-dev python3-setuptools + apt-get install --force-yes -y build-essential libudev-dev g++ libyaml-dev + common-deps: @echo Installing dependencies for python : ${python_version_full} ifeq (${python_version_major},2) - apt-get install --force-yes -y python-pip python-dev python-docutils python-setuptools python-louie + apt-get install --force-yes -y python-pip python-dev python-docutils python-setuptools endif ifeq (${python_version_major},3) -apt-get install --force-yes -y python3-pip python3-docutils python3-dev python3-setuptools endif - apt-get install --force-yes -y build-essential libudev-dev g++ + apt-get install --force-yes -y build-essential libudev-dev g++ libyaml-dev tests-deps: ${PIP_EXEC} install nose-html @@ -164,7 +182,7 @@ tests-deps: doc-deps: -apt-get install --force-yes -y python-sphinx - ${PIP_EXEC} install sphinxcontrib-blockdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag sphinxcontrib-seqdiag + ${PIP_EXEC} install cython sphinxcontrib-blockdiag sphinxcontrib-actdiag sphinxcontrib-nwdiag sphinxcontrib-seqdiag pip-deps: #${PIP_EXEC} install docutils @@ -172,14 +190,6 @@ pip-deps: #The following line crashes with a core dump #${PIP_EXEC} install "Cython==0.22" -merge-python3: - git checkout python3 - git merge -m "Auto-merge from master" master - git push - git checkout master - @echo - @echo "Commits for branch python3 pushed on github." - clean-docs: cd docs && $(MAKE) clean -rm -Rf docs/html @@ -187,18 +197,18 @@ clean-docs: -rm -Rf docs/pdf docs: clean-docs - -mkdir -p docs/html/nosetests - -mkdir -p docs/html/coverage - -mkdir -p docs/html/pylint - -mkdir -p docs/joomla/nosetests - -mkdir -p docs/joomla/coverage - -mkdir -p docs/joomla/pylint - #$(NOSE) $(NOSEOPTS) $(NOSECOVER) tests/ - #$(NOSE) $(NOSEOPTS) tests/ - -cp docs/html/nosetests/* docs/joomla/nosetests - -cp docs/html/coverage/* docs/joomla/coverage + #-mkdir -p docs/html/nosetests + #-mkdir -p docs/html/coverage + #-mkdir -p docs/html/pylint + #-mkdir -p docs/joomla/nosetests + #-mkdir -p docs/joomla/coverage + #-mkdir -p docs/joomla/pylint + #${NOSE_EXEC} $(NOSEOPTS) $(NOSECOVER) tests/ + #${NOSE_EXEC} $(NOSEOPTS) tests/ + #-cp docs/html/nosetests/* docs/joomla/nosetests + #-cp docs/html/coverage/* docs/joomla/coverage #-$(PYLINT) --output-format=html $(PYLINTOPTS) src-lib/libopenzwave/ src-api/openzwave/ src-manager/pyozwman/ src-web/pyozwweb/>docs/html/pylint/report.html - -cp docs/html/pylint/* docs/joomla/pylint/ + #-cp docs/html/pylint/* docs/joomla/pylint/ cd docs && $(MAKE) docs cp docs/README.rst README.rst cp docs/INSTALL_REPO.rst . @@ -206,16 +216,17 @@ docs: clean-docs cp docs/INSTALL_MAC.rst . cp docs/INSTALL_WIN.rst . cp docs/_build/text/COPYRIGHT.txt . + cp docs/_build/text/COPYRIGHT.txt LICENSE.txt cp docs/_build/text/CHANGELOG.txt . cp docs/_build/text/DEVEL.txt . cp docs/_build/text/EXAMPLES.txt . - cp -Rf docs/_build/html/* docs/html/ - cp -Rf docs/_build/joomla/* docs/joomla/ + #cp -Rf docs/_build/html/* docs/html/ + #cp -Rf docs/_build/joomla/* docs/joomla/ @echo @echo "Documentation finished." -install-lib: build - ${PYTHON_EXEC} setup-lib.py install +install-lib: + ${PYTHON_EXEC} setup-lib.py install --flavor=git @echo @echo "Installation of lib finished." @@ -234,22 +245,23 @@ install: install-manager @echo @echo "Installation for users finished." -develop: - ${PYTHON_EXEC} setup-lib.py develop +develop: src-lib/libopenzwave/libopenzwave.cpp + ${PYTHON_EXEC} setup-lib.py develop --flavor=dev ${PYTHON_EXEC} setup-api.py develop ${PYTHON_EXEC} setup-manager.py develop ${PYTHON_EXEC} setup-web.py develop + ${PYTHON_EXEC} setup.py develop --flavor=dev @echo - @echo "Installation for developpers of python-openzwave finished." + @echo "Installation for developers of python-openzwave finished." tests: - #export NOSESKIP=False && $(NOSE) $(NOSEOPTS) tests/ --with-progressive; unset NOSESKIP - export NOSESKIP=False && $(NOSE) $(NOSEOPTS) tests/lib tests/api tests/manager ; unset NOSESKIP + export NOSESKIP=False && ${NOSE_EXEC} $(NOSEOPTS) tests/; unset NOSESKIP +#~ export NOSESKIP=False && ${NOSE_EXEC} $(NOSEOPTS) tests/lib tests/api tests/manager ; unset NOSESKIP @echo @echo "Tests for ZWave network finished." autobuild-tests: - $(NOSE) $(NOSEOPTS) tests/lib/autobuild tests/api/autobuild + ${NOSE_EXEC} $(NOSEOPTS) tests/lib/autobuild tests/api/autobuild @echo @echo "Autobuild-tests for ZWave network finished." @@ -263,14 +275,22 @@ update: openzwave cd openzwave && git pull build: openzwave/.lib/ - ${PYTHON_EXEC} setup-lib.py build + ${PYTHON_EXEC} setup-lib.py build --flavor=dev + +src-lib/libopenzwave/libopenzwave.cpp: openzwave/.lib/ + ${PYTHON_EXEC} setup-lib.py build --flavor=dev openzwave: git clone git://github.com/OpenZWave/open-zwave.git openzwave +openzwave.gzip: + wget --no-check-certificate https://codeload.github.com/OpenZWave/open-zwave/zip/master + mv master open-zwave-master.zip + unzip open-zwave-master.zip + mv open-zwave-master openzwave + openzwave/.lib/: openzwave - #sed -i -e '253s/.*//' openzwave/cpp/src/value_classes/ValueID.h - cd openzwave && $(MAKE) + cd openzwave && $(MAKE) -j 4 clean-archive: -rm -rf $(ARCHBASE) @@ -322,35 +342,993 @@ tgz: clean-archive $(ARCHDIR) docs -mkdir -p $(DISTDIR) tar cvzf $(DISTDIR)/python-openzwave-${python_openzwave_version}.tgz -C $(ARCHBASE) ${ARCHNAME} rm -Rf $(ARCHBASE) - mv $(DISTDIR)/python-openzwave-${python_openzwave_version}.tgz $(ARCHIVES) - git add $(ARCHIVES)/python-openzwave-${python_openzwave_version}.tgz - git commit -m "Add new archive" $(ARCHIVES)/python-openzwave-${python_openzwave_version}.tgz + mv $(DISTDIR)/python-openzwave-${python_openzwave_version}.tgz $(ARCHIVES)/ @echo @echo "Archive for version ${python_openzwave_version} created" +embed_openzave_master:clean-archive src-lib/libopenzwave/libopenzwave.cpp + -rm -Rf $(ARCHBASE)/open-zwave-master + -mkdir -p $(ARCHBASE)/open-zwave-master/python-openzwave/src-lib/libopenzwave + cp -Rf openzwave/* $(ARCHBASE)/open-zwave-master/ + cp -f openzwave/cpp/src/vers.cpp $(ARCHBASE)/open-zwave-master/python-openzwave/openzwave.vers.cpp + cp -f src-lib/libopenzwave/libopenzwave.cpp $(ARCHBASE)/open-zwave-master/python-openzwave/src-lib/libopenzwave/ + -find $(ARCHBASE)/open-zwave-master -name \*.pyc -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name zwcfg_\*.xml -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name OZW_Log.log -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name OZW_Log.txt -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name ozwsh.log -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name errors.log -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name zwscene.xml -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name zwbutton.xml -delete 2>/dev/null || true + -find $(ARCHBASE)/open-zwave-master -name pyozw.db -delete 2>/dev/null || true + -cd $(ARCHBASE)/open-zwave-master && $(MAKE) clean + -rm -Rf $(ARCHBASE)/open-zwave-master/.git + -rm -f $(ARCHBASE)/open-zwave-master/open-zwave-master.zip + -rm -Rf $(ARCHBASE)/open-zwave-master/docs/* + -cp -f openzwave/docs/default.htm $(ARCHBASE)/open-zwave-master/docs/* + -rm -Rf $(ARCHBASE)/open-zwave-master/dotnet/* + cp -f $(ARCHBASE)/open-zwave-master/python-openzwave/openzwave.vers.cpp $(ARCHBASE)/open-zwave-master/cpp/src/vers.cpp + -mkdir -p $(DISTDIR) + cd $(ARCHBASE) && zip -r ../$(DISTDIR)/open-zwave-master-${python_openzwave_version}.zip open-zwave-master + mv $(DISTDIR)/open-zwave-master-${python_openzwave_version}.zip $(ARCHIVES)/ + @echo + @echo "embed_openzave_master for version ${python_openzwave_version} created" + +pypi_package:clean-archive + -rm -Rf $(ARCHBASE)/python_openzwave/ + ${PYTHON_EXEC} setup.py egg_info + -mkdir -p $(ARCHBASE)/python_openzwave/ + cp -Rf src-python_openzwave $(ARCHBASE)/python_openzwave/ + cp -Rf src-lib $(ARCHBASE)/python_openzwave/ + cp -Rf src-api $(ARCHBASE)/python_openzwave/ + cp -Rf src-manager $(ARCHBASE)/python_openzwave/ + cp -f setup.cfg $(ARCHBASE)/python_openzwave/ + cp -f setup.py $(ARCHBASE)/python_openzwave/ + cp -f pyozw_pkgconfig.py $(ARCHBASE)/python_openzwave/ + cp -f pyozw_setup.py $(ARCHBASE)/python_openzwave/ + cp -f pyozw_version.py $(ARCHBASE)/python_openzwave/ + cp -f pyozw_win.py $(ARCHBASE)/python_openzwave/ + cp -f pyozw_progressbar.py $(ARCHBASE)/python_openzwave/ + cp -f python_openzwave.egg-info/PKG-INFO $(ARCHBASE)/python_openzwave/ + -find $(ARCHBASE)/python_openzwave/ -name \*.pyc -delete 2>/dev/null || true + -find $(ARCHBASE)/python_openzwave/ -name \*.so -delete 2>/dev/null || true + -find $(ARCHBASE)/python_openzwave/ -type d -name \*.egg-info -exec rm -rf '{}' \; 2>/dev/null || true + -find $(ARCHBASE)/python_openzwave/ -name zwcfg_\*.xml -delete + -find $(ARCHBASE)/python_openzwave/ -name OZW_Log.log -delete + -find $(ARCHBASE)/python_openzwave/ -name OZW_Log.txt -delete + -find $(ARCHBASE)/python_openzwave/ -name ozwsh.log -delete + -find $(ARCHBASE)/python_openzwave/ -name errors.log -delete + -find $(ARCHBASE)/python_openzwave/ -name zwscene.xml -delete + -find $(ARCHBASE)/python_openzwave/ -name zwbutton.xml -delete + -find $(ARCHBASE)/python_openzwave/ -name pyozw.db -delete + -rm -f $(ARCHBASE)/python_openzwave/src-lib/libopenzwave/libopenzwave.cpp + -mkdir -p $(DISTDIR) || src-lib/ + cd $(ARCHBASE) && zip -r ../$(DISTDIR)/python_openzwave-${python_openzwave_version}.zip python_openzwave + mv $(DISTDIR)/python_openzwave-${python_openzwave_version}.zip $(ARCHIVES)/ + @echo + @echo "pypi_package for version ${python_openzwave_version} created" + push: develop -git commit -m "Auto-commit for docs" README.rst INSTALL_REPO.rst INSTALL_MAC.rst INSTALL_WIN.rst INSTALL_ARCH.rst COPYRIGHT.txt DEVEL.txt EXAMPLES.txt CHANGELOG.txt docs/ -git push @echo @echo "Commits for branch master pushed on github." -commit: push merge-python3 +commit: push @echo - @echo "Commits for branches master/python3 pushed on github." + @echo "Commits for branches master pushed on github." tag: - git tag v${python_openzwave_version} + -git tag v${python_openzwave_version} git push origin v${python_openzwave_version} @echo @echo "Tag pushed on github." -new-version: commit tgz tag commit - git push +validate-pr: uninstall clean update develop + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo + @echo + @echo "Tests to validate a PR" + @echo + @echo + + $(MAKE) venv-dev-autobuild-tests + $(MAKE) venv-bdist_wheel-whl-autobuild-tests + $(MAKE) venv-bdist_wheel-autobuild-tests +#~ $(MAKE) venv-tests + + @echo + @echo + @echo "Tests to validate a PR finished" + @echo + @echo + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo + +new-version: validate-pr + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo + @echo + @echo "Make a new version ${python_openzwave_version}" + @echo + @echo + + -$(MAKE) docs + -git commit -m "Auto-commit for new-version" README.rst INSTALL_REPO.rst INSTALL_MAC.rst INSTALL_WIN.rst INSTALL_ARCH.rst LICENSE.txt COPYRIGHT.txt DEVEL.txt EXAMPLES.txt CHANGELOG.txt docs/ + -git checkout $(ARCHIVES)/ + -git commit -m "Update pyozw_version to ${python_openzwave_version}" pyozw_version.py + $(MAKE) debch + -git commit -m "Update debian version to ${python_openzwave_version}" debian/ + -$(MAKE) embed_openzave_master + -$(MAKE) pypi_package + -git add $(ARCHIVES)/python_openzwave-${python_openzwave_version}.zip && git commit -m "Add new pypi package" $(ARCHIVES)/python_openzwave-${python_openzwave_version}.zip && git push + -git add $(ARCHIVES)/open-zwave-master-${python_openzwave_version}.zip && git commit -m "Add new embed package" $(ARCHIVES)/open-zwave-master-${python_openzwave_version}.zip && git push + -git checkout $(ARCHIVES)/* + -twine upload archives/python_openzwave-${python_openzwave_version}.zip -r pypitest + -twine upload archives/python_openzwave-${python_openzwave_version}.zip -r pypi + -$(MAKE) tag + sleep 60 + $(MAKE) venv-pypitest-autobuild-tests + $(MAKE) venv-pypilive-autobuild-tests + + @echo @echo @echo "New version ${python_openzwave_version} created and published" + @echo + @echo + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + @echo '////////////////////////////////////////////////////////////////////////////////////////////' + @echo debch: - dch --newversion ${python_openzwave_version} --maintmaint "Automatic release from upstream" + dch --newversion ${python_openzwave_version} --maintmaint "Automatic release from upstream. Look at CHANGELOG.txt" deb: dpkg-buildpackage + +venv-deps: common-deps + apt-get install --force-yes -y python-all python-dev python3-all python3-dev python-virtualenv python-pip +#~ apt-get install --force-yes -y python-wheel-common python3-wheel python-wheel python-pip-whl + apt-get install --force-yes -y pkg-config wget unzip zip + pip install Cython==0.28.6 + pip install wheel + +docker-deps: common-deps + apt-get install --force-yes -y python-all python-dev python3-all python3-dev python-virtualenv + apt-get install --force-yes -y python3-pip python-pip python-wheel python3-wheel python-pip-whl + apt-get install --force-yes -y wget unzip zip + apt-get install --force-yes -y g++ libudev-dev libyaml-dev + pip install Cython==0.28.6 + pip3 install Cython==0.28.6 + +venv2: + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo "New venv for python2" + @echo + + virtualenv --python=python2 venv2 + venv2/bin/python --version + venv2/bin/pip install nose + venv2/bin/pip install Cython==0.28.6 wheel six pyserial + venv2/bin/pip install 'Louie>=1.1' + chmod 755 venv2/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + + @echo + @echo "Venv for python2 created" + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + +venv3: + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo "New venv for python3" + @echo + + virtualenv --python=python3 venv3 + venv3/bin/python --version + venv3/bin/pip install nose + venv3/bin/pip install Cython==0.28.6 wheel six pyserial + venv3/bin/pip install 'PyDispatcher>=2.0.5' + chmod 755 venv3/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + + @echo + @echo "Venv for python3 created" + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + +venv2-dev: venv2 src-lib/libopenzwave/libopenzwave.cpp + venv2/bin/python setup-lib.py develop --flavor=dev + venv2/bin/python setup-api.py develop + venv2/bin/python setup-manager.py develop + +venv3-dev: venv3 src-lib/libopenzwave/libopenzwave.cpp + venv3/bin/python setup-lib.py develop --flavor=dev + venv3/bin/python setup-api.py develop + venv3/bin/python setup-manager.py develop + +venv2-install: venv2 src-lib/libopenzwave/libopenzwave.cpp + venv2/bin/python setup.py install --flavor=dev + +venv3-install: venv3 src-lib/libopenzwave/libopenzwave.cpp + venv3/bin/python setup.py install --flavor=dev + +venv2-shared: venv2 src-lib/libopenzwave/libopenzwave.cpp + venv2/bin/python setup-lib.py install --flavor=shared + venv2/bin/python setup-api.py install + venv2/bin/python setup-manager.py install + +venv3-shared: venv3 src-lib/libopenzwave/libopenzwave.cpp + venv3/bin/python setup-lib.py install --flavor=shared + venv3/bin/python setup-api.py install +#~ venv3/bin/python setup-manager.py install + +venv-clean: + @echo "Clean files in venvs" + -rm -rf venv2 + -rm -rf venv3 + -rm -f src-lib/libopenzwave/libopenzwave.cpp + +venv-tests: venv2-tests venv3-tests + +venv2-tests: venv2-dev + @echo ========================================================================================== + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -$(MAKE) PYTHON_EXEC=venv2/bin/python NOSE_EXEC=venv2/bin/nosetests tests + + @echo + @echo + @echo "Tests for venv2 done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv3-tests: venv3-dev + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -$(MAKE) PYTHON_EXEC=venv3/bin/python NOSE_EXEC=venv3/bin/nosetests tests + + @echo + @echo + @echo "Tests for venv3 done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-autobuild-tests: clean + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-autobuild-autobuild-tests." + @echo + @echo + + $(MAKE) venv-pypitest-autobuild-tests + $(MAKE) venv-pypilive-autobuild-tests + $(MAKE) venv-embed-autobuild-tests + $(MAKE) venv-bdist_wheel-whl-autobuild-tests + $(MAKE) venv-bdist_wheel-autobuild-tests + $(MAKE) venv-pypi-autobuild-tests + $(MAKE) venv-dev-autobuild-tests + $(MAKE) venv-git-autobuild-tests + + @echo + @echo + @echo "Tests for venv-autobuild-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-continuous-autobuild-tests: + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-continuous-autobuild-tests." + @echo + @echo + + -$(MAKE) venv-embed-autobuild-tests + -$(MAKE) venv-embed_shared-autobuild-tests + -$(MAKE) venv-git-autobuild-tests + -$(MAKE) venv-git_shared-autobuild-tests + -$(MAKE) venv-bdist_wheel-whl-autobuild-tests + -$(MAKE) venv-bdist_wheel-autobuild-tests + -$(MAKE) venv-pypi-autobuild-tests + + @echo + @echo + @echo "Tests for venv-continuous-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-git-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-git-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv2/bin/python setup-lib.py install --flavor=git + venv2/bin/python setup-api.py install + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + venv2/bin/python venv2/bin/pyozw_check + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(git-' + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv3/bin/python setup-lib.py install --flavor=git + venv3/bin/python setup-api.py install + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + venv3/bin/python venv3/bin/pyozw_check + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(git-' + + @echo + @echo + @echo "Tests for venv-git-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-pypitest-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-pypitest-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv2/bin/pip install "urwid>=1.1.1" + venv2/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(embed-' + venv2/bin/pip install "Cython" + venv2/bin/pip uninstall python_openzwave -y + venv2/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave --install-option="--flavor=git" + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave --force --install-option="--flavor=git" + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/python venv2/bin/pyozw_check + venv2/bin/python venv2/bin/pyozw_shell --help + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(git-' + venv2/bin/pip uninstall python_openzwave -y + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(embed-' + venv3/bin/pip install "Cython" + venv3/bin/pip uninstall python_openzwave -y + venv3/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave --install-option="--flavor=git" + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/pip install -i https://pypi.python.org/pypi -vvv python_openzwave --force --install-option="--flavor=git" + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/python venv3/bin/pyozw_check + venv3/bin/python venv3/bin/pyozw_shell --help + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(git-' + venv3/bin/pip uninstall python_openzwave -y + + -rm -f libopenzwave*.so + @echo + @echo "Tests for venv-pypitest-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-pypilive-autobuild-tests: venv-clean + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-pypilive-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -Rf venv2/ + virtualenv --python=python2 venv2 + chmod 755 venv2/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libopenzwave*.so + venv2/bin/pip install "urwid>=1.1.1" + venv2/bin/pip install "nose" + venv2/bin/pip install -vv python_openzwave + venv2/bin/python venv2/bin/pyozw_check -o raw + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(embed-' + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/pip install Cython==0.28.6 +#~ venv2/bin/pip install wheel + venv2/bin/pip uninstall python_openzwave -y + venv2/bin/pip install -vv python_openzwave --upgrade --install-option="--flavor=git" + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/python venv2/bin/pyozw_check -o raw + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(git-' + venv2/bin/pip uninstall python_openzwave -y + venv2/bin/pip install -vv python_openzwave --upgrade --install-option="--flavor=ozwdev" + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/python venv2/bin/pyozw_check -o raw + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(ozwdev-' + venv2/bin/pip uninstall python_openzwave -y + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -Rf venv3/ + virtualenv --python=python3 venv3 + chmod 755 venv3/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libop1enzwave*.so + venv3/bin/pip install "nose" + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip install -vv python_openzwave + venv3/bin/python venv3/bin/pyozw_check -o raw + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(embed-' + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/pip install Cython==0.28.6 +#~ venv3/bin/pip install wheel + venv3/bin/pip uninstall python_openzwave -y + venv3/bin/pip install -vv python_openzwave --upgrade --install-option="--flavor=git" + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/python venv3/bin/pyozw_check -o raw + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(git-' + venv3/bin/pip uninstall python_openzwave -y + venv3/bin/pip install -vv python_openzwave --upgrade --install-option="--flavor=ozwdev" + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv3/bin/python venv3/bin/pyozw_check -o raw + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(ozwdev-' + venv3/bin/pip uninstall python_openzwave -y + + -rm -f libopenzwave*.so + @echo + @echo "Tests for venv-pypilive-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-git_shared-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-git_shared-autobuild-tests." + @echo + @echo + + $(MAKE) uninstall + $(MAKE) uninstallso + -pkg-config --libs libopenzwave + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv2/bin/python setup-lib.py install --flavor=git_shared + venv2/bin/python setup-api.py install + venv2/bin/python setup-manager.py install + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + find /usr/local/etc/openzwave -iname device_classes.xml -type f -exec cat '{}' \;|grep open-zwave + test -f venv2/lib/python*/site-packages/libopenzwave*.so + venv2/bin/python venv2/bin/pyozw_check + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(git_shared-' + pkg-config --libs libopenzwave + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv3/bin/python setup-lib.py install --flavor=git_shared + venv3/bin/python setup-api.py install +#~ venv3/bin/python setup-manager.py install + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + find /usr/local/etc/openzwave -iname device_classes.xml -type f -exec cat '{}' \;|grep open-zwave + test -f venv3/lib/python*/site-packages/libopenzwave*.so + venv3/bin/python venv3/bin/pyozw_check + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(git_shared-' + pkg-config --libs libopenzwave + + @echo + @echo + @echo "Tests for venv-git-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-embed-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-embed-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv2/bin/pip uninstall -y wheel + venv2/bin/pip install "urwid>=1.1.1" + venv2/bin/pip uninstall -y Cython + venv2/bin/python setup.py install --flavor=embed + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + test -f venv2/lib/python*/site-packages/libopenzwave*.so + venv2/bin/python venv2/bin/pyozw_check + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(embed-' + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv3/bin/pip uninstall -y wheel + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip uninstall -y Cython + venv3/bin/python setup.py install --flavor=embed + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + test -f venv3/lib/python*/site-packages/libopenzwave*.so + venv3/bin/python venv3/bin/pyozw_check + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(embed-' + + -rm -f libopenzwave*.so + @echo + @echo + @echo "Tests for venv-embed-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-embed_shared-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-embed_shared-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv2/bin/pip install "urwid>=1.1.1" + venv2/bin/pip uninstall -y Cython + venv2/bin/python setup.py install --flavor=embed_shared + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + test -f venv2/lib/python*/site-packages/libopenzwave*.so + venv2/bin/python venv2/bin/pyozw_check + venv2/bin/python venv2/bin/pyozw_check -o raw|grep '(embed_shared-' + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip uninstall -y Cython + venv3/bin/python setup.py install --flavor=embed_shared + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + test -f venv3/lib/python*/site-packages/libopenzwave*.so + venv3/bin/python venv3/bin/pyozw_check + venv3/bin/python venv3/bin/pyozw_check -o raw|grep '(embed_shared-' + + -rm -f libopenzwave*.so + @echo + @echo + @echo "Tests for venv-embed-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-pypi-autobuild-tests: venv-clean pypi_package + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-pypi-autobuild-tests." + @echo + @echo + + -rm -f dist/*.whl + -rm -Rf tmp/pypi_test/ + -mkdir -p tmp/pypi_test/ + cd tmp/pypi_test/ && unzip ../../$(ARCHIVES)/python_openzwave-${python_openzwave_version}.zip + + virtualenv --python=python2 venv2 + chmod 755 venv2/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libopenzwave*.so + venv2/bin/pip install "wheel" + venv2/bin/pip install "urwid>=1.1.1" + venv2/bin/pip install "Cython" + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py install + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py bdist_wheel --flavor=git + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + virtualenv --python=python3 venv3 + chmod 755 venv3/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libop1enzwave*.so + venv3/bin/pip install "wheel" + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip install "Cython" + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py install + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py bdist_wheel --flavor=git + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + . venv3/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py bdist_wheel --flavor=git + + -mkdir -p dist + cp tmp/pypi_test/python_openzwave/dist/*.whl dist/ + + $(MAKE) venv-bdist_wheel-autobuild-tests + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py install --force --flavor=git + . venv2/bin/activate && python venv2/bin/pyozw_check + . venv2/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py clean --all --flavor=git + find venv2/lib/ -iname device_classes.xml -type f -print|cat + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + . venv3/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py install --force --flavor=git + . venv3/bin/activate && python venv3/bin/pyozw_check + . venv3/bin/activate && cd tmp/pypi_test/python_openzwave && python setup.py clean --all --flavor=git + find venv3/lib/ -iname device_classes.xml -type f -print|cat + + @echo + @echo + @echo "Tests for venv-pypi-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-bdist_wheel-whl-autobuild-tests: venv-clean venv2 venv3 + @echo ========================================================================================== + @echo + @echo + @echo "Create tests whl for venv-bdist_wheel-autobuild-tests." + @echo + @echo + + -rm -f dist/*.whl + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv2/bin/python setup.py install --flavor=git + venv2/bin/python setup.py bdist_wheel --flavor=git + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv3/bin/python setup.py install --flavor=git + venv3/bin/python setup.py bdist_wheel --flavor=git + + @echo + @echo + @echo "Tests for venv-bdist_wheel-autobuild-tests created." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-bdist_wheel-autobuild-tests: venv-clean + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-bdist_wheel-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -Rf venv2 + virtualenv --python=python2 venv2 + chmod 755 venv2/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libopenzwave*.so + + venv2/bin/pip install "wheel" + venv2/bin/pip install "nose" +#~ venv2/bin/pip install "Cython" + venv2/bin/pip install "urwid>=1.1.1" + + venv2/bin/pip install dist/python_openzwave-${python_openzwave_version}-cp2* + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + find venv2/lib/ -iname device_classes.xml -type f -exec cat '{}' \;|grep open-zwave + test -f venv2/lib/python*/site-packages/libopenzwave*.so + venv2/bin/pip uninstall -y "${WHL_PYTHON2}" + #test ! -f venv2/lib/python*/site-packages/libopenzwave*.so + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -Rf venv3 + virtualenv --python=python3 venv3 + chmod 755 venv3/bin/activate + -rm -f src-lib/libopenzwave/libopenzwave.cpp + -rm -f libopenzwave*.so + + venv2/bin/pip install "wheel" + venv3/bin/pip install "nose" +#~ venv3/bin/pip install "Cython" + venv3/bin/pip install "urwid>=1.1.1" + venv3/bin/pip install dist/python_openzwave-${python_openzwave_version}-cp3* + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + find venv3/lib/ -iname device_classes.xml -type f -exec cat '{}' \;|grep open-zwave + test -f venv3/lib/python*/site-packages/libopenzwave*.so + venv3/bin/pip uninstall -y "${WHL_PYTHON3}" + #test ! -f venv3/lib/python*/site-packages/libopenzwave*.so + + @echo + @echo + @echo "Tests for venv-bdist_wheel-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-dev-autobuild-tests: venv-clean venv2 venv3 src-lib/libopenzwave/libopenzwave.cpp + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-dev-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + #PIP like + venv2/bin/python2 -u -c "import setuptools, tokenize;__file__='setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/install-record.txt --single-version-externally-managed --compile --install-headers venv2/include/site/python2.7/python-openzwave "--flavor=git" + + rm -f src-lib/libopenzwave/libopenzwave.cpp + venv2/bin/python setup-lib.py install --flavor=dev + venv2/bin/python setup-api.py install + venv2/bin/python setup-manager.py install + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild tests/manager/autobuild + venv2/bin/python venv2/bin/pyozw_check + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + -rm -f libopenzwave*.so + + #PIP like + venv3/bin/python3 -u -c "import setuptools, tokenize;__file__='setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/install-record.txt --single-version-externally-managed --compile --install-headers venv3/include/site/python3.5/python-openzwave "--flavor=git" + + rm -f src-lib/libopenzwave/libopenzwave.cpp + venv3/bin/python setup-lib.py install --flavor=dev + venv3/bin/python setup-api.py install +#~ venv3/bin/python setup-manager.py install + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + venv3/bin/python venv3/bin/pyozw_check + + -rm -f libopenzwave*.so + @echo + @echo + @echo "Tests for venv-dev-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +venv-shared-autobuild-tests: venv-clean venv2-shared venv3-shared + @echo ========================================================================================== + @echo + @echo + @echo "Launch tests for venv-shared-autobuild-tests." + @echo + @echo + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python2 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv2/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + venv2/bin/python venv2/bin/pyozw_check + + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + @echo Tests for python3 + @echo + @echo //////////////////////////////////////////////////////////////////////////////////////////// + @echo + + venv3/bin/nosetests --verbose tests/lib/autobuild tests/api/autobuild + venv3/bin/python venv3/bin/pyozw_check + + @echo + @echo + @echo "Tests for venv-shared-autobuild-tests done." + @echo + @echo + @echo ========================================================================================== + @echo + +buildso: openzwave/.lib/ + cd openzwave && $(MAKE) install + +uninstallso: + rm -f /usr/local/lib/x86_64-linux-gnu/pkgconfig/libopenzwave.pc + rm -f /usr/local/lib64/libopenzwave.so.1.4 + rm -f /usr/local/lib64/libopenzwave.so + rm -Rf /usr/local/include/openzwave + rm -Rf /usr/local/etc/openzwave + rm -Rf /usr/local/share/doc/openzwave* + -find /usr/local/lib/pkgconfig/ -iname libopenzwave.pc -delete + +pyozw_pkgconfig.py: + wget https://raw.githubusercontent.com/matze/pkgconfig/master/pkgconfig/pkgconfig.py + mv pkgconfig.py pyozw_pkgconfig.py diff --git a/Makefile.archive b/Makefile.archive index ce559770..59789fa6 100644 --- a/Makefile.archive +++ b/Makefile.archive @@ -109,9 +109,9 @@ uninstall: -rm -Rf /usr/local/share/python-openzwave -rm -Rf /usr/local/share/openzwave -developper-deps: common-deps cython-deps tests-deps pip-deps doc-deps +developer-deps: common-deps cython-deps tests-deps pip-deps doc-deps @echo - @echo "Dependencies for developpers of python-openzwave installed (python ${python_version_full})" + @echo "Dependencies for developers of python-openzwave installed (python ${python_version_full})" autobuild-deps: common-deps cython-deps tests-deps pip-deps apt-get install --force-yes -y git diff --git a/README.rst b/README.rst index a32381c5..c4ae7c44 100755 --- a/README.rst +++ b/README.rst @@ -1,3 +1,23 @@ +.. image:: https://travis-ci.org/OpenZWave/python-openzwave.svg?branch=master + :target: https://travis-ci.org/OpenZWave/python-openzwave + :alt: Travis status + +.. image:: https://circleci.com/gh/OpenZWave/python-openzwave.png?style=shield + :target: https://circleci.com/gh/OpenZWave/python-openzwave + :alt: Circle status + +.. image:: https://ci.appveyor.com/api/projects/status/2ogl8tx7o3pqphc9?svg=true + :target: https://ci.appveyor.com/project/bibi21000/python-openzwave + :alt: Appveyor status + +.. image:: https://img.shields.io/pypi/format/python_openzwave.svg + :target: https://pypi.python.org/pypi/python_openzwave + :alt: Pypi format + +.. image:: https://img.shields.io/badge/Documentation-ok-brightgreen.svg?style=flat + :target: http://openzwave.github.io/python-openzwave/index.html + :alt: Documentation + ================ python-openzwave ================ @@ -10,15 +30,215 @@ python-openzwave is a python wrapper for the openzwave c++ library : https://git * a full-event webapp example : flask + socket.io + jquery * a suite of tests * many examples - -python-openzwave 0.3.0 is out !!! -================================= - -Look at CHANGELOG to see new features and release notes. - -Look at INSTALL_REPO to test it now. - -Look at INSTALL_ARCH to install from archive : no need to install cython anymore. + * `Full documentation `_ + +python-openzwave 0.4.x is here !!! +================================== + +- New installation process via pip + +- First, you need some build tools and libs. On ubuntu, you should use : + + .. code-block:: bash + + sudo apt-get install --force-yes -y make libudev-dev g++ libyaml-dev + +- Make your virtualenv and activate it : + + .. code-block:: bash + + virtualenv --python=python3 venv3 + source venv3/bin/activate + +- Install the default flavor : + + .. code-block:: bash + + (venvX) pip install python_openzwave + +- The previous command try to install python_openzwave with the flavor 'shared'. + If it can't find a precompiled library of openzwave, it will use the flavor 'embed' with sources downloaded from https://github.com/OpenZWave/python-openzwave/tree/master/archives. + You can change this using flavor option. + There is a bug in the package dependencies and flavors on some systems. You may need to install dependencies manualy : + + - on python 2.7 : + + .. code-block:: bash + + (venvX) pip install cython wheel six pyserial + (venvX) pip install 'Louie>=1.1' + + - on python 3 : + + .. code-block:: bash + + (venvX) pip install cython wheel six pyserial + (venvX) pip install 'PyDispatcher>=2.0.5' + +- Choose your flavor : + + - embed : the default one. Download sources from https://github.com/OpenZWave/python-openzwave/tree/master/archives and + build them. Python_openzwave is statically build using a cythonized version of libopenzwave. No need to install cython. + - shared : if you have install openzwave as module manually, you can link python_openzwave to it. + - git : download sources from openzwave github and link statically to it. + - embed_shared : download sources from https://github.com/OpenZWave/python-openzwave/tree/master/archives, build and install as module on the system. + Python_openzwave use it. Need root access to install openzwave libs. + - git_shared : download sources from openzwave github, build and install them as module on the system. + Python_openzwave use it. Need root access to install openzwave libs. + - ozwdev and ozwdev_shared : use the dev branch of openzwave on github. + - dev : for python_openzwave developers. Look for openzwave sources in a local folder specified by the LOCAL_OPENZWAVE environment variable (defaults to 'openzwave'). + +- Install it : + + .. code-block:: bash + + (venvX) pip install python_openzwave --no-deps --install-option="--flavor=git" + +- You can update to the last version of openzwave using the git flavor : + + .. code-block:: bash + + (venvX) pip uninstall -y python_openzwave + (venvX) pip install python_openzwave --no-cache-dir --no-deps --install-option="--flavor=git" + + +- At last, you can launch pyozw_check to test your installation : + + If no usb stick is connected to the machine, launch : + + .. code-block:: bash + + (venvX) pyozw_check + + If you've one, use it for advanced checks : + + .. code-block:: bash + + (venvX) pyozw_check -i -d /dev/ttyUSB0 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Import libs + Try to import libopenzwave + Try to import libopenzwave.PyLogLevels + Try to get options + Try to get manager + Try to get python_openzwave version + 0.4.0.27 + Try to get python_openzwave full version + python-openzwave version 0.4.0.27 (dev / Apr 18 2017 - 23:22:26) + Try to get openzwave version + 1.4.2501 + Try to get default config path + /etc/openzwave/ + Try to import openzwave (API) + ------------------------------------------------------------------------------- + Intialize device /dev/ttyUSB0 + Try to get options + Try to get manager + 2017-04-12 16:41:29.329 Always, OpenZwave Version 1.4.2497 Starting Up + Try to add watcher + ... + 2017-04-12 16:44:05.880 Always, *************************************************************************** + 2017-04-12 16:44:05.880 Always, ********************* Cumulative Network Statistics ********************* + 2017-04-12 16:44:05.880 Always, *** General + 2017-04-12 16:44:05.880 Always, Driver run time: . . . 0 days, 0 hours, 1 minutes + 2017-04-12 16:44:05.880 Always, Frames processed: . . . . . . . . . . . . . . . . . . . . 27 + 2017-04-12 16:44:05.880 Always, Total messages successfully received: . . . . . . . . . . 27 + 2017-04-12 16:44:05.880 Always, Total Messages successfully sent: . . . . . . . . . . . . 19 + 2017-04-12 16:44:05.880 Always, ACKs received from controller: . . . . . . . . . . . . . 19 + 2017-04-12 16:44:05.880 Always, *** Errors + 2017-04-12 16:44:05.880 Always, Unsolicited messages received while waiting for ACK: . . 0 + 2017-04-12 16:44:05.880 Always, Reads aborted due to timeouts: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Bad checksum errors: . . . . . . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, CANs received from controller: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, NAKs received from controller: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Out of frame data flow errors: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Messages retransmitted: . . . . . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Messages dropped and not delivered: . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, *************************************************************************** + 2017-04-12 16:44:07.887 Info, mgr, Driver for controller /dev/ttyUSB0 removed + Try to remove watcher + Try to destroy manager + Try to destroy options + + You can list the nodes on your network using : + + .. code-block:: bash + + (venvX) pyozw_check -l -d /dev/ttyUSB0 -t 60 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Define options for device /dev/ttyUSB0 + Start network + Wait for network (30s) + Network is ready + ------------------------------------------------------------------------------- + Controller capabilities : {'primaryController', 'staticUpdateController'} + Controller node capabilities : {'listening', 'primaryController', 'staticUpdateController', 'beaming'} + Nodes in network : 4 + Driver statistics : {'noack': 6, 'routedbusy': 0, 'readCnt': 115, 'ACKWaiting': 0, 'badChecksum': 0, 'broadcastReadCnt': 0, 'NAKCnt': 0, 'broadcastWriteCnt': 9, 'dropped': 0, 'CANCnt': 0, 'callbacks': 0, 'OOFCnt': 0, 'readAborts': 0, 'badroutes': 0, 'SOFCnt': 115, 'netbusy': 0, 'writeCnt': 49, 'nondelivery': 0, 'ACKCnt': 49, 'retries': 0} + ------------------------------------------------------------ + 1 - Name : ( Location : ) + 1 - Ready : True / Awake : True / Failed : False + 1 - Manufacturer : Aeotec ( id : 0x0086 ) + 1 - Product : DSA02203 Z-Stick S2 ( id : 0x0001 / type : 0x0002 ) + 1 - Version : 3 / Secured : False / Zwave+ : False + 1 - Command classes : {'COMMAND_CLASS_NO_OPERATION', 'COMMAND_CLASS_BASIC'} + 1 - Capabilities : {'staticUpdateController', 'listening', 'primaryController', 'beaming'} + 1 - Neigbors : {4} / Power level : None + 1 - Is sleeping : False / Can wake-up : False / Battery level : None + + ... + + ------------------------------------------------------------ + 4 - Name : ( Location : ) + 4 - Ready : True / Awake : True / Failed : False + 4 - Manufacturer : GreenWave ( id : 0x0099 ) + 4 - Product : PowerNode 6 port ( id : 0x0004 / type : 0x0003 ) + 4 - Version : 4 / Secured : False / Zwave+ : False + 4 - Command classes : {'COMMAND_CLASS_BASIC', 'COMMAND_CLASS_CONFIGURATION', 'COMMAND_CLASS_SWITCH_BINARY', 'COMMAND_CLASS_VERSION', 'COMMAND_CLASS_CRC_16_ENCAP', 'COMMAND_CLASS_MANUFACTURER_SPECIFIC', 'COMMAND_CLASS_ASSOCIATION', 'COMMAND_CLASS_MULTI_INSTANCE/CHANNEL', 'COMMAND_CLASS_METER', 'COMMAND_CLASS_PROTECTION', 'COMMAND_CLASS_NO_OPERATION', 'COMMAND_CLASS_SWITCH_ALL'} + 4 - Capabilities : {'listening', 'routing', 'beaming'} + 4 - Neigbors : {1} / Power level : None + 4 - Is sleeping : False / Can wake-up : False / Battery level : None + + ... + + + - The old manager is now available via the pyozw_shell command. You need to install module "urwid>=1.1.1" with pip before using it. + + - libopenzwave and openzwave python modules are packaged in the python_openzwave. + So developers needs to update their install_requires (it works fine with pyozw_manager). + They can use the following code to update softly : + + .. code-block:: python + + pyozw_version='0.4.1' + + def install_requires(): + try: + import python_openzwave + return ['python_openzwave==%s' % pyozw_version] + except ImportError: + pass + try: + import libopenzwave + return ['openzwave==%s' % pyozw_version] + except ImportError: + pass + return ['python_openzwave == %s' % pyozw_version] + + + - If you already have an 0.3.x version installed, you should update your installation as usual. Don't install it with pip as it can break your installation (maybe not if you don't remove old modules) + + - Support for windows, macosx, ... is not tested. Feel free to report bug and patches. We can try to support these plateforms. Don't have Windows at home so I can't help. Same for mac. + + - Old installation process is deprecated and reserved for python-openzwave-developers and alternatives machines. + + - Please report your successful installations here : https://github.com/OpenZWave/python-openzwave/issues/73 Support ======= @@ -30,86 +250,3 @@ Pull requests ============= Please read DEVEL documentation before submitting pull request. A lot of project tasks are done automatically or with makefile, so they must be done in a certain place or in a special order. - -Migrating from python-openzwave 0.2.X to 0.3.0 -============================================== -I need to update source tree of python-openzwave and modules's names because of a bug in setuptools : https://bitbucket.org/pypa/setuptools/issue/230/develop-mode-does-not-respect-src . -Sorry for that. - -Update your sources: - -.. code-block:: bash - - git pull - -Before building python-openzwave 0.3.0, you must uninstall the old version : - -.. code-block:: bash - - sudo make uninstall - -About cython : I've made many tests using cython installed via pip : (0.20, 0.21 and 0.22). -Compilation is ok but a segfault appears when launching the tests. Please remove it. - -.. code-block:: bash - - sudo pip uninstall Cython - -You also need to make some minor updates in you code, look at CHANGELOG - -If you have problems, please submit an issue with : - - - cython -V - - the content of the directory /usr/local/lib/python2.7/dist-packages/ (for python2.7) - - the content of /usr/local/lib/python2.7/dist-packages/easy-install.pth (for python 2.7) - - -Ubuntu 64bits ... and the others -================================ - -If you're using Ubuntu 64 bits (and mayde others) and keep your distribution up to date, -you certainly have the segfault problem. - -Ubuntu 12.04 and 14.04 seems to be affected by this bug. Ubuntu 15.10 and Debian Jessie not. - -It appears with the last update of python : - -.. code-block:: bash - - $ python - Python 2.7.6 (default, Jun 22 2015, 17:58:13) - [GCC 4.8.2] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - - -I've open a discussion on cython-users here : https://groups.google.com/forum/#!topic/cython-users/mRsviGuCFOk - -The only way I found to avoid this is to rebuild and reinstall the old release of python : - -.. code-block:: bash - - wget https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6-8.dsc https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6.orig.tar.gz https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6-8.diff.gz - - dpkg-source -x python2.7_2.7.6-8.dsc - - sudo apt-get build-dep python2.7 - - cd python2.7-2.7.6 - - dpkg-buildpackage - -Wait, wait and await again :) - -.. code-block:: bash - - cd .. - - sudo dpkg -i *.deb - -To prevent future updates of python, you could mark its packages. For example, if you use apt to update your distribution, use the following command : - -.. code-block:: bash - - sudo apt-mark hold idle-python2.7 libpython2.7-minimal python2.7-dbg python2.7-minimal libpython2.7 libpython2.7-stdlib python2.7-dev libpython2.7-dbg libpython2.7-testsuite python2.7-doc libpython2.7-dev python2.7 python2.7-examples - -Some users have reported that building python-openzwave using the archive (INSTALL_ARCH) can also do the trick. Let me know if it works for you. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..0dfab890 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,140 @@ +environment: + PYPI_USER: + secure: yna6KiH2GE3Ka1G5a3TlUQ== + PYPI_PASSWORD: + secure: UpISOsYyHdCzurReV6FcTA== + + global: + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script intepreter + # See: http://stackoverflow.com/a/13751649/163740 + CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" + + matrix: + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python36" + PYTHON_VERSION: "3.6.x" + PYTHON_ARCH: "32" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python36-x64" + PYTHON_VERSION: "3.6.x" + PYTHON_ARCH: "64" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python27" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "32" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python27-x64" + PYTHON_VERSION: "2.7.x" + PYTHON_ARCH: "64" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python34" + PYTHON_VERSION: "3.4.x" + PYTHON_ARCH: "32" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python34-x64" + PYTHON_VERSION: "3.4.x" + PYTHON_ARCH: "64" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python37" + PYTHON_VERSION: "3.7.x" + PYTHON_ARCH: "32" + + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PYTHON: "C:\\Python37-x64" + PYTHON_VERSION: "3.7.x" + PYTHON_ARCH: "64" + +deploy: + - provider: Environment + name: production + on: + APPVEYOR_REPO_TAG: true + +install: + # If there is a newer build queued for the same PR, cancel this one. + # The AppVeyor 'rollout builds' option is supposed to serve the same + # purpose but it is problematic because it tends to cancel builds pushed + # directly to master instead of just PR builds (or the converse). + # credits: JuliaLang developers. + - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` + https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` + Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` + throw "There are newer queued builds for this pull request, failing early." } + - ECHO "Filesystem root:" + - ps: "ls \"C:/\"" + + #~ - ECHO "Installed SDKs:" + #~ - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" + + - ECHO "Installed prgrams:" + - ps: "ls \"C:/Program Files/\"" + - ps: "ls \"C:/Program Files (x86)/\"" + - ps: "ls \"C:/Program Files (x86)/MSBuild/\"" + - ps: "ls \"C:/Program Files (x86)/Windows Kits/\"" + + # Prepend newly installed Python to the PATH of this build (this cannot be + # done from inside the powershell script as it would require to restart + # the parent CMD process). + - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + + # Check that we have the expected version and architecture for Python + - "python --version" + - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" + + # Upgrade to the latest version of pip to avoid it displaying warnings + # about it being out of date. + - "python -m pip install --disable-pip-version-check --user --upgrade pip" + + # Install the build dependencies of the project. If some dependencies contain + # compiled extensions and are not provided as pre-built wheel packages, + # pip will build them from source using the MSVC compiler matching the + # target Python version and architecture + # - "%CMD_IN_ENV% pip install Cython six" + - "python -m pip install wheel" + - "python -m pip install pyserial" + - "python -m pip install Cython six" + - "python -m pip install nose" + - "python -m pip install twine" + + - ps: Write-Host "PYTHON_VERSION $env:PYTHON_VERSION" + + - cmd: IF "%PYTHON_VERSION%" == "2.7.x" ( python -m pip install Louie ) ELSE ( python -m pip install PyDispatcher ) + + - git clone git://github.com/OpenZWave/open-zwave.git C:\projects\python-openzwave\openzwave + +build_script: + # Build the compiled extension + # "python pyozw_win.py" + - "python setup.py install --flavor=dev" + +test_script: + # Run the project tests + - "pyozw_check" + - "nosetests --verbose tests/lib/autobuild tests/api/autobuild" + +after_test: + # If tests are successful, create binary packages for the project. + - python setup.py bdist_wheel --flavor=dev + #~ - "python setup.py bdist_wininst" + #~ - "%CMD_IN_ENV% python setup.py bdist_msi" + - ps: "ls dist" + +artifacts: + # Archive the generated packages in the ci.appveyor.com build report. + - path: dist/* + name: windowswheels + +deploy_script: + # upload to pypi for Windows + - cmd: IF "%APPVEYOR_REPO_TAG%" == "true" (echo "Uploading wheels") + - cmd: IF "%APPVEYOR_REPO_TAG%" == "true" (set HOME=%USERPROFILE%) + - cmd: IF "%APPVEYOR_REPO_TAG%" == "true" (twine upload dist/*.whl --repository-url https://upload.pypi.org/legacy/ -u %PYPI_USER% -p %PYPI_PASSWORD%) + - cmd: IF "%APPVEYOR_REPO_TAG%" == "true" (echo "Finished Artifact Deployment" ) diff --git a/archives/open-zwave-master-0.4.0.27.zip b/archives/open-zwave-master-0.4.0.27.zip new file mode 100644 index 00000000..5263c90b Binary files /dev/null and b/archives/open-zwave-master-0.4.0.27.zip differ diff --git a/archives/open-zwave-master-0.4.0.28.zip b/archives/open-zwave-master-0.4.0.28.zip new file mode 100644 index 00000000..00f1b9bd Binary files /dev/null and b/archives/open-zwave-master-0.4.0.28.zip differ diff --git a/archives/open-zwave-master-0.4.0.29.zip b/archives/open-zwave-master-0.4.0.29.zip new file mode 100644 index 00000000..b1184588 Binary files /dev/null and b/archives/open-zwave-master-0.4.0.29.zip differ diff --git a/archives/open-zwave-master-0.4.0.30.zip b/archives/open-zwave-master-0.4.0.30.zip new file mode 100644 index 00000000..7a8922c5 Binary files /dev/null and b/archives/open-zwave-master-0.4.0.30.zip differ diff --git a/archives/open-zwave-master-0.4.0.31.zip b/archives/open-zwave-master-0.4.0.31.zip new file mode 100644 index 00000000..8854927c Binary files /dev/null and b/archives/open-zwave-master-0.4.0.31.zip differ diff --git a/archives/open-zwave-master-0.4.0.32.zip b/archives/open-zwave-master-0.4.0.32.zip new file mode 100644 index 00000000..9f3e01b6 Binary files /dev/null and b/archives/open-zwave-master-0.4.0.32.zip differ diff --git a/archives/open-zwave-master-0.4.0.33.zip b/archives/open-zwave-master-0.4.0.33.zip new file mode 100644 index 00000000..6c851ab4 Binary files /dev/null and b/archives/open-zwave-master-0.4.0.33.zip differ diff --git a/archives/open-zwave-master-0.4.0.34.zip b/archives/open-zwave-master-0.4.0.34.zip new file mode 100644 index 00000000..fdf798ec Binary files /dev/null and b/archives/open-zwave-master-0.4.0.34.zip differ diff --git a/archives/open-zwave-master-0.4.0.35.zip b/archives/open-zwave-master-0.4.0.35.zip new file mode 100644 index 00000000..f56a9ca4 Binary files /dev/null and b/archives/open-zwave-master-0.4.0.35.zip differ diff --git a/archives/open-zwave-master-0.4.1.zip b/archives/open-zwave-master-0.4.1.zip new file mode 100644 index 00000000..676c2903 Binary files /dev/null and b/archives/open-zwave-master-0.4.1.zip differ diff --git a/archives/open-zwave-master-0.4.10.zip b/archives/open-zwave-master-0.4.10.zip new file mode 100644 index 00000000..9b9898ad Binary files /dev/null and b/archives/open-zwave-master-0.4.10.zip differ diff --git a/archives/open-zwave-master-0.4.11.zip b/archives/open-zwave-master-0.4.11.zip new file mode 100644 index 00000000..2247bde9 Binary files /dev/null and b/archives/open-zwave-master-0.4.11.zip differ diff --git a/archives/open-zwave-master-0.4.14.zip b/archives/open-zwave-master-0.4.14.zip new file mode 100644 index 00000000..b84d0d8b Binary files /dev/null and b/archives/open-zwave-master-0.4.14.zip differ diff --git a/archives/open-zwave-master-0.4.15.zip b/archives/open-zwave-master-0.4.15.zip new file mode 100644 index 00000000..12e55244 Binary files /dev/null and b/archives/open-zwave-master-0.4.15.zip differ diff --git a/archives/open-zwave-master-0.4.16.zip b/archives/open-zwave-master-0.4.16.zip new file mode 100644 index 00000000..670b7f68 Binary files /dev/null and b/archives/open-zwave-master-0.4.16.zip differ diff --git a/archives/open-zwave-master-0.4.17.zip b/archives/open-zwave-master-0.4.17.zip new file mode 100644 index 00000000..ffa36699 Binary files /dev/null and b/archives/open-zwave-master-0.4.17.zip differ diff --git a/archives/open-zwave-master-0.4.18.zip b/archives/open-zwave-master-0.4.18.zip new file mode 100644 index 00000000..9897a92f Binary files /dev/null and b/archives/open-zwave-master-0.4.18.zip differ diff --git a/archives/open-zwave-master-0.4.19.zip b/archives/open-zwave-master-0.4.19.zip new file mode 100644 index 00000000..62b61c1d Binary files /dev/null and b/archives/open-zwave-master-0.4.19.zip differ diff --git a/archives/open-zwave-master-0.4.2.zip b/archives/open-zwave-master-0.4.2.zip new file mode 100644 index 00000000..14c251aa Binary files /dev/null and b/archives/open-zwave-master-0.4.2.zip differ diff --git a/archives/open-zwave-master-0.4.3.zip b/archives/open-zwave-master-0.4.3.zip new file mode 100644 index 00000000..9e3568d8 Binary files /dev/null and b/archives/open-zwave-master-0.4.3.zip differ diff --git a/archives/open-zwave-master-0.4.4.zip b/archives/open-zwave-master-0.4.4.zip new file mode 100644 index 00000000..826ac8e3 Binary files /dev/null and b/archives/open-zwave-master-0.4.4.zip differ diff --git a/archives/open-zwave-master-0.4.5.zip b/archives/open-zwave-master-0.4.5.zip new file mode 100644 index 00000000..c9a94777 Binary files /dev/null and b/archives/open-zwave-master-0.4.5.zip differ diff --git a/archives/open-zwave-master-0.4.6.zip b/archives/open-zwave-master-0.4.6.zip new file mode 100644 index 00000000..c26caf17 Binary files /dev/null and b/archives/open-zwave-master-0.4.6.zip differ diff --git a/archives/open-zwave-master-0.4.7.zip b/archives/open-zwave-master-0.4.7.zip new file mode 100644 index 00000000..10e0a163 Binary files /dev/null and b/archives/open-zwave-master-0.4.7.zip differ diff --git a/archives/open-zwave-master-0.4.8.zip b/archives/open-zwave-master-0.4.8.zip new file mode 100644 index 00000000..f5d3cb1e Binary files /dev/null and b/archives/open-zwave-master-0.4.8.zip differ diff --git a/archives/open-zwave-master-0.4.9.zip b/archives/open-zwave-master-0.4.9.zip new file mode 100644 index 00000000..f8899041 Binary files /dev/null and b/archives/open-zwave-master-0.4.9.zip differ diff --git a/archives/python-openzwave-0.3.0.tgz b/archives/python-openzwave-0.3.0.tgz deleted file mode 100644 index 9f7696e2..00000000 Binary files a/archives/python-openzwave-0.3.0.tgz and /dev/null differ diff --git a/archives/python-openzwave-0.3.0b8.tgz b/archives/python-openzwave-0.3.0b8.tgz deleted file mode 100644 index e6a7e54d..00000000 Binary files a/archives/python-openzwave-0.3.0b8.tgz and /dev/null differ diff --git a/archives/python-openzwave-0.3.1.tgz b/archives/python-openzwave-0.3.1.tgz deleted file mode 100644 index 8236b29a..00000000 Binary files a/archives/python-openzwave-0.3.1.tgz and /dev/null differ diff --git a/archives/python-openzwave-0.3.2.tgz b/archives/python-openzwave-0.3.2.tgz new file mode 100644 index 00000000..82a96ec4 Binary files /dev/null and b/archives/python-openzwave-0.3.2.tgz differ diff --git a/archives/python-openzwave-0.3.3.tgz b/archives/python-openzwave-0.3.3.tgz new file mode 100644 index 00000000..f5ad69fb Binary files /dev/null and b/archives/python-openzwave-0.3.3.tgz differ diff --git a/archives/python_openzwave-0.4.0.27.zip b/archives/python_openzwave-0.4.0.27.zip new file mode 100644 index 00000000..c1928219 Binary files /dev/null and b/archives/python_openzwave-0.4.0.27.zip differ diff --git a/archives/python_openzwave-0.4.0.28.zip b/archives/python_openzwave-0.4.0.28.zip new file mode 100644 index 00000000..41b2ac22 Binary files /dev/null and b/archives/python_openzwave-0.4.0.28.zip differ diff --git a/archives/python_openzwave-0.4.0.29.zip b/archives/python_openzwave-0.4.0.29.zip new file mode 100644 index 00000000..6f0c8a0f Binary files /dev/null and b/archives/python_openzwave-0.4.0.29.zip differ diff --git a/archives/python_openzwave-0.4.0.30.zip b/archives/python_openzwave-0.4.0.30.zip new file mode 100644 index 00000000..1750bcc5 Binary files /dev/null and b/archives/python_openzwave-0.4.0.30.zip differ diff --git a/archives/python_openzwave-0.4.0.31.zip b/archives/python_openzwave-0.4.0.31.zip new file mode 100644 index 00000000..ff002623 Binary files /dev/null and b/archives/python_openzwave-0.4.0.31.zip differ diff --git a/archives/python_openzwave-0.4.0.32.zip b/archives/python_openzwave-0.4.0.32.zip new file mode 100644 index 00000000..5e9e4b68 Binary files /dev/null and b/archives/python_openzwave-0.4.0.32.zip differ diff --git a/archives/python_openzwave-0.4.0.33.zip b/archives/python_openzwave-0.4.0.33.zip new file mode 100644 index 00000000..21013607 Binary files /dev/null and b/archives/python_openzwave-0.4.0.33.zip differ diff --git a/archives/python_openzwave-0.4.0.34.zip b/archives/python_openzwave-0.4.0.34.zip new file mode 100644 index 00000000..f4a5a89a Binary files /dev/null and b/archives/python_openzwave-0.4.0.34.zip differ diff --git a/archives/python_openzwave-0.4.0.35.zip b/archives/python_openzwave-0.4.0.35.zip new file mode 100644 index 00000000..1d1cb64b Binary files /dev/null and b/archives/python_openzwave-0.4.0.35.zip differ diff --git a/archives/python_openzwave-0.4.1.zip b/archives/python_openzwave-0.4.1.zip new file mode 100644 index 00000000..a2925d22 Binary files /dev/null and b/archives/python_openzwave-0.4.1.zip differ diff --git a/archives/python_openzwave-0.4.10.zip b/archives/python_openzwave-0.4.10.zip new file mode 100644 index 00000000..7762b7ff Binary files /dev/null and b/archives/python_openzwave-0.4.10.zip differ diff --git a/archives/python_openzwave-0.4.11.zip b/archives/python_openzwave-0.4.11.zip new file mode 100644 index 00000000..9ab4b224 Binary files /dev/null and b/archives/python_openzwave-0.4.11.zip differ diff --git a/archives/python_openzwave-0.4.14.zip b/archives/python_openzwave-0.4.14.zip new file mode 100644 index 00000000..31798f3d Binary files /dev/null and b/archives/python_openzwave-0.4.14.zip differ diff --git a/archives/python_openzwave-0.4.15.zip b/archives/python_openzwave-0.4.15.zip new file mode 100644 index 00000000..d341a2e2 Binary files /dev/null and b/archives/python_openzwave-0.4.15.zip differ diff --git a/archives/python_openzwave-0.4.16.zip b/archives/python_openzwave-0.4.16.zip new file mode 100644 index 00000000..c08369f2 Binary files /dev/null and b/archives/python_openzwave-0.4.16.zip differ diff --git a/archives/python_openzwave-0.4.17.zip b/archives/python_openzwave-0.4.17.zip new file mode 100644 index 00000000..f1008c65 Binary files /dev/null and b/archives/python_openzwave-0.4.17.zip differ diff --git a/archives/python_openzwave-0.4.18.zip b/archives/python_openzwave-0.4.18.zip new file mode 100644 index 00000000..4dafdcfd Binary files /dev/null and b/archives/python_openzwave-0.4.18.zip differ diff --git a/archives/python_openzwave-0.4.19.zip b/archives/python_openzwave-0.4.19.zip new file mode 100644 index 00000000..0c9cafef Binary files /dev/null and b/archives/python_openzwave-0.4.19.zip differ diff --git a/archives/python_openzwave-0.4.2.zip b/archives/python_openzwave-0.4.2.zip new file mode 100644 index 00000000..f79ae946 Binary files /dev/null and b/archives/python_openzwave-0.4.2.zip differ diff --git a/archives/python_openzwave-0.4.3.zip b/archives/python_openzwave-0.4.3.zip new file mode 100644 index 00000000..dc37d2e6 Binary files /dev/null and b/archives/python_openzwave-0.4.3.zip differ diff --git a/archives/python_openzwave-0.4.4.zip b/archives/python_openzwave-0.4.4.zip new file mode 100644 index 00000000..ec98edc5 Binary files /dev/null and b/archives/python_openzwave-0.4.4.zip differ diff --git a/archives/python_openzwave-0.4.5.zip b/archives/python_openzwave-0.4.5.zip new file mode 100644 index 00000000..db6317d6 Binary files /dev/null and b/archives/python_openzwave-0.4.5.zip differ diff --git a/archives/python_openzwave-0.4.6.zip b/archives/python_openzwave-0.4.6.zip new file mode 100644 index 00000000..9c6fa0f8 Binary files /dev/null and b/archives/python_openzwave-0.4.6.zip differ diff --git a/archives/python_openzwave-0.4.7.zip b/archives/python_openzwave-0.4.7.zip new file mode 100644 index 00000000..e0c43de7 Binary files /dev/null and b/archives/python_openzwave-0.4.7.zip differ diff --git a/archives/python_openzwave-0.4.8.zip b/archives/python_openzwave-0.4.8.zip new file mode 100644 index 00000000..26d47a4c Binary files /dev/null and b/archives/python_openzwave-0.4.8.zip differ diff --git a/archives/python_openzwave-0.4.9.zip b/archives/python_openzwave-0.4.9.zip new file mode 100644 index 00000000..51918e6a Binary files /dev/null and b/archives/python_openzwave-0.4.9.zip differ diff --git a/circle.yml b/circle.yml index 410a0227..a375e575 100644 --- a/circle.yml +++ b/circle.yml @@ -5,14 +5,17 @@ # For circle.yml explanation, see: https://circleci.com/docs/manually # Python specific configuration, see: https://circleci.com/docs/language-python ##### +machine: + python: + version: 2.7.6 + version: 3.5.3 + version: pypy-2.3.1 dependencies: - pre: + override: - sudo apt-get update - - sudo make python-deps - - sudo make autobuild-deps - - make update - - make build - - sudo make install + - sudo make ci-deps + - make openzwave.gzip + - echo "Don't need to install setup.py" test: override: - - make autobuild-tests + - make venv-continuous-autobuild-tests diff --git a/debian/changelog b/debian/changelog index 61bfaf76..8744ed4c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,36 @@ +python-openzwave (0.4.19) UNRELEASED; urgency=medium + + * Try to fix + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + * Automatic release from upstream. Look at CHANGELOG.txt + + -- bibi21000 Wed, 20 Mar 2019 10:57:44 +0100 + python-openzwave (0.3.0b8) UNRELEASED; urgency=medium * Automatic release from upstream diff --git a/debian/control b/debian/control index b34efcf9..82b3dd09 100755 --- a/debian/control +++ b/debian/control @@ -2,53 +2,33 @@ Source: python-openzwave Section: python Priority: optional Maintainer: Sébastien GALLET +Build-Depends: debhelper (>= 9), dh-python, + python-all (>=2.6.6-3~), python-setuptools, python-pip, + python3-all (>=3.2), python3-setuptools, python3-pip, + cython, cython3, build-essential, + python-docutils, python-sphinx, + libopenzwave1.4-dev | libopenzwave1.3-dev +Standards-Version: 3.9.5 X-Python-Version: >= 2.7 -Build-Depends: debhelper (>= 7.0.50~), python (>= 2.6.6-3~), python-setuptools, - python-dev, cython, build-essential, libopenzwave1.0-dev|libopenzwave1.3-dev -Build-Depends-Indep: debhelper (>= 7.0.50~), python (>= 2.6.6-3~), python-setuptools, - python-dev, python-pygraphviz, python-louie, sphinx-common, - python-sphinxcontrib.actdiag, python-sphinxcontrib.blockdiag, - python-sphinxcontrib.nwdiag, python-sphinxcontrib.seqdiag -Standards-Version: 3.9.1 +X-Python3-Version: >= 3.2 +XS-Python-Version: >= 2.7 +XS-Python3-Version: >= 3.2 Homepage: https://github.com/OpenZWave/python-openzwave -Package: python-openzwave-lib -Architecture: any -Depends: libopenzwave1.0|libopenzwave1.3, python, ${misc:Depends}, ${python:Depends} -Description: python-openzwave is another python wrapper around the openzwave project. - The wrapper allows you to control a z-wave network from python. - The one-to-one library is in beta state. You can try it. - The new wrapper is in early developpement stage. So don't use it, but -Package: python-openzwave-api -Architecture: all -Depends: libopenzwave1.0|libopenzwave1.3, python-louie, python-openzwave-lib (= ${binary:Version}), ${misc:Depends}, ${python:Depends} -Suggests: python-pysqlite2 -Description: python-openzwave is another python wrapper around the openzwave project. +Package: python-openzwave +Architecture: any +Depends: ${misc:Depends}, ${python:Depends} +Description: python-openzwave is a python wrapper for the openzwave project. The wrapper allows you to control a z-wave network from python. - The one-to-one library is in beta state. You can try it. - The new wrapper is in early developpement stage. So don't use it, but + . + This package installs the library for Python 2. -Package: python-openzwave-manager -Architecture: all -Depends: python-openzwave-api (= ${binary:Version}), python-urwid -Description: A command line manager for your ZWave Network. - You can : - * Reset controller (hard and soft) and add/remove device/controller - * Change node informations (name, location, ... ) - * view and change values informations - * view and change group informations - * view and change config parameters - * view and change gassociations - * Full management of scenes, switches, dimmers and sensors -Package: python-openzwave-web -Architecture: all -Depends: python-openzwave-api (= ${binary:Version}), python-flask, python-flaskext.wtf, python-flask-babel, python-socketio -Description: The webapp. - Work in progress - -Package: python-openzwave-doc -Architecture: all -Description: Documentation for python-openzwave. - HTML format +Package: python3-openzwave +Architecture: any +Depends: ${misc:Depends}, ${python3:Depends} +Description: python-openzwave is a python wrapper for the openzwave project. + The wrapper allows you to control a z-wave network from python. + . + This package installs the library for Python 3. diff --git a/debian/docs b/debian/docs old mode 100755 new mode 100644 index 8b137891..3075e64c --- a/debian/docs +++ b/debian/docs @@ -1 +1,3 @@ - +README.rst +LICENSE.txt +CHANGELOG.txt diff --git a/debian/python-openzwave-doc.docs b/debian/python-openzwave-doc.docs deleted file mode 100755 index 91efdaab..00000000 --- a/debian/python-openzwave-doc.docs +++ /dev/null @@ -1,3 +0,0 @@ -docs/_build/html -docs/_build/text/CHANGELOG.txt -docs/_build/text/README.txt diff --git a/debian/rules b/debian/rules index a826ea04..acb1bdc9 100755 --- a/debian/rules +++ b/debian/rules @@ -1,27 +1,29 @@ -#!/usr/bin/make -f +#! /usr/bin/make -f -%: - dh $@ --with python2 +#export DH_VERBOSE = 1 +export PYBUILD_NAME = openzwave + +export PYBUILD_INSTALL_ARGS=--flavor=shared + +export PYBUILD_DESTDIR_python2=debian/python-openzwave/ +export PYBUILD_DESTDIR_python2-dbg=debian/python-openzwave-dbg/ +export PYBUILD_DESTDIR_python3=debian/python3-openzwavefoo/ +export PYBUILD_DESTDIR_python3-dbg=debian/python3-openzwave-dbg/ +export PYBUILD_DESTDIR_pypy=debian/pypy-openzwave/ +override_dh_auto_clean: + make clean + -rm -rf venv* + -rm -rf openzwave* + -rm -rf dist + -rm -rf dists + -rm -rf archives + override_dh_auto_build: - python setup-lib.py build --debian-package -override_dh_auto_install: - python setup-lib.py install --root=debian/python-openzwave-lib/ --install-layout=deb --debian-package - rm -rf debian/python-openzwave-lib/usr/config - rm -rf build - python setup-api.py install --root=debian/python-openzwave-api/ --install-layout=deb --debian-package - rm -rf build - python setup-manager.py install --root=debian/python-openzwave-manager/ --install-layout=deb --debian-package - rm -rf build - python setup-web.py install --root=debian/python-openzwave-web/ --install-layout=deb --debian-package - python setup-lib.py develop --debian-package - python setup-api.py develop --debian-package - python setup-manager.py develop --debian-package - python setup-web.py develop --debian-package - cd docs && make html - cd docs && make text - python setup-lib.py develop --uninstall - python setup-api.py develop --uninstall - python setup-manager.py develop --uninstall - python setup-web.py develop --uninstall +override_dh_auto_configure: + +override_dh_auto_test: + +%: + dh $@ --with python2,python3 --buildsystem=pybuild diff --git a/docs/CHANGELOG.rst b/docs/CHANGELOG.rst index cb46a445..ec9d1b02 100755 --- a/docs/CHANGELOG.rst +++ b/docs/CHANGELOG.rst @@ -3,20 +3,123 @@ ========= Changelog ========= + +python_openzwave 0.4.18.x: + * Fix python 2.7/appveyor + * Add serial port auto-detection + +python_openzwave 0.4.17.x: + * Add wheels for Windows + + +python_openzwave 0.4.16.x: + * Fix appveyor build for windows + + +python_openzwave 0.4.15.x: + * Update embeded package + + +python_openzwave 0.4.14.x: + * Use Cython 0.28.6 + * Update embeded package + + +python_openzwave 0.4.12.x: + * Improve support Windows + * COMMAND_CLASS_ZWAVE_PLUS_INFO renamed to COMMAND_CLASS_ZWAVEPLUS_INFO + * Update thermostat + * Update embeded package + + +python_openzwave 0.4.11.x: + * Update embeded package + + +python_openzwave 0.4.10.x: + * Improve support Windows in pip + * Improve tests Windows + * Update contructors for scenes and groups + + +python_openzwave 0.4.9.x: + * Improve support Windows in pip + * Update tests + + +python_openzwave 0.4.6.x: + * First try to support Windows in pip + + +python_openzwave 0.4.5.x: + * Fix bug in node statistics and add test. + * Update Makefile to build flavor dev + * Update pyozw_check. + * Update default flavor : check cython is here before choosing shared + * Fix controller.update_ozw_config when directory isn't writable + + +python_openzwave 0.4.4.x: + * Add new options to pyozw_check to list nodes on network. + + +python_openzwave 0.4.3.x: + * Fix bug in default flavor. + + +python_openzwave 0.4.1.x: + * Update the default flavor : try to use a precompiled library. If can't find one, use the embeded package. + * Add method to controller to get new config from github. + + +python_openzwave 0.4.0.x: + + * New installation process via pip + * Update your install_requires : both libopenzwave, openzwave and the manager are merged in python_openzwave package on pypi. Don't need to update your imports in code. + * There will be major updates in the next releases, it's safe to use python_openzwave>0.4.0 and python_openzwave<0.5 in your requires. + * Remove old versions of libopenzwave and openzwave before you update your installation with new pip process ... or not. + * You can use the old installation process (via github), it's the one I use to develop. + * Installation via archive method is no longer suppored (no release for 0.4.0). Use pip instead with --flavor embed option. + * Default mode is embed now. + * Update config path discovery : check for 'device_classes.xml' in /etc/openzwave/, /usr/local/etc/openzwave/ and + finally in ozw_config in python_openzwave module. + * Add flavor : different ways of building and installing openzwave / python_openzwave. + * Add infos on flavor / build date to getPythonLibraryVersion + * Improve installation on micro machines : embed_shared build and install openzwave/python_openzwave in 8 minutes on a raspberry pi 3 + * Add ozwdev and ozwdev_shared flavors : use openzwave dev branch instead of master + * Rename to COMMAND_CLASS_MULTI_CHANNEL_V2 to COMMAND_CLASS_MULTI_INSTANCE/CHANNEL + * Add tests for c++ library sync + * Add door locks helpers + * Add helpers for config parameters + * Add data_items to value's dict + + +python-openzwave 0.3.3: + + * Openzwave update + * Update values getter in nodes. See #70 + * Fix setvalue for string types in python3 + + python-openzwave 0.3.2: * Openzwave update * Add thermostat + * Add patch from https://github.com/ebisso/python-openzwave/commit/8776daccc730cb5d7f71a178e9e0cc1d191ad115 + * Can compile dynamically + python-openzwave 0.3.1: * Fix bugs and openzwave update + python-openzwave 0.3.0: * Fix bugs and openzwave update + python-openzwave 0.3.0-beta8: * Add multi instance support diff --git a/docs/DEVEL.rst b/docs/DEVEL.rst index c2c7b753..1e6a79f6 100644 --- a/docs/DEVEL.rst +++ b/docs/DEVEL.rst @@ -4,89 +4,54 @@ Developers information ====================== + How to develop for python-openzwave =================================== -Get the sources - -.. code-block:: bash - - git clone https://github.com/OpenZWave/python-openzwave +Fork the project on Github. -You can install all the dependances to develop for python-openzwave using the command : +Get the sources : .. code-block:: bash - sudo make developper-deps + git clone https://github.com/yourname/python-openzwave -You must now install python-openzwave in develop mode +You can install all the dependances to develop for python-openzwave using the command : .. code-block:: bash - make develop - -Your password will be asked (by sudo) for installing eggs in your local directory. - -Develop, test, debug, test, ... :) - -Update the documentation if needed. You surely found the documentation useful, so please keep it up to date. - -You can create an account on travis or docker to run the tests. + sudo make developer-deps -At last but not least, submit your request. - -How to develop for libopenzwave (was python-openzwave-lib) -========================================================== -After updating the pyx, you need to reinstall it. Otherwise, your changes will not be applied : +You must now install python-openzwave in develop mode. Depending on which python version you prefer, use : .. code-block:: bash - make develop - -Tests -===== - -First, install the dependances : + make venv2-dev +or + .. code-block:: bash - sudo make tests-deps + make venv2-dev -To launch all the tests suite (about 140 tests), use the followind command : +Keep in mind that your updates must be python 2 / python 3 compatible. -.. code-block:: bash - - make tests - -To launch on ly some tests : +Develop, test, debug, test, ... :) -.. code-block:: bash +Update the documentation if needed. You surely found the documentation useful, so please keep it up to date. - nosetests --verbosity=2 tests/api/test_controller_command.py +It a good idea to add automatic tests. -Some tests need manual operations (ie to add a node, to remove one, ...). For example, to test the remove node, use : +Launch the full test suite (for python 2 and python 3) : .. code-block:: bash - export MANUALSKIP='False' && nosetests --verbosity=2 tests/api/test_controller_command.py -m test_150 && unset MANUALSKIP - test_150_command_remove_node_and_wait_for_user (tests.api.test_controller_command.TestControllerCommand) ... ok - - ---------------------------------------------------------------------- - Ran 1 test in 16.031s - - OK + make venv-tests -You should push the inclusion button of the node before the end of the test. +At last but not least, submit your request with the result of tests in the comment. -Some tests don't need a ZWave Stick to be launched, so they can be run on the autobuilders (travis, docker, ...). Place them in the autobuild directory. +If you don't follow the previous steps, your PR will be refused or letting in pending state until I've got time to test it. -Travis-ci, Docker Hub, nosetests and pylint are used to test quality of code. There reports are here : - - - Docker : https://registry.hub.docker.com/u/bibi21000/python-openzwave/ - - Travis : https://travis-ci.org/bibi21000/python-openzwave - - `Nosetests report `_ - - `Coverage report `_ - - `Pylint report `_ Documentation ============= @@ -98,90 +63,6 @@ First, install the dependances : sudo make doc-deps Documentation is managed with sphinx. -Don't utpdate txt files (README, INSTALL, ...), update the RST sources in docs. -Use the following commands to generate all docs files (txt, html and joomla) - -You need to have installed python-openzwave (in either develop or install mode) before generating the documentation. - -.. code-block:: bash - - make docs - -Static vs dynamic (or shared) -============================= -The openzwave (c++) lib needs to run as a singleton : it means that it MUST have only one instance of the manager running on your computer. - -There is 2 ways of linking libraries with a program : - - * static : includes a copy of the library in your binary program. - This means that your program has its own instance of the library. - This the way the install.sh runs. - So you CAN'T have another program (like the control-panel) running when using the python-openzwave library - - * dynamic or shared : includes a link to the library in your binary program. - This means that your program share the library with other programs. - In this case, the instance is owned directly by the library. - This the way the debian package works. So you CAN have another program running when using the python-openzwave library. - Of course, this program MUST use the shared library too. - -About sudo -========== -If you are like me and don't like root (and sudo), you can use the following tip to install packages via pip : - -Look at your python local library, it should looks like : - -.. code-block:: bash - - ls -lisa /usr/local/lib/python2.7/dist-packages/ - total 2428 - 1445174 12 drwxrwsr-x 115 root staff 12288 avril 9 21:35 . - 1445172 4 drwxrwsr-x 4 root staff 4096 mai 2 2014 .. - 1457164 4 drwxr-sr-x 5 root staff 4096 nov. 26 2013 actdiag - 1715480 4 drwxr-sr-x 2 root staff 4096 nov. 26 2013 actdiag-0.5.1.egg-info - 1457163 4 -rw-r--r-- 1 root staff 1004 nov. 26 2013 actdiag_sphinxhelper.py - 1457172 4 -rw-r--r-- 1 root staff 620 nov. 26 2013 actdiag_sphinxhelper.pyc - .... - -So, add your common user to the staff group : - -.. code-block:: bash - - sudo usermod -a -G staff userName - -Add the write right to the group staff - -.. code-block:: bash - - sudo chmod -Rf g+w /usr/local/lib/python2.7/dist-packages/ - -And now, it's time log off and log on. Groups are checked when you open the session. - -You can now install your packages without sudo. - -Python3 and virtualenv -====================== -Python 3 is actually not supported. - -A branch (python3) has been created with a special Dockerfile. It build python-openzwave and launch some tests. -This branch is automatically merged from master at "make commit". - -So please, do not directly push under python3 branch. Make your developments under master or another branch. - -It's important for me have python2/python3 compatibilty in the master branch. -cython can help for this : http://docs.cython.org/src/tutorial/strings.html - -The Makefile sill try to automatically configure your version of python (running python --version). - -If you want to install python-openzwave in a python virtual environnement, you should use something like : - -.. code-block:: bash - - make VIRTUAL_ENV=/path/to/my/venv ... - -If you use python 3 and your python executable is called python3 : - -.. code-block:: bash - make PYTHON_EXEC=python3 ... +Don't update txt and rst files (README, INSTALL, ...) in the root directory, update the RST sources in docs. -You can also put these variables in a CONFIG.make file instead of passing them to the command line diff --git a/docs/INSTALL.rst b/docs/INSTALL.rst new file mode 100755 index 00000000..890e529c --- /dev/null +++ b/docs/INSTALL.rst @@ -0,0 +1,41 @@ +:orphan: + +==================================== +Installing python-openzwave from pip +==================================== + + +Flavors +======= + +Flavor embed +------------ + + +Flavor shared +------------- + + +Flavor git +---------- + + +Flavor ozwdev +------------- + + +Flavor ozwdev +------------- + + +Flavor dev +---------- + + +OS +== + +Windows +------- + + diff --git a/docs/INSTALL_ARCH.rst b/docs/INSTALL_ARCH.rst index d4065a7a..6a5ff8aa 100755 --- a/docs/INSTALL_ARCH.rst +++ b/docs/INSTALL_ARCH.rst @@ -4,7 +4,9 @@ Installing python-openzwave from archive ======================================== -This is the simplest (and the fastest) way to install python-openzwave. It cames with openzwave source files and is already cythonized. +This method is deprecated for 0.4.X. Use pip with --embed flavor. Look at README. + +This is the simplest (and the fastest) way to install python-openzwave. It comes with openzwave source files and is already cythonized. This is surely the best solution to install python-openzwave on a raspberry pi. diff --git a/docs/INSTALL_MAC.rst b/docs/INSTALL_MAC.rst index 9ded5e53..6369ee7f 100755 --- a/docs/INSTALL_MAC.rst +++ b/docs/INSTALL_MAC.rst @@ -4,6 +4,4 @@ Installing python-openzwave on MacOs ==================================== -To be done - -Looking for volunteers +Look at README for 0.4.X installation. diff --git a/docs/INSTALL_REPO.rst b/docs/INSTALL_REPO.rst index 06f1f3a9..14145af0 100755 --- a/docs/INSTALL_REPO.rst +++ b/docs/INSTALL_REPO.rst @@ -4,6 +4,8 @@ Installing python-openzwave from repository =========================================== +This method is deprecated for 0.4.X. Use pip with --git flavor. Look at README. + Install the needed tools ======================== diff --git a/docs/INSTALL_WIN.rst b/docs/INSTALL_WIN.rst index 05d7846f..6ced83fc 100755 --- a/docs/INSTALL_WIN.rst +++ b/docs/INSTALL_WIN.rst @@ -5,76 +5,183 @@ Installing python-openzwave on Windows ====================================== -How To Build python-openzwave on Windows with VS2015 -==================================================== +Install Microsoft tools +======================= -Assuming Python 3.5 is set in PATH -Assuming your python environment has pip, cython, setuptools +This package use MSBuild.exe to build openzwave code. +You can find it in Visual Studio 2017 or Visual Studio 2015. -Get sources ------------ +It's also possible to get it as a separate package. -.. code-block:: bash - - git clone https://github.com/openzwave/python-openzwave.git +Only release 14.0 and 15.0 of Microsft Build Tools are tested. - cd python-openzwave - git clone git://github.com/OpenZWave/open-zwave.git openzwave +You nust use the C++ compiler used to build your version of python : https://wiki.python.org/moin/WindowsCompilers - cd openzwave - git checkout Dev - cd .. - git checkout python3 +Install other tools +=================== -Build open-zwave ----------------- +You need git to clone the repository and python (32 bits or 64 bits). Add it to your PATH. -Open openzwave/cpp/build/windows/vs2010/OpenZWave.sln in Visual Studio +Install dependencies : -When asked, accept the project upgrade to VS2015 + - for python 2.7 : -Build Win32|Release + .. code-block:: bash + (venvX) pip install Cython six Louie -Build python-openzwave lib --------------------------- + - for python 3 : -Patch libopenzwave.pyx + .. code-block:: bash -Cause: ValueID has no default constructor and cython needs one for allocating objects on the stack + (venvX) pip install Cython six PyDispatcher -Fix: Allocate object on the the heap as a workaround +clone repositories +================== -Open test/python-openzwave/src-lib/libopenzwave/libopenzwave.pyx +Clone python-openzwave: -Go to line 437 and change: .. code-block:: bash - values_map.insert(pair[uint64_t, ValueID](v.GetId(), v)) + git clone https://github.com/OpenZWave/python-openzwave.git -To: +And clone open-zwave inside python-openzwave : .. code-block:: bash - newPair = new pair[uint64_t, ValueID](v.GetId(), v) - values_map.insert(deref(newPair)) - del newPair - -From a Command Prompt, build it : + cd python-openzwave + git clone https://github.com/OpenZWave/open-zwave.git openzwave -.. code-block:: bash +It's mandatory to clone the previous repository in a directory called openzwave (not open-zwave) - python setup-lib.py build - python setup-api.py build +Visual studio +============= -And install it (in a virtualenv if needed) : +Copy vs2010 in a new directory vs2017 (or vs2015 depending of which Visual Studio you use) : .. code-block:: bash - python setup-lib.py install - python setup-api.py install + xcopy openzwave\cpp\build\windows\vs2010 openzwave\cpp\build\windows\vs2017 /s /e /h + +Open the project (openzwave\cpp\build\windows\vs2017\OpenZWave.sln) in your Visual Studio. +If you want to build for 64bits, add a new target for it. And finally close it. + +Python-openzwave +================ + +Build and install python-openzwave : + + .. code-block:: bash + + python setup.py install --flavor=dev + + .. code-block:: bash + + sysargv ['setup.py', 'install'] + thon setup.py install --flavor=dev + Requirement already satisfied: Cython in c:\program files (x86)\python36-32\lib\site-packages + {'name': 'libopenzwave', 'sources': ['src-lib/libopenzwave/libopenzwave.pyx'], 'include_dirs': ['openzwave/cpp/src', 'openzwave + /cpp/src/value_classes', 'openzwave/cpp/src/platform', 'openzwave/cpp/build/windows', 'src-lib/libopenzwave', 'openzwave/cpp/bu + ild/windows/vs2017/Release/'], 'define_macros': [('PY_LIB_VERSION', '0.4.4'), ('PY_SSIZE_T_CLEAN', 1), ('PY_LIB_FLAVOR', 'dev') + , ('PY_LIB_BACKEND', 'cython')], 'libraries': ['setupapi', 'msvcrt', 'ws2_32', 'dnsapi'], 'extra_objects': ['openzwave/cpp/buil + d/windows/vs2017/Release//OpenZWave.lib'], 'extra_compile_args': [], 'extra_link_args': [], 'language': 'c++'} + ['six', 'PyDispatcher>=2.0.5', 'Cython'] + Requirement already satisfied: Cython in c:\program files (x86)\python36-32\lib\site-packages + running install + flavor --flavor=dev c:\program files (x86)\python36-32\lib\site-packages + running build_openzwave + Found MSBuild.exe : c:/Program Files (x86)/Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe + Found arch : Win32 wave + Found Visual Studio project : vs2017 (x86)/Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\MSBuild.exe + Found build path : openzwave/cpp/build/windows/vs2017/Release/ + ... + ... + byte-compiling C:\Program Files (x86)\Python36-32\Lib\site-packages\python_openzwave\scripts\__init__.py to __init__.cpython-36 + .pyc + running install_egg_info + running egg_info + writing python_openzwave.egg-info\PKG-INFO + writing dependency_links to python_openzwave.egg-info\dependency_links.txt + writing entry points to python_openzwave.egg-info\entry_points.txt + ================================================================ + .\scripts\allusers.bat + this script is executed for all users + delete/rename it if you dont need it + ================================================================ + Page de codes active�: 437 + +And finally, test it : + + .. code-block:: bash + + pyozw_check -l -d COM2 -t 30 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Define options for device COM2 + Start network + Wait for network awake (30s) + ------------------------------------------------------------------------------- + Network is awaked. Talk to controller. + Get python_openzwave version : 0.4.4 + Get python_openzwave config version : Original Z-Wave 2.78 + Get python_openzwave flavor : dev + Get openzwave version : 1.4.2942 + Get config path : C:\Program Files\Python36\lib\site-packages\python_openzwave\ozw_config + Controller capabilities : {'primaryController', 'staticUpdateController'} + Controller node capabilities : {'listening', 'primaryController', 'beaming', 'staticUpdateController'} + Nodes in network : 4 + ------------------------------------------------------------------------------- + Wait for network ready (30s) + ------------------------------------------------------------------------------- + Network is ready. Get nodes + ------------------------------------------------------------ + 1 - Name : ( Location : ) + 1 - Ready : True / Awake : True / Failed : False + 1 - Manufacturer : Aeotec ( id : 0x0086 ) + 1 - Product : DSA02203 Z-Stick S2 ( id : 0x0001 / type : 0x0002 / Version : 3) + 1 - Command classes : set() + 1 - Capabilities : {'listening', 'primaryController', 'beaming', 'staticUpdateController'} + 1 - Neighbors : {4} / Power level : None + 1 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 2 - Name : ( Location : ) + 2 - Ready : True / Awake : True / Failed : False + 2 - Manufacturer : ( id : 0x0000 ) + 2 - Product : ( id : 0x0000 / type : 0x0000 / Version : 2) + 2 - Command classes : set() + 2 - Capabilities : {'listening', 'routing'} + 2 - Neighbors : {3} / Power level : None + 2 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 3 - Name : ( Location : ) + 3 - Ready : False / Awake : True / Failed : True + 3 - Manufacturer : ( id : 0x0000 ) + 3 - Product : ( id : 0x0000 / type : 0x0000 / Version : 3) + 3 - Command classes : set() + 3 - Capabilities : {'listening', 'routing', 'beaming'} + 3 - Neighbors : set() / Power level : None + 3 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + 4 - Name : ( Location : ) + 4 - Ready : True / Awake : True / Failed : False + 4 - Manufacturer : GreenWave ( id : 0x0099 ) + 4 - Product : PowerNode 6 port ( id : 0x0004 / type : 0x0003 / Version : 4) + 4 - Command classes : {'COMMAND_CLASS_MANUFACTURER_SPECIFIC', 'COMMAND_CLASS_ASSOCIATION', 'COMMAND_CLASS_NO_OPERATION', 'COMM + AND_CLASS_VERSION', 'COMMAND_CLASS_SWITCH_BINARY', 'COMMAND_CLASS_MULTI_INSTANCE/CHANNEL', 'COMMAND_CLASS_CRC_16_ENCAP', 'COMMA + ND_CLASS_PROTECTION', 'COMMAND_CLASS_CONFIGURATION', 'COMMAND_CLASS_BASIC', 'COMMAND_CLASS_METER', 'COMMAND_CLASS_SWITCH_ALL'} + 4 - Capabilities : {'listening', 'routing', 'beaming'} + 4 - Neighbors : {1} / Power level : None + 4 - Is sleeping : False / Can wake-up : False / Battery level : None + ------------------------------------------------------------ + Driver statistics : {'SOFCnt': 49, 'ACKWaiting': 0, 'readAborts': 0, 'badChecksum': 0, 'readCnt': 49, 'writeCnt': 46, 'CANCnt': + 0, 'NAKCnt': 1, 'ACKCnt': 30, 'OOFCnt': 0, 'dropped': 17, 'retries': 0, 'callbacks': 0, 'badroutes': 0, 'noack': 4, 'netbusy': + 0, 'nondelivery': 0, 'routedbusy': 0, 'broadcastReadCnt': 0, 'broadcastWriteCnt': 9} + ------------------------------------------------------------ + Stop network + Exit -Reference : https://github.com/OpenZWave/python-openzwave/issues/53 diff --git a/docs/Makefile b/docs/Makefile index 6a2207bb..8b00b67f 100755 --- a/docs/Makefile +++ b/docs/Makefile @@ -43,7 +43,7 @@ clean: -rm -rf $(BUILDDIR)/* html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + $(SPHINXBUILD) -E -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/docs/README.rst b/docs/README.rst index a32381c5..c4ae7c44 100755 --- a/docs/README.rst +++ b/docs/README.rst @@ -1,3 +1,23 @@ +.. image:: https://travis-ci.org/OpenZWave/python-openzwave.svg?branch=master + :target: https://travis-ci.org/OpenZWave/python-openzwave + :alt: Travis status + +.. image:: https://circleci.com/gh/OpenZWave/python-openzwave.png?style=shield + :target: https://circleci.com/gh/OpenZWave/python-openzwave + :alt: Circle status + +.. image:: https://ci.appveyor.com/api/projects/status/2ogl8tx7o3pqphc9?svg=true + :target: https://ci.appveyor.com/project/bibi21000/python-openzwave + :alt: Appveyor status + +.. image:: https://img.shields.io/pypi/format/python_openzwave.svg + :target: https://pypi.python.org/pypi/python_openzwave + :alt: Pypi format + +.. image:: https://img.shields.io/badge/Documentation-ok-brightgreen.svg?style=flat + :target: http://openzwave.github.io/python-openzwave/index.html + :alt: Documentation + ================ python-openzwave ================ @@ -10,15 +30,215 @@ python-openzwave is a python wrapper for the openzwave c++ library : https://git * a full-event webapp example : flask + socket.io + jquery * a suite of tests * many examples - -python-openzwave 0.3.0 is out !!! -================================= - -Look at CHANGELOG to see new features and release notes. - -Look at INSTALL_REPO to test it now. - -Look at INSTALL_ARCH to install from archive : no need to install cython anymore. + * `Full documentation `_ + +python-openzwave 0.4.x is here !!! +================================== + +- New installation process via pip + +- First, you need some build tools and libs. On ubuntu, you should use : + + .. code-block:: bash + + sudo apt-get install --force-yes -y make libudev-dev g++ libyaml-dev + +- Make your virtualenv and activate it : + + .. code-block:: bash + + virtualenv --python=python3 venv3 + source venv3/bin/activate + +- Install the default flavor : + + .. code-block:: bash + + (venvX) pip install python_openzwave + +- The previous command try to install python_openzwave with the flavor 'shared'. + If it can't find a precompiled library of openzwave, it will use the flavor 'embed' with sources downloaded from https://github.com/OpenZWave/python-openzwave/tree/master/archives. + You can change this using flavor option. + There is a bug in the package dependencies and flavors on some systems. You may need to install dependencies manualy : + + - on python 2.7 : + + .. code-block:: bash + + (venvX) pip install cython wheel six pyserial + (venvX) pip install 'Louie>=1.1' + + - on python 3 : + + .. code-block:: bash + + (venvX) pip install cython wheel six pyserial + (venvX) pip install 'PyDispatcher>=2.0.5' + +- Choose your flavor : + + - embed : the default one. Download sources from https://github.com/OpenZWave/python-openzwave/tree/master/archives and + build them. Python_openzwave is statically build using a cythonized version of libopenzwave. No need to install cython. + - shared : if you have install openzwave as module manually, you can link python_openzwave to it. + - git : download sources from openzwave github and link statically to it. + - embed_shared : download sources from https://github.com/OpenZWave/python-openzwave/tree/master/archives, build and install as module on the system. + Python_openzwave use it. Need root access to install openzwave libs. + - git_shared : download sources from openzwave github, build and install them as module on the system. + Python_openzwave use it. Need root access to install openzwave libs. + - ozwdev and ozwdev_shared : use the dev branch of openzwave on github. + - dev : for python_openzwave developers. Look for openzwave sources in a local folder specified by the LOCAL_OPENZWAVE environment variable (defaults to 'openzwave'). + +- Install it : + + .. code-block:: bash + + (venvX) pip install python_openzwave --no-deps --install-option="--flavor=git" + +- You can update to the last version of openzwave using the git flavor : + + .. code-block:: bash + + (venvX) pip uninstall -y python_openzwave + (venvX) pip install python_openzwave --no-cache-dir --no-deps --install-option="--flavor=git" + + +- At last, you can launch pyozw_check to test your installation : + + If no usb stick is connected to the machine, launch : + + .. code-block:: bash + + (venvX) pyozw_check + + If you've one, use it for advanced checks : + + .. code-block:: bash + + (venvX) pyozw_check -i -d /dev/ttyUSB0 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Import libs + Try to import libopenzwave + Try to import libopenzwave.PyLogLevels + Try to get options + Try to get manager + Try to get python_openzwave version + 0.4.0.27 + Try to get python_openzwave full version + python-openzwave version 0.4.0.27 (dev / Apr 18 2017 - 23:22:26) + Try to get openzwave version + 1.4.2501 + Try to get default config path + /etc/openzwave/ + Try to import openzwave (API) + ------------------------------------------------------------------------------- + Intialize device /dev/ttyUSB0 + Try to get options + Try to get manager + 2017-04-12 16:41:29.329 Always, OpenZwave Version 1.4.2497 Starting Up + Try to add watcher + ... + 2017-04-12 16:44:05.880 Always, *************************************************************************** + 2017-04-12 16:44:05.880 Always, ********************* Cumulative Network Statistics ********************* + 2017-04-12 16:44:05.880 Always, *** General + 2017-04-12 16:44:05.880 Always, Driver run time: . . . 0 days, 0 hours, 1 minutes + 2017-04-12 16:44:05.880 Always, Frames processed: . . . . . . . . . . . . . . . . . . . . 27 + 2017-04-12 16:44:05.880 Always, Total messages successfully received: . . . . . . . . . . 27 + 2017-04-12 16:44:05.880 Always, Total Messages successfully sent: . . . . . . . . . . . . 19 + 2017-04-12 16:44:05.880 Always, ACKs received from controller: . . . . . . . . . . . . . 19 + 2017-04-12 16:44:05.880 Always, *** Errors + 2017-04-12 16:44:05.880 Always, Unsolicited messages received while waiting for ACK: . . 0 + 2017-04-12 16:44:05.880 Always, Reads aborted due to timeouts: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Bad checksum errors: . . . . . . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, CANs received from controller: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, NAKs received from controller: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Out of frame data flow errors: . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Messages retransmitted: . . . . . . . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, Messages dropped and not delivered: . . . . . . . . . . . 0 + 2017-04-12 16:44:05.880 Always, *************************************************************************** + 2017-04-12 16:44:07.887 Info, mgr, Driver for controller /dev/ttyUSB0 removed + Try to remove watcher + Try to destroy manager + Try to destroy options + + You can list the nodes on your network using : + + .. code-block:: bash + + (venvX) pyozw_check -l -d /dev/ttyUSB0 -t 60 + + .. code-block:: bash + + ------------------------------------------------------------------------------- + Define options for device /dev/ttyUSB0 + Start network + Wait for network (30s) + Network is ready + ------------------------------------------------------------------------------- + Controller capabilities : {'primaryController', 'staticUpdateController'} + Controller node capabilities : {'listening', 'primaryController', 'staticUpdateController', 'beaming'} + Nodes in network : 4 + Driver statistics : {'noack': 6, 'routedbusy': 0, 'readCnt': 115, 'ACKWaiting': 0, 'badChecksum': 0, 'broadcastReadCnt': 0, 'NAKCnt': 0, 'broadcastWriteCnt': 9, 'dropped': 0, 'CANCnt': 0, 'callbacks': 0, 'OOFCnt': 0, 'readAborts': 0, 'badroutes': 0, 'SOFCnt': 115, 'netbusy': 0, 'writeCnt': 49, 'nondelivery': 0, 'ACKCnt': 49, 'retries': 0} + ------------------------------------------------------------ + 1 - Name : ( Location : ) + 1 - Ready : True / Awake : True / Failed : False + 1 - Manufacturer : Aeotec ( id : 0x0086 ) + 1 - Product : DSA02203 Z-Stick S2 ( id : 0x0001 / type : 0x0002 ) + 1 - Version : 3 / Secured : False / Zwave+ : False + 1 - Command classes : {'COMMAND_CLASS_NO_OPERATION', 'COMMAND_CLASS_BASIC'} + 1 - Capabilities : {'staticUpdateController', 'listening', 'primaryController', 'beaming'} + 1 - Neigbors : {4} / Power level : None + 1 - Is sleeping : False / Can wake-up : False / Battery level : None + + ... + + ------------------------------------------------------------ + 4 - Name : ( Location : ) + 4 - Ready : True / Awake : True / Failed : False + 4 - Manufacturer : GreenWave ( id : 0x0099 ) + 4 - Product : PowerNode 6 port ( id : 0x0004 / type : 0x0003 ) + 4 - Version : 4 / Secured : False / Zwave+ : False + 4 - Command classes : {'COMMAND_CLASS_BASIC', 'COMMAND_CLASS_CONFIGURATION', 'COMMAND_CLASS_SWITCH_BINARY', 'COMMAND_CLASS_VERSION', 'COMMAND_CLASS_CRC_16_ENCAP', 'COMMAND_CLASS_MANUFACTURER_SPECIFIC', 'COMMAND_CLASS_ASSOCIATION', 'COMMAND_CLASS_MULTI_INSTANCE/CHANNEL', 'COMMAND_CLASS_METER', 'COMMAND_CLASS_PROTECTION', 'COMMAND_CLASS_NO_OPERATION', 'COMMAND_CLASS_SWITCH_ALL'} + 4 - Capabilities : {'listening', 'routing', 'beaming'} + 4 - Neigbors : {1} / Power level : None + 4 - Is sleeping : False / Can wake-up : False / Battery level : None + + ... + + + - The old manager is now available via the pyozw_shell command. You need to install module "urwid>=1.1.1" with pip before using it. + + - libopenzwave and openzwave python modules are packaged in the python_openzwave. + So developers needs to update their install_requires (it works fine with pyozw_manager). + They can use the following code to update softly : + + .. code-block:: python + + pyozw_version='0.4.1' + + def install_requires(): + try: + import python_openzwave + return ['python_openzwave==%s' % pyozw_version] + except ImportError: + pass + try: + import libopenzwave + return ['openzwave==%s' % pyozw_version] + except ImportError: + pass + return ['python_openzwave == %s' % pyozw_version] + + + - If you already have an 0.3.x version installed, you should update your installation as usual. Don't install it with pip as it can break your installation (maybe not if you don't remove old modules) + + - Support for windows, macosx, ... is not tested. Feel free to report bug and patches. We can try to support these plateforms. Don't have Windows at home so I can't help. Same for mac. + + - Old installation process is deprecated and reserved for python-openzwave-developers and alternatives machines. + + - Please report your successful installations here : https://github.com/OpenZWave/python-openzwave/issues/73 Support ======= @@ -30,86 +250,3 @@ Pull requests ============= Please read DEVEL documentation before submitting pull request. A lot of project tasks are done automatically or with makefile, so they must be done in a certain place or in a special order. - -Migrating from python-openzwave 0.2.X to 0.3.0 -============================================== -I need to update source tree of python-openzwave and modules's names because of a bug in setuptools : https://bitbucket.org/pypa/setuptools/issue/230/develop-mode-does-not-respect-src . -Sorry for that. - -Update your sources: - -.. code-block:: bash - - git pull - -Before building python-openzwave 0.3.0, you must uninstall the old version : - -.. code-block:: bash - - sudo make uninstall - -About cython : I've made many tests using cython installed via pip : (0.20, 0.21 and 0.22). -Compilation is ok but a segfault appears when launching the tests. Please remove it. - -.. code-block:: bash - - sudo pip uninstall Cython - -You also need to make some minor updates in you code, look at CHANGELOG - -If you have problems, please submit an issue with : - - - cython -V - - the content of the directory /usr/local/lib/python2.7/dist-packages/ (for python2.7) - - the content of /usr/local/lib/python2.7/dist-packages/easy-install.pth (for python 2.7) - - -Ubuntu 64bits ... and the others -================================ - -If you're using Ubuntu 64 bits (and mayde others) and keep your distribution up to date, -you certainly have the segfault problem. - -Ubuntu 12.04 and 14.04 seems to be affected by this bug. Ubuntu 15.10 and Debian Jessie not. - -It appears with the last update of python : - -.. code-block:: bash - - $ python - Python 2.7.6 (default, Jun 22 2015, 17:58:13) - [GCC 4.8.2] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - - -I've open a discussion on cython-users here : https://groups.google.com/forum/#!topic/cython-users/mRsviGuCFOk - -The only way I found to avoid this is to rebuild and reinstall the old release of python : - -.. code-block:: bash - - wget https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6-8.dsc https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6.orig.tar.gz https://launchpad.net/ubuntu/+archive/primary/+files/python2.7_2.7.6-8.diff.gz - - dpkg-source -x python2.7_2.7.6-8.dsc - - sudo apt-get build-dep python2.7 - - cd python2.7-2.7.6 - - dpkg-buildpackage - -Wait, wait and await again :) - -.. code-block:: bash - - cd .. - - sudo dpkg -i *.deb - -To prevent future updates of python, you could mark its packages. For example, if you use apt to update your distribution, use the following command : - -.. code-block:: bash - - sudo apt-mark hold idle-python2.7 libpython2.7-minimal python2.7-dbg python2.7-minimal libpython2.7 libpython2.7-stdlib python2.7-dev libpython2.7-dbg libpython2.7-testsuite python2.7-doc libpython2.7-dev python2.7 python2.7-examples - -Some users have reported that building python-openzwave using the archive (INSTALL_ARCH) can also do the trick. Let me know if it works for you. diff --git a/docs/_index_txt.rst b/docs/_index_txt.rst index 4ebd7801..c0e88762 100755 --- a/docs/_index_txt.rst +++ b/docs/_index_txt.rst @@ -5,7 +5,6 @@ * :doc:`Install from archive ` * :doc:`Install for MacOs ` * :doc:`Install for Windows ` -* :doc:`Manual installation ` * :doc:`Change log ` * :doc:`Examples ` * :doc:`Developpers notes ` diff --git a/docs/command.rst b/docs/command.rst index 0a0d4e9c..ecef5297 100755 --- a/docs/command.rst +++ b/docs/command.rst @@ -7,5 +7,5 @@ The commands to use with nodes. :maxdepth: 2 .. automodule:: openzwave.command - :members: ZWaveNodeBasic, ZWaveNodeSwitch, ZWaveNodeSensor + :members: ZWaveNodeBasic, ZWaveNodeSwitch, ZWaveNodeSensor, ZWaveNodeDoorLock diff --git a/docs/conf.py b/docs/conf.py index d1358e3e..5748fb51 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -257,3 +257,5 @@ # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' + +suppress_warnings = ['image.nonlocal_uri'] diff --git a/docs/data.rst b/docs/data.rst index 3787f3a9..fcf7357e 100755 --- a/docs/data.rst +++ b/docs/data.rst @@ -12,4 +12,8 @@ The common data structures and defitions. .. autodata:: PyValueTypes .. autodata:: PyLogLevels .. autodata:: PyControllerCommand +.. autodata:: PyControllerError .. autodata:: PyControllerState +.. autodata:: PyOptionList +.. autodata:: PyStatDriver +.. autodata:: PyStatNode diff --git a/docs/diagrams.rst b/docs/diagrams.rst index d3809f65..e470c482 100755 --- a/docs/diagrams.rst +++ b/docs/diagrams.rst @@ -8,7 +8,7 @@ Full startup process ==================== .. blockdiag:: - :maxwidth: 600 + :width: 600 blockdiag StartupProcess { orientation = portrait; diff --git a/docs/index.rst b/docs/index.rst index 6d61c312..6cc2f303 100755 --- a/docs/index.rst +++ b/docs/index.rst @@ -6,9 +6,12 @@ Contents: .. toctree:: :maxdepth: 3 - The new "pyx". It provides a low level to the ZWave network. - And its data's definitions - The new API. Map a ZWave Network in objects. + The Readme. + Installation notes. + The low level library ("pyx") to the ZWave network. + The API. Map a ZWave Network in python objects. + How to submit a PR. + Changelog. Indices and tables diff --git a/docs/libopenzwave.rst b/docs/libopenzwave.rst index 7da30fbe..0dc35df6 100755 --- a/docs/libopenzwave.rst +++ b/docs/libopenzwave.rst @@ -5,3 +5,15 @@ libopenzwave module :members: :undoc-members: :show-inheritance: + +.. automodule:: libopenzwave +.. autodata:: PyNotifications +.. autodata:: PyGenres +.. autodata:: PyValueTypes +.. autodata:: PyLogLevels +.. autodata:: PyControllerCommand +.. autodata:: PyControllerError +.. autodata:: PyControllerState +.. autodata:: PyOptionList +.. autodata:: PyStatDriver +.. autodata:: PyStatNode diff --git a/docs/object.rst b/docs/object.rst index 93e1e972..541d6ec9 100755 --- a/docs/object.rst +++ b/docs/object.rst @@ -8,4 +8,4 @@ The low level object. Implements cache mechanism. .. automodule:: openzwave.object :members: ZWaveObject, ZWaveNodeInterface, ZWaveException, ZWaveTypeException, - ZWaveCacheException, ZWaveCommandClassException, NullLoggingHandler + ZWaveCacheException, ZWaveCommandClassException diff --git a/docs/pyozwman.rst b/docs/pyozwman.rst index 46b05035..bcb044cb 100644 --- a/docs/pyozwman.rst +++ b/docs/pyozwman.rst @@ -35,6 +35,6 @@ command cd. All available commands are displayed on every screens. You can use the tab keys to switch between the view panel and the edit panel and the up and down ones to view all informations. -For the developpers : this a good example on how to use the api. +For the developers : this provides a good example on how to use the api. Update are sent to uwird widget using louie notifications. ZWave data updates are done in the set, add, delete, remove, ... methods. diff --git a/examples/api_demo.py b/examples/api_demo.py index 18dbc557..8365589a 100755 --- a/examples/api_demo.py +++ b/examples/api_demo.py @@ -208,9 +208,9 @@ print(" label/help : {}/{}".format (network.nodes[node].values[val].label,network.nodes[node].values[val].help)) print(" id on the network : {}".format (network.nodes[node].values[val].id_on_network)) print(" level: {}".format (network.nodes[node].get_dimmer_level(val))) -print "------------------------------------------------------------" -print "Retrieve RGB Bulbs on the network" -print "------------------------------------------------------------" +print("------------------------------------------------------------") +print("Retrieve RGB Bulbs on the network") +print("------------------------------------------------------------") values = {} for node in network.nodes: for val in network.nodes[node].get_rgbbulbs() : @@ -218,9 +218,9 @@ print(" label/help : {}/{}".format(network.nodes[node].values[val].label,network.nodes[node].values[val].help)) print(" id on the network : {}".format(network.nodes[node].values[val].id_on_network)) print(" level: {}".format(network.nodes[node].get_dimmer_level(val))) -print "------------------------------------------------------------" -print "Retrieve sensors on the network" -print "------------------------------------------------------------" +print("------------------------------------------------------------") +print("Retrieve sensors on the network") +print("------------------------------------------------------------") values = {} for node in network.nodes: for val in network.nodes[node].get_sensors() : @@ -228,9 +228,9 @@ print(" label/help : {}/{}".format(network.nodes[node].values[val].label,network.nodes[node].values[val].help)) print(" id on the network : {}".format(network.nodes[node].values[val].id_on_network)) print(" value: {} {}".format(network.nodes[node].get_sensor_value(val), network.nodes[node].values[val].units)) -print "------------------------------------------------------------" -print "Retrieve thermostats on the network" -print "------------------------------------------------------------" +print("------------------------------------------------------------") +print("Retrieve thermostats on the network") +print("------------------------------------------------------------") values = {} for node in network.nodes: for val in network.nodes[node].get_thermostats() : diff --git a/examples/api_sniff.py b/examples/api_sniff.py index d8bb22af..53ce3e4f 100755 --- a/examples/api_sniff.py +++ b/examples/api_sniff.py @@ -41,7 +41,11 @@ from openzwave.network import ZWaveNetwork from openzwave.option import ZWaveOption import time -from louie import dispatcher, All +import six +if six.PY3: + from pydispatch import dispatcher +else: + from louie import dispatcher device="/dev/ttyUSB0" log="Debug" diff --git a/examples/hello_world.py b/examples/hello_world.py index 9886a67b..ef0a8402 100755 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -41,7 +41,11 @@ from openzwave.network import ZWaveNetwork from openzwave.option import ZWaveOption import time -from louie import dispatcher, All +import six +if six.PY3: + from pydispatch import dispatcher +else: + from louie import dispatcher device="/dev/ttyUSB0" log="None" diff --git a/examples/test_lib.py b/examples/test_lib.py index 20f05d48..2ce9b68b 100755 --- a/examples/test_lib.py +++ b/examples/test_lib.py @@ -65,12 +65,12 @@ def callback(args): if 'valueId' in args: v = args['valueId'] print('valueID: {}'.format(v['id'])) - if v.has_key('groupIndex') and v['groupIndex'] != 0xff: print('GroupIndex: {}'.format(v['groupIndex'])) - if v.has_key('event') and v['event'] != 0xff: print('Event: {}'.format(v['event'])) - if v.has_key('value'): print('Value: {}'.format(str(v['value']))) - if v.has_key('label'): print('Label: {}'.format(v['label'])) - if v.has_key('units'): print('Units: {}'.format(v['units'])) - if v.has_key('readOnly'): print('ReadOnly: {}'.format(v['readOnly'])) + if 'groupIndex' in v and v['groupIndex'] != 0xff: print('GroupIndex: {}'.format(v['groupIndex'])) + if 'event' in v and v['event'] != 0xff: print('Event: {}'.format(v['event'])) + if 'value' in v: print('Value: {}'.format(str(v['value']))) + if 'label' in v: print('Label: {}'.format(v['label'])) + if 'units' in v: print('Units: {}'.format(v['units'])) + if 'readOnly' in v: print('ReadOnly: {}'.format(v['readOnly'])) print('-------------------------------------------------\n') print("Add watcher") diff --git a/github_deploy_key.enc b/github_deploy_key.enc new file mode 100644 index 00000000..f3dad52f --- /dev/null +++ b/github_deploy_key.enc @@ -0,0 +1 @@ +gAAAAABZQtLzloi-Lo8ejSQiUuAlw605x7C5pGJ270Ak-6uMgS4m02uf3nmTLRRgZiKfEevzZaV_r5pBp4CLvxUKjX0ne0iMngvTUyRg8C_7-vVhSkWlTXxzhvorO7Bh24Txy1nLEVfu5suTqQeI0DmAX2i-QylT1GAeo_81Mz-AFe64Wul51Q4iG2g8HFVeqEI7O_mjwvMC5je3Ip0oDMtNSw1zdTqa1SzfzEPQOJOJkY88ssuiRlGhWK1rHtGqKuzHJltjFYkFbeIQnGRvlh3hDumgXhW_6YGlJfGbVLw5dGfx8QO4myLCd72veNc0oeGbbxGDdfz7hpTSITjcolXvDpg2-30kBvV4xCiaFECBn2F8-V6Tm4vJDqchUsw-JT27pIvukNuOu6Zrt2z_Bx_NSDrsE27AgIysqVedFeFJjG7Uv1IzQ6t8qxbikPx1AlS9BodD3cKdB9vvDYZirspL7tus0TCUfews-UYxXB5DTsSSkJyFCy4fw52ATmWN8x-KHVFqVo9ONAF-WyUKZ0KHBg_eYU02oSnO7ceSoR80dgnbSbH6RiZ-8cNdQleFBKK313PJvhpXA3SylDrzPjO63EnJPK7gMbT83QcollBm8oRV-4l4Qxjk-IrnEhSRwJdaNcMPppTp5pA-KC17yX6E-pXYDFcyxNOSUyul8Sh8C5_JXpGq-au8PB1XRitD-Rg1y0bcoy6ZaZpEfxIICJy0K4fLF-ly9u1vFV-p484Ea7QUstnKlnicdS--YqvZJ_sofbYDtx4tjS2oMz58NVUZtAwNmUhGhBk-aAtXau6FZbJvXiPUx4f07_JJTpIDbZWaQv9Bt4oVXpjm-HHKdaW7d1ju6X93xnQqPZORYhBVTgwd-CNgMC3zYoMHHBgU4fLzr-qtnZ_Ie0TpFagnDcusJw7Syk3BQ9ikuPee85-t6lzyd4XbM1L7ryXzYe-DYBt4slHfEVPukJ8-aX8_DJI56yoN56FF19tOJn8nU5XKdg7oovmMSn8mHZtDdOF-jIlIBobG0C8-3S-pcTL_YjmKEY2GpQaKfYn7y16w2eW93tq6Dpuj9xhuG10Q8u0gZjaKhMIyu1inIUzB-26aRp_DJ2qOCyXrcd0IWmRQBEh4V_UJxzrApvgmL2mcNv-ueR5kK3xpzkhxvf5nwlHqC_0F0OZJwCVkklG4Hzdivq4U57oKHyBWYMeXJ64mBUHJbzfqHDE5hJnnxRy2UaK9_aGgCbPSzqBpNjwp8E16uva2nuIgxUNL4qpsxOLMfZAJKnEh_RIEk76kihbZmdBGjHSbjnFE1tuLKQLpN3EH69O5YgUyUene5DLh6v7984uB8I3YZLUweBbAXBBXw1fa8ddgiU3m2KZMCyMRE2GA5xl7DgpwReEkz6jamWVXuV2767InJ-eIcPaSr4YHSdXW6cO8D_uEl0KM5JTFVA1lkx7z7tez9EQuSVEGLYBNqfjvE6SUbY255U67P5dbijhSIPpnnuEQWzX-klx_sAEuHAicmioTxXC_vpKoLQNhNNbHUVNkyxSG0nCGxANfJyzdwsiS6cZgI94MmRqxa7RhmOvXRyDl1tHvyA1uBBX7-g6tVaosLwuAaq-z_CPWxEvE1k7eXsnN7bXAyyj_M1vTv0jAN1fu7Pho-ArgaOvpiw47346oPbYQn_tedkCpWguIbiDTD2iiamDiPWpLOExNQhk9xNo7ESDn85mZuNJMdfSjxMXlStRudn0JbYH6QcmmztzfapRrhvvHF4eI9Ox2TaSKZoPDB34eIAydOPbHTIlvHmM1mF_h9WH0hUHmjbWiH2_qYwPnq4phqF8Dot1l3QxloW-lSY08vpkMMYYgy4sxDR4BxUPtB0UtnuDNuAuXPtPOmG5aLaPNz47tOo7lDZwp24jnLLa0bzrhmNYrNiv0oQZRBurWWzSDk5uOijpYTLjCcu1qO_KnIj0rSfr5hi22nhNVSOarLDpR5Fhy6aaKD_p3xRQ2tl3KL8dgOjHI-0L338kHxGVM1wyWPFTxTUXAOoJGPToBR0o7RkHp_FcfdBDN6JNj35XRo-C_92yM3HZR1grW7P8zFRsnMUBGqpthmCYeXC60RXB00xCGxMOTtQm_q7wEFZ7bdBV2VVVnRaLJcLOCXZ4l9qz2MdJVSprlQlkYd9No5W5NCyBukkqfCzpR94u0CU1VjC_8JhI5uS747_uRUNFNxr1T_qvAMcEGv7UHFmSaqledMDi_dScf1xKpt3vegss8PXem2H1BQ0txWAGC0g247X7DQ7JmcXOXnxELgOl17T53YjVXguVdbMxMSIZcb40QrBL401ieJWZ_BlIQAn3PqmUViSX-EfL5cxMkW2QjWCezfAX1M-Qcb8p4e6E_mnowoxLKiQNNsDqrMTHwal7cXuvop5sx28zo5-Gxn-OQF-Dmmvr1ABGlwJknNJyZkj2bKTJ7RUx7jJuhma1olnl0Jf9Axx4ZZQoFFKhfM18mslDxGgT_KUlH65x-miRoo4dhwIfHXxo4mjgTukz1YChVByyx2jHIo-FIeu5JSM10Kb15heoaH50tHSSM7ueZjZ_8RORFellZBqnW08Q5ZdijhTxLEX5HOVxV3KJvdMelxd_gAI1Txq7UPIiapNPB7QNA6gXMD7fgkGa4j33965FhW5yXw0QurdSVBUtwtwt7vi2hmcBdh8qiL0Sr0ydK4I5qQKtEuojKZG1JmwvbkIL5HKdRXiuby-KYLoHsxjzadhwpkRE3inktqjaQlShE4TEgkEEeKFBgm7Wro0rqeLd2HYbu2O3dkL_i6OyCpTCD4QemtuKUbdRnFK5GzDDys8a2iW2X6iRKpPOaCiT37iokWXrff2RG7gEE1AIScjXoCIHraxaFhGrR1Z7Nfe-b80pSP902aeER5RDKxR6scvh0UnV58mIL5H-aZPbWIHFyIT6CkjaUOc7OBKjeK-KNI7eVOnUZY9fHce472ie9j_zJwbndNMkdlqsBATO3gkvR9fbOxIiFz_MsB15ut8YzfjGy5XWJLUofAldNEwd-4wrodkB0ZDh88nBgUH60zem1gJVdvE5j5KWCfpHRd0orwEoL3ouyGKfEXhQk-2F6hcwRFoFLNhKzEFJITIW5YsAfrZmhNFI9hHjzyccvYLHbTzKAj4CDyKZOnndIssz2DpghenFQtsnbunVygGhLQv6cOwDVBs00MKjaIE7EcswlZ_WzZu3nd2G8dsw22AJMZGsvOt_cFOzkoWTudWDfr3F7q9-K7A1ei3YPzfoxXZJAlSTi8SJnVjCD60SeG6B_EKW-EZP5nGA2zYHFdNiJT9NwpwV-oj6W2lUos9_I899HAnUKK2Gxs7RQRxv7evEK1eQWwlQ_uJ2KaditwLO0H-TlNgEZZvsqrKcvz72gXQqhIeqS0F4HFM0Q1ogO1UZWG41LtWEahZRjLxoazgkRTcGPB5B5x545dFDXDJ9SYI8gFjK8CLzIS9iYMqJpXN7fMQlOuWzN_eikU-j3ppTMMtY5Txxdkmo7Y6CArZTKxW1A1I-CRGyo27iL3eVqSpRUj8oMfVkXGw72i5meZGOH_lWsIK3bs077ovhndEtJsQ1dXa7UKXpLm_7vX_BgEi9URSFAQG40ypCtxTAsyDrmdfktwod0Sbd_WN1IXmnpqVAZWT0awGXV3h5X7_0-3wDSHZAbCUSOZWPKBZPOddGPS0wZk0lOUBPXr_ptkea2cqBVem9YmLN64Ueu59YOlYpLs1670Lb8dvIe07exNAi6oFl_XE9vAG0ziUmRhWgKtovNByqMFEvpCJSctT6lVlEdkxCKG35sXYvVCQkAMN3BZnG9fsJq8t-INeu2W7mRvSPN_intV7hscAajcrlFm688_-ScBIz53j9DaYDhvl9yqapDVu4N7ORiZVpdxJyP56XNFs3k4lPI7UKykzT8yMxUSZzQmahl861bWXiIoVuUng4UgkGuY0X3tIQl4zOM33wluik4Xzt1qxkp3DuhFZVuiUhTmHvaG18-72L6VZ0h7jfUUZ1phtcEtLjBHbEkUN8kItJoYrs7iVCTpX0POjQib80E5tCCdBi-8rWIuUyrs81-0hfpENiz6vujiuVtmVWvnnzExhbrE-bgFmOqj8wT4Ks5g9NVhb9Q0KAzeG01cMHxNl-zyTC-uVeqD0A_IbszpJHlV0pjKNVS1bqCJr_BsvLqy1NNo-7qYH8Yl4QI81pIyeStYFn_XjpB-XnG6jS4ET0lmzA2kAuUxs39BAJof8-y9aMhMlXH379wQwuTHrAJyorPQXswSNA9XAFgIWqt9dlBZKf4kJs-JKvkI8yWoDTiQV_bu_bP3tSEBxukpcO2hl09GHHnEIQqMYQV_ID_qmpYrf5qRZnhBt8QcEcujBIBzfP2Xfauq0tg4bYYgofrF3Y= \ No newline at end of file diff --git a/github_deploy_key_openzwave_python_openzwave.enc b/github_deploy_key_openzwave_python_openzwave.enc new file mode 100644 index 00000000..7084b6cb --- /dev/null +++ b/github_deploy_key_openzwave_python_openzwave.enc @@ -0,0 +1 @@ +gAAAAABaaPgox9_NS0MxF8CneeTVNKqVTLD4L9qfTWWYyzBzMjv5RMLlK6yaarYcvLo4tCPFM9o1i9QBatG5nWNzeyosiBCvft8wmYmua1rWLuAP2bGic3QgviCw75wvA677DDHfZ5w--spPJNfdUcmWlh0bONeBKi4kHFdTXKZ0snjciqAehF1vyc3YcnBIQEhZ0GZSxavbFeXhfgtf5ysw79-KIY295KbBmF1UpieDCE-LJiLxjIc027Qymw2gL-JSoRfCtFZRl9PD6E2MmEk2YWYuZhkxYMpTMmTouK8E70QKQXpfUX7M8yyidR_DXjyrNsReOC4gJtZhFkIMZZ7ic2WJ93SjSI7kCetHF-gE1sB-c89WVOH19htCldHj2_MeeXR0aF4dyC5-P2eHapMY0AHZo-A-z2AIeO9zmmiqFhu-PNQfkoq8bpfvGQgRRT20mDHbRxuwAQMYuoSyBaF35w7pEzPjJv3rmJO_3x4SLZoCZ6UBq-03TyMrpAF5hhycct79EjJGBhGXGAQiQNW2yeW1mpx9J4AsyJJ6INjfMvqYMdY8tQxsEO117HdwLh-R3qMlwl1B10_tmMDs5dwIphMkRgdEwHGFlE6hkBN5nDx3eH-AH5VaYxBaro8Z_wu6FzFFhMbSfJDq1x8b7uJRhk1K0DI1lqRKrcfAVrdW3r7WGodmUdi8TNk2_pYcPRAi-adYiN6QHUQTguJ0FWl3kvm3WOfR1-WPqfGSu6DCHGADTxMQFrl94vnCqEGtc7GLg27cuq72JMvcZqcu9bK39cu64d1UExzLd1slfjKya5dCCGt1t0PPxx4KtqRqzndgDSrF0csCViBZA4CUytDtUdQF79wi3pJckJoaNRCKzykg_Hmvg52POPtclRum3e70-yToxRsZRAEjMyVXs3jrYVGJvl7PtYydhvwVUq9BK5lQcXyyHnztgABLnIb7eYt5APIRAUC554Kx1hnsyUkSH1VgvFs7-I1ZiOSVq7-Vh1OksyfEkPnwKv86Z4rTAXQkw9JlKDh2VC0piVia_iwRwOBLat6KkVDRvcrEuSHtLaBnYj14hIY9rEZQks5cavDS3XoEVZhvcQag7FQDbCGMBVs1y0rw-IY8a3gyR1fegtHH6CuucS8FoWy1VPdTrniIfmYSpRJQFPMqt-wfrTXeYXa6jBxuspV8rh9w_a-hMMbr87KENqSsa18pPey9GmBHCUaIwmWcHKqtbzULtgeOQBo1aKcii6BLG91qE9ysexrXUcDUpl55PF_UfY_Nweyu_jwozjYV8_XO-RIjruDonni1OjO8-HdnlTdj-VBN13OqWPs7BWeNWJ11lxAlLn8L-ZaqAqO1fY-f_xJ0SCLLyK2_2Osvn51ZckngpZ_nyrQU5t0k39xhXiN5_lKXeU8KNsvZ5JO6t7iG6JctVwu-v7AZgKFw5UFfTj3QLj509fjzBUBHl0PVh8HgBtMScWCBAB7V_KDwFgY4JRFvQ1PTrk8Rm5QnlYKVKhrZAbrKwrB58stKk3azZgkWxbquYkv2ffZtCoVmmQUaXbIFgQ7JKSlF2DINoIztAu5M2e99YTQC-6j2eOkiEDqdk4lI5CTESnjSYtmVracoRhjnnLfskgSt04ec8Q4hymqKGFC1QYCgXYcU1H1umrYuchz9HwoHDIe51YVAf86rI1-grm8Z2baQUIoVA1n_1Jj6ENYEMpHPk6OjFu10tgSpSpTAgTUXpmsFspyPJzlD_ThqyebLOKr_iv3jJ8vkSOto1-fxAH9lNd9VM-HpQutxXcxilA6Kf5i3bMHktD_9h-dbg6akazaSe3uwIL5c7_OnKDsKOIbWRYpQ5hNKwquS02gOQCYiPuYokHL-XJMZHAkYUMDjAvgYy4awieSVQmaNo7HfZLJWfwWuE7cdz1lqkpDNnjkQ72cUbRq34bekvgrjEvDslqxmqjBAL2IBfacbpMxVm4pGTmjP3ZGvhIAizY-I_F_J5TlEJolpdmApRV-wfjCk7eZpOqFfUrOT9BRR22FYiXY1rMrFKxlvwCmBYbKtVNPaLaOjQJoRTtyc5iJc3kv0XcI_5fiAGciG87nFXd3IA9hO04N5jV5XKaMlVSCJ1jJdlre4wQuESiDtzaIY7-bAgrRocllIshZezf0aw9qQa-iXVsK7Ili8d-ewr9TL6CK2g5qjwMv5BvCvhYaV-kON7Jvk1buYg8GHuNSRJuzbHvEETihYASB2dPOGvSwtKw1imDnfbUYxYyC8fBNlbg4ttlDRYnlSNVYqn8LNqKaeuvrpP7xpEuTMB4KcloDJ8UuaUYM9ty_6evZBrL9FwSb5qj0p0mZ12O_NHgHvDqNX35DMC4GNqvV5iOhlOChCq92QRd2QhkwrgGpctPADOU1Wo8c8T44PkKxymeyjhJEXrbmlL5SdS2wV3HOu_TyjPXIEEdAv6Czex6VHbDR6fPOJAyiCdCwrraeElWqKMOYOLW-xlI9zS1TJUJXKez7QsEkoCJMk0htzpu_dF_pFk5u4RmTeXHH-KlVTDvxuQlnnT-lbRLz0XtukKtjGPyZHJbdCfbVgULRI-Z204NN91LRZ4E4MGjofTbLWIKU4CrxoQAcQeUh1xIGt2ZH4CoF3xsm46GuS65Wf5NPoqWGFZ8y_8vEMxuSJG6iaskiuQRnW_ikkHAws0RLcJh_gpdF0uShaSoO7zJXcdkYF75IDVaHJeIGIh7SDhVAE6rDnEpVLETd-5wm_zaLO-nJ1b6-qe0k_V4tQG24VdErF6IumXqUuDqwjT3Jy4-pR0Bd9_hd2wyOGZN6oo5tF3xz1IvY5i6GM1PH2P0qMnephzri7b9yJYFM5Y6PzjSY9sZC44rt6GlAHQ4nfzqLhCXR8dr6UYPPF1KKhpDL-WdUu6VxjEMUWVxxsNvcjJRC0ggTpu9uRtBqdRt_PRV0sKoSj3NLICg7ludePdpdw5w-Sx-rSm0c0xjROSlA-0mLHN2i4ZbOolyU1JpUqH2Zz22I10aofeBapxAiXfzLzle_M1ZmeWt8tqm4pEx0DjGVjtMNKhgLRaEgDcAgm6FNUA-W4KCysnLcC-J3l8xyhrZvDXW0KT7oUtwcJi1ZHXOJE6ZAVjMRjkFJJlkhCflTDjU0V1-Uue6yw-Moo9KHbq5uDGMKtzrj_zkpLIBIilZ_kTPSfZrfB5m2jR9Q1Pn07KRoXWKnSkqr9u8hHZ-kfpc_yi6Y7YI4ghENv15zDXRHO2WYKIpOe_biEbJ4djHariIBokXAEF8_lbFiMM_d0kTqYdXxGrJktwakh0hs2uO8PcXCMgNu0Oi23xPSqUPQjpLkNL_1VRkaMbQGVLW9EyBJfMLs7TFfmxcrJXqo5rEJ5gsx4O5B4syi9pM3HFxwPz2p5tsSrK6Cy5n-OYD-E4fpbE1a1xP5UZXRtpOFrL7OT48xQ9xTrsUq2sCR-e_JsGePWGJJrkTzDrpINSvYw8U94dGf23YvAJn03y2EmGU5NXNvsc9ize3a6uoKyA3swNP2FHvPuG16XjlHmySixLQPWQwtUn75q9sfN9XBgPzqwDY-KJrZXABp9iPuHHHxhttaNHXf15GY9rGbAMaTQ7SGDjSykXO-sUrFDmLsO1AsuvEHN1plV0kYYNY3DVP0uZ5vc3_P35RvdkRWfYV_oG6TnAHKgTVu18gdtD6Db7QhBP2LqxbYR9PQQ1U5vWFAbBLf1sst5O_Y5gIkmw4jd6lR_QXcBPvEWzdEc2Z3uLIVrgQxwAXfwOMWVTlkwV3bvP9pH_mGSdmWhDZQeXx06HaJaHMHYKM9oT_peXbSP1xPBxSu_qL7CBZYEOr72bAaU5xFmylENOKlfCxD7cx35zArbFJrHcG4AabBh3HSQE8xjpgzNVTAskWSiesknI5jYtzsvjTu0wEfSGikYHe_R_aKuSTiJotN6MExOhuOJt1CvCUWmVIKtfvyDFmW0MCRslIxdEtrSJfvQBMD0bsk1f6M9GiAdF3xoX2jeDCwp2Rn9gefUWwG-01nc6QbEUYC-frNp2w4x-2NFmiBirVLr9_Dbcg4TxWmArnjg85YfkIk_Iy8HtO-Lv0QJm4hcdyait6_AikTZlOIVkwwkedA42q7s5CisbY_53p9pmc2yeas6RwgPAgYX_8b1ipy8zbnjf28BCytEazeeGPqcFJR37dAkjQrbA-YK_PZV62xY6UlpVii9T4Bpd70jcnnJ4_TieSqPJNzypopJBKS2OlaN-vHLZ2i8iZ7OpA0ZjBJtRT8jyplsLi7GRIA9CJgBWnP_54udPGg4RFkwCNk5GodBVVKmaGqpHKp7_Q-0pIMVCASkktGx6g0NWP59SFJNUHejM9QgwhLlaB3CC8y1p2_57wAFhl07lTQdfhbFKz3053_obzBu8wJiCoQBI3sZXcs= \ No newline at end of file diff --git a/pyozw_pkgconfig.py b/pyozw_pkgconfig.py new file mode 100644 index 00000000..6a9f0c86 --- /dev/null +++ b/pyozw_pkgconfig.py @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2013 Matthias Vogelgesang + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""pkgconfig is a Python module to interface with the pkg-config command line +tool.""" + +import os +import subprocess +import re +import collections +from functools import wraps + + +def _compare_versions(v1, v2): + """ + Compare two version strings and return -1, 0 or 1 depending on the equality + of the subset of matching version numbers. + + The implementation is taken from the top answer at + http://stackoverflow.com/a/1714190/997768. + """ + def normalize(v): + return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")] + + n1 = normalize(v1) + n2 = normalize(v2) + + return (n1 > n2) - (n1 < n2) + + +def _split_version_specifier(spec): + """Splits version specifiers in the form ">= 0.1.2" into ('0.1.2', '>=')""" + m = re.search(r'([<>=]?=?)?\s*((\d*\.)*\d*)', spec) + return m.group(2), m.group(1) + + +def _convert_error(func): + @wraps(func) + def _wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except OSError: + raise EnvironmentError("pkg-config is not installed") + + return _wrapper + + +@_convert_error +def _query(package, option): + pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config' + cmd = '{0} {1} {2}'.format(pkg_config_exe, option, package).split() + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = proc.communicate() + + return out.rstrip().decode('utf-8') + + +@_convert_error +def exists(package): + """ + Return True if package information is available. + + If ``pkg-config`` not on path, raises ``EnvironmentError``. + """ + pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config' + cmd = '{0} --exists {1}'.format(pkg_config_exe, package).split() + return subprocess.call(cmd) == 0 + + +@_convert_error +def requires(package): + """ + Return a list of package names that is required by the package. + + If ``pkg-config`` not on path, raises ``EnvironmentError``. + """ + return _query(package, '--print-requires').split('\n') + + +def cflags(package): + """ + Return the CFLAGS string returned by pkg-config. + + If ``pkg-config`` not on path, raises ``EnvironmentError``. + """ + return _query(package, '--cflags') + + +def libs(package): + """Return the LDFLAGS string returned by pkg-config.""" + return _query(package, '--libs') + +def libs_only_l(package): + """Return the LDFLAGS string returned by pkg-config.""" + return _query(package, '--libs-only-L') + + +def installed(package, version): + """ + Check if the package meets the required version. + + The version specifier consists of an optional comparator (one of =, ==, >, + <, >=, <=) and an arbitrarily long version number separated by dots. The + should be as you would expect, e.g. for an installed version '0.1.2' of + package 'foo': + + >>> installed('foo', '==0.1.2') + True + >>> installed('foo', '<0.1') + False + >>> installed('foo', '>= 0.0.4') + True + + If ``pkg-config`` not on path, raises ``EnvironmentError``. + """ + if not exists(package): + return False + + number, comparator = _split_version_specifier(version) + modversion = _query(package, '--modversion') + + try: + result = _compare_versions(modversion, number) + except ValueError: + msg = "{0} is not a correct version specifier".format(version) + raise ValueError(msg) + + if comparator in ('', '=', '=='): + return result == 0 + + if comparator == '>': + return result > 0 + + if comparator == '>=': + return result >= 0 + + if comparator == '<': + return result < 0 + + if comparator == '<=': + return result <= 0 + + +_PARSE_MAP = { + '-D': 'define_macros', + '-I': 'include_dirs', + '-L': 'library_dirs', + '-l': 'libraries' +} + + +def parse(packages): + """ + Parse the output from pkg-config about the passed package or packages. + + Builds a dictionary containing the 'libraries', the 'library_dirs', + the 'include_dirs', and the 'define_macros' that are presented by + pkg-config. *package* is a string with space-delimited package names. + + If ``pkg-config`` not on path, raises ``EnvironmentError``. + """ + def parse_package(package): + result = collections.defaultdict(list) + + # Execute the query to pkg-config and clean the result. + out = _query(package, '--cflags --libs') + out = out.replace('\\"', '') + + # Iterate through each token in the output. + for token in re.split(r'(? + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +Build process : +- ask user what to do (zmq way in pip) +- or parametrizes it + --dev : use local sources and cythonize way (for python-openzwave devs, ...) + --embed : use local sources and cpp file (for third parties packagers, ...) + --git : download openzwave from git (for geeks) + --shared : use pkgconfig and cython (for debian devs and common users) + --pybind : use pybind alternative (not tested) + --auto (default) : try static, shared and cython, fails if it can't +""" +import time +import os, sys +from os import name as os_name +import re +import shutil +import setuptools +from setuptools import setup, find_packages +from distutils.extension import Extension +from distutils.spawn import find_executable +from distutils import log +from setuptools.command.install import install as _install +from distutils.command.build import build as _build +from distutils.command.clean import clean as _clean +from setuptools.command.bdist_egg import bdist_egg as _bdist_egg +from setuptools.command.develop import develop as _develop +try: + from wheel.bdist_wheel import bdist_wheel as _bdist_wheel +except ImportError: + log.warn("ImportError in : from wheel.bdist_wheel import bdist_wheel as _bdist_wheel") +from platform import system as platform_system +import glob + +from pyozw_version import pyozw_version + +try: + PY3 = not unicode +except NameError: + PY3 = True + +LOCAL_OPENZWAVE = os.getenv('LOCAL_OPENZWAVE', 'openzwave') + +SETUP_DIR = os.path.dirname(os.path.abspath(__file__)) + +class Template(object): + + def __init__(self, openzwave=None, cleanozw=False, sysargv=None, flavor="embed", backend="cython"): + self.openzwave = openzwave + self._ctx = None + self.cleanozw = cleanozw + self.flavor = flavor + self.backend = backend + self.sysargv = sysargv + """Specifics options for os ie windows + """ + self.os_options = dict() + + def get_default_exts (self): + exts = { "name": "libopenzwave", + "sources": [ ], + "include_dirs": [ ], + "define_macros": [ ( 'PY_LIB_VERSION', pyozw_version ) ], + "libraries": [ ], + "extra_objects": [ ], + "extra_compile_args": [ ], + "extra_link_args": [ ], + "language": "c++", + } + return exts + + def cython_context(self): + try: + from Cython.Distutils import build_ext + except ImportError: + return None + exts = self.get_default_exts() + exts['define_macros'] += [('PY_SSIZE_T_CLEAN',1)] + exts['sources'] = ["src-lib/libopenzwave/libopenzwave.pyx"] + return exts + + def cpp_context(self): + try: + from distutils.command.build_ext import build_ext + except ImportError: + return None + exts = self.get_default_exts() + exts['define_macros'] += [('PY_SSIZE_T_CLEAN',1)] + exts['sources'] = ["openzwave-embed/open-zwave-master/python-openzwave/src-lib/libopenzwave/libopenzwave.cpp"] + exts["include_dirs"] += [ "src-lib/libopenzwave/" ] + return exts + + def pybind_context(self): + exts = self.get_default_exts() + exts["sources"] = [ "src-lib/libopenzwave/LibZWaveException.cpp", + "src-lib/libopenzwave/Driver.cpp", + "src-lib/libopenzwave/Group.cpp", + "src-lib/libopenzwave/Log.cpp", + "src-lib/libopenzwave/Options.cpp", + "src-lib/libopenzwave/Manager.cpp", + "src-lib/libopenzwave/Notification.cpp", + "src-lib/libopenzwave/Node.cpp", + "src-lib/libopenzwave/Values.cpp", + "src-lib/libopenzwave/libopenzwave.cpp" + ] + exts["include_dirs"] = [ "pybind11/include" ] + exts['extra_compile_args'] += [ "-fvisibility=hidden" ] + return exts + + def system_context(self, ctx, static=False): + #System specific section + #~ os.environ["CC"] = "gcc" + #~ os.environ["CXX"] = "g++" + #~ os.environ["PKG_CONFIG_PATH"] = "PKG_CONFIG_PATH:/usr/local/lib/x86_64-linux-gnu/pkgconfig/" + log.info("Found platform {0}".format(sys.platform)) + if static: + ctx['include_dirs'] += [ + "{0}/cpp/src".format(self.openzwave), + "{0}/cpp/src/value_classes".format(self.openzwave), + "{0}/cpp/src/platform".format(self.openzwave) ] + + if sys.platform.startswith("win"): + from pyozw_win import get_system_context + get_system_context(ctx, self.os_options, openzwave=os.path.abspath(self.openzwave), static=static) + + elif sys.platform.startswith("cygwin"): + if static: + ctx['libraries'] += [ "udev", "stdc++",'resolv' ] + ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ] + ctx['include_dirs'] += [ "{0}/cpp/build/linux".format(self.openzwave) ] + else: + import pyozw_pkgconfig + ctx['libraries'] += [ "openzwave" ] + extra = pyozw_pkgconfig.cflags('libopenzwave') + if extra != '': + for ssubstitute in ['', 'value_classes', 'platform']: + ctx['extra_compile_args'] += [ os.path.normpath(os.path.join(extra, ssubstitute)) ] + + elif sys.platform.startswith("darwin") : + ctx['extra_link_args'] += [ "-framework", "CoreFoundation", "-framework", "IOKit" ] + ctx['extra_compile_args'] += [ "-stdlib=libc++", "-mmacosx-version-min=10.7" ] + + if static: + ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ] + ctx['include_dirs'] += [ "{0}/cpp/build/mac".format(self.openzwave) ] + else: + import pyozw_pkgconfig + ctx['libraries'] += [ "openzwave" ] + extra = pyozw_pkgconfig.cflags('libopenzwave') + if extra != '': + for ssubstitute in ['', 'value_classes', 'platform']: + ctx['extra_compile_args'] += [ os.path.normpath(os.path.join(extra, ssubstitute)) ] + + elif sys.platform.startswith("freebsd"): + os.environ["CPPFLAGS"] = "-Wno-unused-private-field" + if static: + ctx['libraries'] += [ "usb", "stdc++" ] + ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ] + ctx['include_dirs'] += [ "{0}/cpp/build/linux".format(self.openzwave) ] + else: + import pyozw_pkgconfig + ctx['libraries'] += [ "openzwave" ] + extra = pyozw_pkgconfig.cflags('libopenzwave') + if extra != '': + for ssubstitute in ['', 'value_classes', 'platform']: + ctx['extra_compile_args'] += [ os.path.normpath(os.path.join(extra, ssubstitute)) ] + + elif sys.platform.startswith("sunos"): + if static: + ctx['libraries'] += [ "usb-1.0", "stdc++",'resolv' ] + ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ] + ctx['include_dirs'] += [ "{0}/cpp/build/linux".format(self.openzwave) ] + else: + import pyozw_pkgconfig + ctx['libraries'] += [ "openzwave" ] + extra = pyozw_pkgconfig.cflags('libopenzwave') + if extra != '': + for ssubstitute in ['', 'value_classes', 'platform']: + ctx['extra_compile_args'] += [ os.path.normpath(os.path.join(extra, ssubstitute)) ] + + elif sys.platform.startswith("linux"): + if static: + ctx['libraries'] += [ "udev", "stdc++",'resolv' ] + ctx['extra_objects'] = [ "{0}/libopenzwave.a".format(self.openzwave) ] + ctx['include_dirs'] += [ "{0}/cpp/build/linux".format(self.openzwave) ] + else: + import pyozw_pkgconfig + ctx['libraries'] += [ "openzwave" ] + extra = pyozw_pkgconfig.cflags('libopenzwave') + if extra != '': + for ssubstitute in ['', 'value_classes', 'platform']: + ctx['extra_compile_args'] += [ os.path.normpath(os.path.join(extra, ssubstitute)) ] + + else: + # Unknown systemm + raise RuntimeError("Can't detect plateform {0}".format(sys.platform)) + + return ctx + + @property + def ctx(self): + if self._ctx is None: + if 'install' in sys.argv or 'develop' in sys.argv or 'bdist_egg' in sys.argv: + current_template.install_minimal_dependencies() + self._ctx = self.get_context() + self.finalize_context(self._ctx) + return self._ctx + + @property + def build_ext(self): + if 'install' in sys.argv or 'develop' in sys.argv or 'bdist_egg' in sys.argv: + current_template.install_minimal_dependencies() + from Cython.Distutils import build_ext as _build_ext + return _build_ext + + @property + def copy_openzwave_config(self): + return True + + @property + def install_openzwave_so(self): + return False + + def finalize_context(self, ctx): + self.clean_cython() + if self.flavor: + ctx['define_macros'] += [('PY_LIB_FLAVOR', self.flavor.replace('--flavor=',''))] + else: + ctx['define_macros'] += [('PY_LIB_FLAVOR', "embed")] + if self.backend: + ctx['define_macros'] += [('PY_LIB_BACKEND', self.backend)] + else: + ctx['define_macros'] += [('PY_LIB_BACKEND', "cython")] + return ctx + + def install_requires(self): + if sys.platform.startswith("win"): + return ['Cython'] + else: + return ['Cython==0.28.6'] + + def build_requires(self): + if sys.platform.startswith("win"): + return ['Cython'] + else: + return ['Cython==0.28.6'] + + def build(self): + if len(self.ctx['extra_objects']) == 1 and os.path.isfile(self.ctx['extra_objects'][0]): + log.info("Use cached build of openzwave") + return True + from subprocess import Popen, PIPE + from threading import Thread + try: + from Queue import Queue, Empty + except ImportError: + from queue import Queue, Empty + + io_q = Queue() + + def stream_watcher(identifier, stream): + # fixes subprocess output lag issue when using python 2.x + + if PY3: + dummy_return = b'' + else: + dummy_return = '' + + for line in iter(stream.readline, dummy_return): + if line: + io_q.put((identifier, line)) + + if not stream.closed: + stream.close() + + def printer(): + while True: + try: + # Block for 1 second. + item = io_q.get(True, 1) + except Empty: + # No output in either streams for a second. Are we done? + if proc.poll() is not None: + break + else: + identifier, line = item + log.debug(identifier + ':', line) + if identifier == 'STDERR': + sys.stderr.write('{0}\n'.format(line)) + log.error('{0}\n'.format(line)) + elif sys.platform.startswith("win"): + progress_bar.write(line) + + if sys.platform.startswith("win"): + progress_bar.close() + + if sys.platform.startswith("win"): + from pyozw_progressbar import ProgressBar + from pyozw_win import get_clean_command, get_build_command + + cwd = os.path.split(self.os_options['solution_path'])[0] + build_command = get_build_command(**self.os_options) + + + log.info("Build openzwave ... be patient ...") + + progress_bar = ProgressBar() + proc = Popen(build_command, stdout=PIPE, stderr=PIPE, cwd=cwd) + + elif sys.platform.startswith("cygwin"): + log.info("Build openzwave ... be patient ...") + proc = Popen('make', stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("darwin"): + log.info("Build openzwave ... be patient ...") + proc = Popen('make', stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("freebsd"): + log.info("Build openzwave ... be patient ...") + proc = Popen('gmake', stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("sunos"): + log.info("Build openzwave ... be patient ...") + # fixed command issues to Popen + proc = Popen(['make', 'PREFIX=/opt/local'], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("linux"): + log.info("Build openzwave ... be patient ...") + proc = Popen('make', stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + else: + # Unknown systemm + raise RuntimeError("Can't detect plateform {0}".format(sys.platform)) + + Thread(target=stream_watcher, name='stdout-watcher', + args=('STDOUT', proc.stdout)).start() + Thread(target=stream_watcher, name='stderr-watcher', + args=('STDERR', proc.stderr)).start() + + tprinter = Thread(target=printer, name='printer') + tprinter.start() + while tprinter.is_alive(): + time.sleep(1) + tprinter.join() + + return True + + def install_so(self): + log.info("Install openzwave so ... be patient ...") + from subprocess import Popen, PIPE + from threading import Thread + try: + from Queue import Queue, Empty + except ImportError: + from queue import Queue, Empty + + io_q = Queue() + + def stream_watcher(identifier, stream): + + for line in stream: + io_q.put((identifier, line)) + + if not stream.closed: + stream.close() + + def printer(): + while True: + try: + # Block for 1 second. + item = io_q.get(True, 1) + except Empty: + # No output in either streams for a second. Are we done? + if proc.poll() is not None: + break + else: + identifier, line = item + log.debug(identifier + ':', line) + if identifier == 'STDERR': + sys.stderr.write('{0}\n'.format(line)) + log.error('{0}\n'.format(line)) + if sys.platform.startswith("win"): + proc = Popen([ 'copy', 'OpenZWave.dll' , '%SYSTEM32%\\' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.os_options['vsproject_build'])) + + elif sys.platform.startswith("cygwin"): + proc = Popen([ 'make', 'install' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("darwin"): + proc = Popen([ 'make', 'install' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("freebsd"): + proc = Popen([ 'gmake', 'install' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("sunos"): + proc = Popen([ 'make', 'PREFIX=/opt/local', 'install' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("linux"): + proc = Popen([ 'make', 'install' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + else: + # Unknown systemm + raise RuntimeError("Can't detect plateform {0}".format(sys.platform)) + + Thread(target=stream_watcher, name='stdout-watcher', + args=('STDOUT', proc.stdout)).start() + Thread(target=stream_watcher, name='stderr-watcher', + args=('STDERR', proc.stderr)).start() + + tprinter = Thread(target=printer, name='printer') + tprinter.start() + while tprinter.is_alive(): + time.sleep(1) + tprinter.join() + + if sys.platform.startswith("win"): + log.info("Register dll ... be patient ...") + proc = Popen([ 'regsvr32', 'OpenZWave.dll' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.os_options['vsproject_build'])) + + elif sys.platform.startswith("cygwin"): + import pyozw_pkgconfig + ldpath = pyozw_pkgconfig.libs_only_l('libopenzwave')[2:] + log.info("ldconfig openzwave in {0} so ... be patient ...".format(ldpath)) + proc = Popen([ 'ldconfig', ldpath ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("darwin"): + import pyozw_pkgconfig + ldpath = pyozw_pkgconfig.libs_only_l('libopenzwave')[2:] + log.info("ldconfig openzwave in {0} so ... be patient ...".format(ldpath)) + proc = Popen([ 'ldconfig', ldpath ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("freebsd"): + import pyozw_pkgconfig + ldpath = pyozw_pkgconfig.libs_only_l('libopenzwave')[2:] + log.info("ldconfig openzwave in {0} so ... be patient ...".format(ldpath)) + proc = Popen([ 'ldconfig', ldpath ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("sunos"): + import pyozw_pkgconfig + ldpath = pyozw_pkgconfig.libs_only_l('libopenzwave')[2:] + log.info("ldconfig openzwave in {0} so ... be patient ...".format(ldpath)) + proc = Popen([ 'ldconfig', ldpath ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("linux"): + import pyozw_pkgconfig + ldpath = pyozw_pkgconfig.libs_only_l('libopenzwave')[2:] + log.info("ldconfig openzwave in {0} so ... be patient ...".format(ldpath)) + proc = Popen([ 'ldconfig', ldpath ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + else: + # Unknown systemm + raise RuntimeError("Can't detect plateform {0}".format(sys.platform)) + + Thread(target=stream_watcher, name='stdout-watcher', + args=('STDOUT', proc.stdout)).start() + Thread(target=stream_watcher, name='stderr-watcher', + args=('STDERR', proc.stderr)).start() + + tprinter = Thread(target=printer, name='printer') + tprinter.start() + while tprinter.is_alive(): + time.sleep(1) + tprinter.join() + time.sleep(2.5) + log.info("Openzwave so installed and loaded") + tprinter = None + return True + + def clean(self): + #Build openzwave + try: + if not os.path.isdir(self.openzwave): + return True + except TypeError: + return True + log.info("Clean openzwave in %s ... be patient ..." % (self.openzwave) ) + from subprocess import Popen, PIPE + from threading import Thread + try: + from Queue import Queue, Empty + except ImportError: + from queue import Queue, Empty + + io_q = Queue() + + def stream_watcher(identifier, stream): + + for line in stream: + io_q.put((identifier, line)) + + if not stream.closed: + stream.close() + + def printer(): + while True: + try: + # Block for 1 second. + item = io_q.get(True, 1) + except Empty: + # No output in either streams for a second. Are we done? + if proc.poll() is not None: + break + else: + identifier, line = item + log.debug(identifier + ':', line) + if identifier == 'STDERR': + sys.stderr.write('{0}\n'.format(line)) + log.error('{0}\n'.format(line)) + proc = None + if sys.platform.startswith("win"): + from pyozw_win import get_clean_command + clean_command = get_clean_command(**self.os_options) + log.info("Clean openzwave project ... be patient ...") + proc = Popen( + clean_command, + stdout=PIPE, + stderr=PIPE, + cwd=os.path.split(self.os_options['solution_path'])[0] + ) + #~ proc.wait() + #~ proc = Popen([ 'regsvr32', '-u', 'OpenZWave.dll' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(os.path.abspath(self.openzwave))) + #~ proc = Popen([ 'del', '/F', '/Q', '/S', '%SYSTEM32%\OpenZWave.dll' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(os.path.abspath(self.openzwave))) + + elif sys.platform.startswith("cygwin"): + proc = Popen([ 'make', 'clean' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("darwin"): + proc = Popen([ 'make', 'clean' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("freebsd"): + proc = Popen([ 'gmake', 'clean' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("sunos"): + proc = Popen([ 'make', 'PREFIX=/opt/local', 'clean' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + elif sys.platform.startswith("linux"): + proc = Popen([ 'make', 'clean' ], stdout=PIPE, stderr=PIPE, cwd='{0}'.format(self.openzwave)) + + else: + # Unknown systemm + raise RuntimeError("Can't detect plateform {0}".format(sys.platform)) + + if proc is not None: + Thread(target=stream_watcher, name='stdout-watcher', + args=('STDOUT', proc.stdout)).start() + Thread(target=stream_watcher, name='stderr-watcher', + args=('STDERR', proc.stderr)).start() + + tprinter = Thread(target=printer, name='printer') + tprinter.start() + while tprinter.is_alive(): + time.sleep(1) + tprinter.join() + return True + + def clean_all(self): + log.info("Clean-all openzwave ... be patient ...") + try: + from pkg_resources import resource_filename + dirn = resource_filename('python_openzwave.ozw_config', '__init__.py') + dirn = os.path.dirname(dirn) + except ImportError: + dirn = None + if dirn is None or (dirn is not None and not os.path.isfile(os.path.join(dirn,'device_classes.xml'))): + #At first, check in /etc/openzwave + return self.clean() + import shutil + for f in os.listdir(dirn): + if f not in ['__init__.py', '__init__.pyc']: + if os.path.isfile(os.path.join(dirn, f)): + os.remove(os.path.join(dirn, f)) + elif os.path.isdir(os.path.join(dirn, f)): + shutil.rmtree(os.path.join(dirn, f)) + return self.clean() + + def check_minimal_config(self): + if sys.platform.startswith("win"): + log.info("Found MSBuild.exe : {0}".format(self.os_options['msbuild_path'])) + log.info("Found arch : {0}".format(self.os_options['arch'])) + log.info("Found build configuration : {0}".format(self.os_options['build_type'])) + log.info("Found Visual Studio project : {0}".format(self.os_options['solution_path'])) + log.info("Found build path : {0}".format(self.os_options['build_path'])) + log.info("Found cython : {0}".format(find_executable("cython"))) + else: + log.info("Found g++ : {0}".format(find_executable("g++"))) + log.info("Found gcc : {0}".format(find_executable("gcc"))) + log.info("Found make : {0}".format(find_executable("make"))) + log.info("Found gmake : {0}".format(find_executable("gmake"))) + log.info("Found cython : {0}".format(find_executable("cython"))) + exe = find_executable("pkg-config") + log.info("Found pkg-config : {0}".format(exe)) + if exe is not None: + import pyozw_pkgconfig + for lib in self.ctx['libraries'] + ['yaml-0.1', 'libopenzwave', 'python', 'python2', 'python3']: + log.info("Found library {0} : {1}".format(lib, pyozw_pkgconfig.exists(lib))) + + def install_minimal_dependencies(self): + if len(self.build_requires()) == 0: + return + import pip + try: + log.info("Get installed packages") + try: + packages = pip.utils.get_installed_distributions() + except Exception: + packages = [] + for pyreq in self.build_requires(): + if pyreq not in packages: + try: + log.info("Install minimal dependencies {0}".format(pyreq)) + pip.main(['install', pyreq]) + except Exception: + log.warn("Fail to install minimal dependencies {0}".format(pyreq)) + else: + log.info("Minimal dependencies already installed {0}".format(pyreq)) + except Exception: + log.warn("Can't get package list from pip.") + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/master'): + #Get openzwave + """download an archive to a specific location""" + dest,tail = os.path.split(self.openzwave) + dest_file = os.path.join(dest, 'open-zwave.zip') + if os.path.exists(self.openzwave): + if not self.cleanozw: + #~ log.info("Already have directory %s. Use it. Use --cleanozw to clean it.", self.openzwave) + return self.openzwave + else: + #~ log.info("Already have directory %s but remove and clean it as asked", self.openzwave) + self.clean_all() + try: + os.remove(dest_file) + except Exception: + pass + log.info("fetching {0} into {1} for version {2}".format(url, dest_file, pyozw_version)) + if not os.path.exists(dest): + os.makedirs(dest) + try: + # py2 + from urllib2 import urlopen + except ImportError: + # py3 + from urllib.request import urlopen + req = urlopen(url) + with open(dest_file, 'wb') as f: + f.write(req.read()) + import zipfile + zip_ref = zipfile.ZipFile(dest_file, 'r') + zip_ref.extractall(dest) + zip_ref.close() + return self.openzwave + + def clean_openzwave_so(self): + for path in ['/usr/local/etc/openzwave', '/usr/local/include/openzwave', '/usr/local/share/doc/openzwave']: + try: + log.info('Try to remove {0}'.format('/usr/local/etc/openzwave')) + shutil.rmtree(self.openzwave) + except Exception: + pass + return True + + def clean_cython(self): + try: + os.remove('src-lib/libopenzwave/libopenzwave.cpp') + except Exception: + pass + +class DevTemplate(Template): + + def __init__(self, **args): + Template.__init__(self, **args) + + def get_context(self): + opzw_dir = LOCAL_OPENZWAVE + if LOCAL_OPENZWAVE is None: + if sys.platform.startswith("win"): + from pyozw_win import get_openzwave + get_openzwave('openzwave') + else: + return None + + if not os.path.isdir(opzw_dir): + if sys.platform.startswith("win"): + from pyozw_win import get_openzwave + get_openzwave(opzw_dir) + else: + return None + self.openzwave = opzw_dir + ctx = self.cython_context() + if ctx is None: + log.error("Can't find Cython") + return None + ctx = self.system_context(ctx, static=True) + return ctx + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/master'): + return True + +class GitTemplate(Template): + + def __init__(self, **args): + Template.__init__(self, openzwave=os.path.join("openzwave-git", 'open-zwave-master'), **args) + + def get_context(self): + ctx = self.cython_context() + if ctx is None: + log.error("Can't find Cython") + return None + ctx = self.system_context(ctx, static=True) + return ctx + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/master'): + return Template.get_openzwave(self, url) + + def clean_all(self): + ret = self.clean() + dest,tail = os.path.split(self.openzwave) + if tail == "openzwave-git": + try: + log.info('Try to remove {0}'.format(self.openzwave)) + if os.path.isdir(self.openzwave): + shutil.rmtree(self.openzwave) + except Exception: + pass + elif tail == 'open-zwave-master': + try: + log.info('Try to remove {0}'.format(dest)) + if os.path.isdir(dest): + shutil.rmtree(dest) + except Exception: + pass + return ret + +class GitSharedTemplate(GitTemplate): + + def get_context(self): + ctx = self.cython_context() + if ctx is None: + log.error("Can't find Cython") + return None + ctx = self.system_context(ctx, static=False) + while '' in ctx['extra_compile_args']: + ctx['extra_compile_args'].remove('') + extra = '-I/usr/local/include/openzwave//' + for ssubstitute in ['/', '/value_classes/', '/platform/']: + incl = extra.replace('//', ssubstitute) + if not incl in ctx['extra_compile_args']: + ctx['extra_compile_args'] += [ incl ] + return ctx + + @property + def copy_openzwave_config(self): + return sys.platform.startswith("win") + + @property + def install_openzwave_so(self): + return True + + def clean(self): + self.clean_openzwave_so() + return GitTemplate.clean(self) + +class OzwdevTemplate(GitTemplate): + + def __init__(self, **args): + Template.__init__(self, openzwave=os.path.join("openzwave-git", 'open-zwave-Dev'), **args) + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/Dev'): + return Template.get_openzwave(self, url) + +class OzwdevSharedTemplate(GitSharedTemplate): + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/Dev'): + return Template.get_openzwave(self, url) + +class EmbedTemplate(Template): + + def __init__(self, backend='cpp', **args): + Template.__init__(self, openzwave=os.path.join("openzwave-embed", 'open-zwave-master'), backend=backend, **args) + + @property + def build_ext(self): + if 'install' in sys.argv or 'develop' in sys.argv: + current_template.check_minimal_config() + current_template.install_minimal_dependencies() + from distutils.command.build_ext import build_ext as _build_ext + return _build_ext + + def get_context(self): + ctx = self.cpp_context() + ctx = self.system_context(ctx, static=True) + return ctx + + def install_requires(self): + return [] + + def build_requires(self): + return [] + + def get_openzwave(self, url='https://raw.githubusercontent.com/OpenZWave/python-openzwave/master/archives/open-zwave-master-{0}.zip'.format(pyozw_version)): + ret = Template.get_openzwave(self, url) + shutil.copyfile(os.path.join(self.openzwave,'python-openzwave','openzwave.vers.cpp'), os.path.join(self.openzwave,'cpp','src','vers.cpp')) + return ret + + def clean(self): + ret = Template.clean(self) + try: + log.info('Try to copy {0}'.format(os.path.join(self.openzwave,'python-openzwave','openzwave.vers.cpp'))) + shutil.copyfile(os.path.join(self.openzwave,'python-openzwave','openzwave.vers.cpp'), os.path.join(self.openzwave,'cpp','src','vers.cpp')) + except Exception: + pass + return ret + + def clean_all(self): + ret = self.clean() + dest,tail = os.path.split(self.openzwave) + if tail == "openzwave-embed": + try: + log.info('Try to remove {0}'.format(self.openzwave)) + shutil.rmtree(self.openzwave) + except Exception: + pass + elif tail == 'open-zwave-master': + try: + log.info('Try to remove {0}'.format(dest)) + shutil.rmtree(dest) + except Exception: + pass + return ret + +class EmbedSharedTemplate(EmbedTemplate): + + def get_context(self): + ctx = self.cpp_context() + ctx = self.system_context(ctx, static=False) + while '' in ctx['extra_compile_args']: + ctx['extra_compile_args'].remove('') + extra = '-I/usr/local/include/openzwave//' + for ssubstitute in ['/', '/value_classes/', '/platform/']: + incl = extra.replace('//', ssubstitute) + if not incl in ctx['extra_compile_args']: + ctx['extra_compile_args'] += [ incl ] + return ctx + + def clean(self): + self.clean_openzwave_so() + return EmbedTemplate.clean(self) + + @property + def copy_openzwave_config(self): + return False + + @property + def install_openzwave_so(self): + return True + +class SharedTemplate(Template): + def __init__(self, **args): + Template.__init__(self, **args) + + def get_context(self): + ctx = self.cython_context() + if ctx is None: + log.error("Can't find Cython") + return None + ctx = self.system_context(ctx, static=False) + return ctx + + def build(self): + return True + + @property + def copy_openzwave_config(self): + return sys.platform.startswith("win") + + def get_openzwave(self, url='https://codeload.github.com/OpenZWave/open-zwave/zip/master'): + return True + +def parse_template(sysargv): + tmpl = None + flavor = None + if '--flavor=dev' in sysargv: + index = sysargv.index('--flavor=dev') + flavor = sysargv.pop(index) + tmpl = DevTemplate(sysargv=sysargv) + elif '--flavor=git' in sysargv: + index = sysargv.index('--flavor=git') + flavor = sysargv.pop(index) + tmpl = GitTemplate(sysargv=sysargv) + elif '--flavor=git_shared' in sysargv: + index = sysargv.index('--flavor=git_shared') + flavor = sysargv.pop(index) + tmpl = GitSharedTemplate(sysargv=sysargv) + elif '--flavor=ozwdev' in sysargv: + index = sysargv.index('--flavor=ozwdev') + flavor = sysargv.pop(index) + tmpl = OzwdevTemplate(sysargv=sysargv) + elif '--flavor=ozwdev_shared' in sysargv: + index = sysargv.index('--flavor=ozwdev_shared') + flavor = sysargv.pop(index) + tmpl = OzwdevSharedTemplate(sysargv=sysargv) + elif '--flavor=embed' in sysargv: + index = sysargv.index('--flavor=embed') + flavor = sysargv.pop(index) + tmpl = EmbedTemplate(sysargv=sysargv) + elif '--flavor=embed_shared' in sysargv: + index = sysargv.index('--flavor=embed_shared') + flavor = sysargv.pop(index) + tmpl = EmbedSharedTemplate(sysargv=sysargv) + elif '--flavor=shared' in sysargv: + index = sysargv.index('--flavor=shared') + flavor = sysargv.pop(index) + tmpl = SharedTemplate(sysargv=sysargv) + if tmpl is None: + flavor = 'embed' + try: + import pyozw_pkgconfig + if pyozw_pkgconfig.exists('libopenzwave'): + try: + from Cython.Distutils import build_ext + flavor = 'shared' + except ImportError: + log.info("Can't find cython") + except: + log.info("Can't find pkg-config") + #Default template + if flavor == 'embed': + log.info("Use embeded package of openzwave") + tmpl = EmbedTemplate(sysargv=sysargv) + elif flavor == 'shared': + log.info("Use precompiled library openzwave") + tmpl = SharedTemplate(sysargv=sysargv) + tmpl.flavor = flavor + if '--cleanozw' in sysargv: + index = sysargv.index('--cleanozw') + sysargv.pop(index) + tmpl.cleanozw = True + log.info('sysargv', sysargv) + print('sysargv', sysargv) + log.info("Found SETUP_DIR : {0}".format(SETUP_DIR)) + print("Found SETUP_DIR : {0}".format(SETUP_DIR)) + return tmpl + +current_template = parse_template(sys.argv) + +def install_requires(): + pkgs = ['six', 'pyserial'] + if (sys.version_info > (3, 0)): + pkgs.append('PyDispatcher>=2.0.5') + else: + pkgs.append('Louie>=1.1') + pkgs += current_template.install_requires() + return pkgs + +def build_requires(): + return current_template.build_requires() + +def get_dirs(base): + return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ] + +def data_files_config(target, source, pattern): + ret = list() + tup = list() + tup.append(target) + tup.append(glob.glob(os.path.join(source,pattern))) + ret.append(tup) + dirs = get_dirs(source) + if len(dirs): + for d in dirs: + rd = d.replace(source+os.sep, "", 1) + ret.extend(data_files_config(os.path.join(target,rd), \ + os.path.join(source,rd), pattern)) + return ret + +class bdist_egg(_bdist_egg): + def run(self): + build_openzwave = self.distribution.get_command_obj('build_openzwave') + build_openzwave.develop = True + self.run_command('build_openzwave') + _bdist_egg.run(self) + +class build_openzwave(setuptools.Command): + description = 'download and build openzwave' + + user_options = [ + ('openzwave-dir=', None, + 'the source directory where openzwave sources should be stored'), + ('flavor=', None, + 'the flavor of python_openzwave to install'), + ] + + def initialize_options(self): + self.openzwave_dir = None + self.flavor = None + + def finalize_options(self): + if self.openzwave_dir is None: + if getattr(self, 'develop', False) or not getattr(self, 'install', False): + self.openzwave_dir = current_template.openzwave + else: + build = self.distribution.get_command_obj('build') + build.ensure_finalized() + self.openzwave_dir = os.path.join(build.build_lib, current_template.openzwave) + self.flavor = current_template.flavor + + def run(self): + current_template.check_minimal_config() + current_template.get_openzwave() + current_template.clean() + current_template.build() + if current_template.install_openzwave_so: + current_template.install_so() + +class openzwave_config(setuptools.Command): + description = 'Install config files from openzwave' + + user_options = [ + ('install-dir=', None, + 'the installation directory where openzwave configuration should be stored'), + ] + + def initialize_options(self): + self.install_dir = None + + def finalize_options(self): + if self.install_dir is None: + install = self.distribution.get_command_obj('install') + install.ensure_finalized() + self.install_dir = install.install_lib + + def run(self): + if self.install_dir is None: + log.warning("Can't install ozw_config to None") + return + if not current_template.copy_openzwave_config: + log.info("Don't install ozw_config for template {0}".format(current_template)) + return + log.info("Install ozw_config for template {0}".format(current_template)) + dest = os.path.join(self.install_dir, 'python_openzwave', "ozw_config") + if os.path.isdir(dest): + #Try to remove old config + try: + import shutil + shutil.rmtree(dest) + except Exception: + log.exception("Can't remove old config directory") + if not os.path.isdir(dest): + os.makedirs(dest) + self.copy_tree(os.path.join(current_template.openzwave,'config'), dest) + +class build(_build): + sub_commands = [('build_openzwave', None)] + _build.sub_commands + +try: + class bdist_wheel(_bdist_wheel): + def run(self): + build_openzwave = self.distribution.get_command_obj('build_openzwave') + build_openzwave.develop = True + self.run_command('build_openzwave') + _bdist_wheel.run(self) +except NameError: + log.warn("NameError in : class bdist_wheel(_bdist_wheel) - Use bdist_egg instead") + class bdist_wheel(bdist_egg): + pass + +class clean(_clean): + def run(self): + if getattr(self, 'all', False): + current_template.clean_all() + else: + current_template.clean() + _clean.run(self) + +class develop(_develop): + description = 'Develop python_openzwave' + + user_options = _develop.user_options + [ + ('flavor=', None, 'the flavor of python_openzwave to install'), + ] + + def initialize_options(self): + self.flavor = None + return _develop.initialize_options(self) + + def finalize_options(self): + if self.flavor is None: + self.flavor = current_template.flavor + log.info('flavor {0}'.format(self.flavor)) + return _develop.finalize_options(self) + + def run(self): + #In case of --uninstall, it will build openzwave to remove it ... stupid. + #In develop mode, build is done by the makefile + #~ build_openzwave = self.distribution.get_command_obj('build_openzwave') + #~ build_openzwave.develop = True + #~ self.run_command('build_openzwave') + _develop.run(self) + +class install(_install): + description = 'Install python_openzwave' + + user_options = _install.user_options + [ + ('flavor=', None, 'the flavor of python_openzwave to install'), + ] + + def initialize_options(self): + self.flavor = None + return _install.initialize_options(self) + + def finalize_options(self): + if self.flavor is None: + self.flavor = current_template.flavor + log.info('flavor {0}'.format(self.flavor)) + return _install.finalize_options(self) + + def run(self): + build_openzwave = self.distribution.get_command_obj('build_openzwave') + build_openzwave.develop = True + self.run_command('build_openzwave') + self.run_command('openzwave_config') + _install.run(self) diff --git a/pyozw_version.py b/pyozw_version.py index 3fd37d2f..4b4d3e8b 100644 --- a/pyozw_version.py +++ b/pyozw_version.py @@ -21,12 +21,25 @@ along with python-openzwave. If not, see http://www.gnu.org/licenses. """ -pyozw_version = '0.3.1' +pyozw_version = '0.4.19' if "-" in pyozw_version: pyozw_version_short = pyozw_version.split("-") else: pyozw_version_short = pyozw_version +def install_requires(): + try: + import python_openzwave + return ['python_openzwave==%s' % pyozw_version] + except ImportError: + pass + try: + import libopenzwave + return ['openzwave==%s' % pyozw_version] + except ImportError: + pass + return ['python_openzwave==%s' % pyozw_version] + if __name__ == '__main__': import sys if len(sys.argv)>1 and sys.argv[1]=="--major": diff --git a/pyozw_win.py b/pyozw_win.py new file mode 100644 index 00000000..3f052ace --- /dev/null +++ b/pyozw_win.py @@ -0,0 +1,802 @@ +# -*- coding: utf-8 -*- +""" +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + :platform: Unix, Windows, MacOS X + :sinopsis: openzwave API + +.. moduleauthor: bibi21000 aka Sébastien GALLET + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +""" + +import sys +import os +import platform +import shutil +from pyozw_version import pyozw_version + +try: + _winreg = __import__('_winreg') +except ImportError: + _winreg = __import__('winreg') + + +from subprocess import Popen, PIPE + +# this is simply to show that you can build using only VS2017 as a requirement. +VS2017_VCVARSALL = r'"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"' + +WIN64 = '64' in platform.machine() +PYTHON64 = platform.architecture()[0] == '64bit' and WIN64 +ARCH = 'x64' if PYTHON64 else 'x86' + + +try: + PY3 = not unicode +except NameError: + PY3 = True + +TOOLSETS = { + 15.0: ['v141', '15.0'], # vs2017 + 14.0: ['v140', '14.0'], # vs2015 + 10.0: ['v100', '4.0'], # vs2010 + 4.0: ['v90', '4.0'], # vs2008 +} + + +def setup_build_env_2017(): + proc = Popen( + VS2017_VCVARSALL + ' ' + ARCH + ' && set', + shell=True, + stdout=PIPE, + stderr=PIPE + ) + + test_env = {} + for line in proc.stdout: + if PY3: + line = line.decode("utf-8") + + if '=' in line: + key, value = line.split('=', 1) + test_env[key.strip()] = value.strip() + + for key, value in list(test_env.items()): + if str(os.environ.get(key, None)) != value: + os.environ[key] = value + + os.environ['DISTUTILS_USE_SDK'] = '1' + + +# comment this line to run normally. +setup_build_env_2017() + + +def _get_reg_value(path, key): + d = _read_reg_values(path) + if key in d: + return d[key] + return '' + + +def _read_reg_keys(key): + try: + handle = _winreg.OpenKeyEx( + _winreg.HKEY_LOCAL_MACHINE, + 'SOFTWARE\\Wow6432Node\\Microsoft\\' + key + ) + except _winreg.error: + return [] + res = [] + + for i in range(_winreg.QueryInfoKey(handle)[0]): + res += [_winreg.EnumKey(handle, i)] + + return res + + +def _read_reg_values(key): + try: + handle = _winreg.OpenKeyEx( + _winreg.HKEY_LOCAL_MACHINE, + 'SOFTWARE\\Wow6432Node\\Microsoft\\' + key + ) + except _winreg.error: + return {} + res = {} + for i in range(_winreg.QueryInfoKey(handle)[1]): + name, value, _ = _winreg.EnumValue(handle, i) + res[_convert_mbcs(name)] = _convert_mbcs(value) + + return res + + +def _convert_mbcs(s): + dec = getattr(s, "decode", None) + if dec is not None: + try: + s = dec("mbcs") + except UnicodeError: + pass + return s + + +def get_environment(): + from setuptools.msvc import ( + msvc9_query_vcvarsall, + EnvironmentInfo, + msvc14_get_vc_env + ) + + py_version = sys.version_info[:2] + + if py_version >= (3, 5): + env = msvc14_get_vc_env(ARCH) + msbuild_version = 14.0 + env_info = EnvironmentInfo(ARCH) + msbuild_path = _find_file( + 'MSBuild.exe', + env_info.MSBuild[0] + )[0] + + sdks = ('10.0', '8.1', '8.1A', '8.0', '8.0A') + solution_dest = 'vs2015' + + elif (3, 5) > py_version >= (3, 3): + env = msvc9_query_vcvarsall(10.0, ARCH) + msbuild_version = 4.0 + msbuild_path = _get_reg_value( + 'MSBuild\\4.0', + 'MSBuildOverrideTasksPath' + ) + + if msbuild_path: + msbuild_path = _find_file( + 'MSBuild.exe', + msbuild_path + )[0] + + sdks = ('7.1', '7.0A') + solution_dest = 'vs2010' + + elif (3, 3) > py_version >= (2, 6): + env = msvc9_query_vcvarsall(9.0, ARCH) + msbuild_version = 4.0 + msbuild_path = _get_reg_value( + 'MSBuild\\4.0', + 'MSBuildOverrideTasksPath' + ) + + if msbuild_path: + msbuild_path = _find_file( + 'MSBuild.exe', + msbuild_path + )[0] + + sdks = ('6.1', '6.1A', '6.0A') + solution_dest = 'vs2008' + + else: + raise RuntimeError( + 'This library does not support python versions < 2.6' + ) + + for sdk in sdks: + sdk_version = _get_reg_value( + 'Microsoft SDKs\\Windows\\v' + sdk, + 'ProductVersion' + ) + if sdk_version: + sdk_installation_folder = _get_reg_value( + 'Microsoft SDKs\\Windows\\v' + sdk, + 'InstallationFolder' + ) + target_platform = sdk_version + os.environ['WindowsSdkDir'] = sdk_installation_folder + break + else: + raise RuntimeError('Unable to locate suitable SDK %s' % (sdks,)) + + platform_toolset, tools_version = TOOLSETS[msbuild_version] + + return ( + env, + msbuild_version, + msbuild_path, + sdk_installation_folder, + target_platform, + platform_toolset, + tools_version, + solution_dest + ) + + +def _find_file(file_name, path): + res = [] + + for root, dirs, files in os.walk(path): + if ( + ((PYTHON64 and 'amd64' in root) or 'amd64' not in root) and + file_name in files + ): + res.append(os.path.join(root, file_name)) + return res + + +def setup_build_environment(openzwave, build_type): + if 'DISTUTILS_USE_SDK' in os.environ: + target_platform = os.environ['WINDOWSSDKVERSION'].replace('\\', '') + + if 'VS150COMNTOOLS' in os.environ: + msbuild_version = 15.0 + solution_dest = 'vs2017' + + elif 'VS140COMNTOOLS' in os.environ: + msbuild_version = 14.0 + solution_dest = 'vs2015' + else: + raise RuntimeError + + msbuild_path = _find_file('MSBuild.exe', os.environ['VSINSTALLDIR'])[0] + platform_toolset, tools_version = TOOLSETS[msbuild_version] + sdk_installation_folder = os.environ['WINDOWSSDKVERBINPATH'] + os.environ['MSSDK'] = sdk_installation_folder + + else: + ( + env, + msbuild_version, + msbuild_path, + sdk_installation_folder, + target_platform, + platform_toolset, + tools_version, + solution_dest + ) = get_environment() + + if 'WINDOWSSDKVERBINPATH' in env: + sdk_installation_folder = env['WINDOWSSDKVERBINPATH'] + + env['MSSDK'] = sdk_installation_folder + env['DISTUTILS_USE_SDK'] = '1' + + for key, value in env.items(): + os.environ[key] = value + + if 'VS150COMNTOOLS' in os.environ and msbuild_version == 14.0: + platform_toolset = 'v141' + tools_version = '15.0' + msbuild_version = 15.0 + solution_dest = 'vs2017' + + if 'WINDOWSSDKLIBVERSION' in os.environ: + target_platform = ( + os.environ['WINDOWSSDKLIBVERSION'].replace('\\', '') + ) + + if not msbuild_path: + raise RuntimeError( + 'Unable to locate MSBuild to compile OpenZWave' + ) + + project_base_path = os.path.abspath( + os.path.join( + openzwave, + 'cpp', + 'build', + 'windows' + ) + ) + + project_path = os.path.join(project_base_path, solution_dest) + + if PYTHON64: + build_path = os.path.join(project_path, 'x64', build_type) + else: + build_path = os.path.join(project_path, build_type) + + if not os.path.exists(project_path): + shutil.copytree( + os.path.join(project_base_path, 'vs2010'), + project_path + ) + + print('Updating VS solution please wait.') + + if update_vs_project( + os.path.join(project_path, 'OpenZWave.vcxproj'), + tools_version, + platform_toolset, + target_platform + ): + with open(os.path.join(project_path, 'OpenZWave.sln'), 'r') as f: + sln = str(f.read()).replace('\r', '') + + if GLOBAL_SELECTION_TEMPLATE not in sln: + sln = sln.replace( + GLOBAL_SELECTION_KEY, + GLOBAL_SELECTION_TEMPLATE + ) + + with open(os.path.join(project_path, 'OpenZWave.sln'), 'w') as f: + f.write(sln) + + solution_path = os.path.join(project_path, 'OpenZWave.sln') + + return ( + solution_path, + build_path, + msbuild_path, + msbuild_version, + target_platform, + platform_toolset, + tools_version, + sdk_installation_folder + ) + + +def update_vs_project(path, tools_version, platform_toolset, target_platform): + from xml.etree import ElementTree + + vcxproj_xmlns = 'http://schemas.microsoft.com/developer/msbuild/2003' + ElementTree.register_namespace('', vcxproj_xmlns) + + with open(path, 'r') as f: + vcxproj = f.read() + + # the original xml file contains some characters that the xml parser + # does not like, these are non human readable characters and they do not + # need to exist. So we remove them. + for char in (187, 191, 239): + vcxproj = vcxproj.replace(chr(char), '') + + root = ElementTree.fromstring(vcxproj) + + vcxproj_xmlns = '{' + vcxproj_xmlns + '}' + + # there are only 3 things that need to get changed once the solution has + # been fully updated. the tools version, the platform teeolset + # and the windows target platform. if a cached version of openzwave is used + # there is no need to create a whole new solution. so what we do is we set + # an attribute in the root of the xml to inform us if the file has been + # upgraded already. + + root.attrib['ToolsVersion'] = tools_version + + for node in root.findall(vcxproj_xmlns + 'PropertyGroup'): + if ( + 'Label' in node.attrib and + node.attrib['Label'] == 'Configuration' + ): + for sub_node in node: + if ( + sub_node.tag.replace(vcxproj_xmlns, '') == + 'PlatformToolset' + ): + sub_node.text = platform_toolset + break + else: + sub_node = ElementTree.Element('PlatformToolset') + sub_node.text = platform_toolset + node.append(sub_node) + + for node in root.findall(vcxproj_xmlns + 'PropertyGroup'): + if 'Label' in node.attrib and node.attrib['Label'] == 'Globals': + for sub_node in node: + if ( + sub_node.tag.replace(vcxproj_xmlns, '') == + 'WindowsTargetPlatformVersion' + ): + sub_node.text = target_platform + break + else: + sub_node = ElementTree.Element('WindowsTargetPlatformVersion') + sub_node.text = target_platform + node.append(sub_node) + + # this function is the core of upgrading the solution. It burrows down + # into a node through each layer and makes a copy. this copy gets modified + # to become an x64 version. the copy gets returned and then added to the + # xml file + + def iter_node(old_node): + new_node = ElementTree.Element(old_node.tag) + if old_node.text is not None: + new_node.text = old_node.text.replace('Win32', 'x64') + + for key, value in old_node.attrib.items(): + new_node.attrib[key] = value.replace('Win32', 'x64') + for old_sub_node in old_node: + new_node.append(iter_node(old_sub_node)) + return new_node + + # here is the testing to se if the file has been updated before. + if 'PythonOpenZWave' not in root.attrib: + update = True + root.attrib['PythonOpenZWave'] = 'True' + i = 0 + + for node in root[:]: + tag = node.tag.replace(vcxproj_xmlns, '') + + if ( + tag == 'ItemGroup' and + 'Label' in node.attrib and + node.attrib['Label'] == 'ProjectConfigurations' + ): + for sub_item in node[:]: + node.append(iter_node(sub_item)) + + if ( + tag == 'PropertyGroup' and + 'Label' in node.attrib and + node.attrib['Label'] == 'Configuration' + ): + root.insert(i, iter_node(node)) + i += 1 + + if ( + tag == 'ImportGroup' and + 'Label' in node.attrib and + node.attrib['Label'] == 'PropertySheets' + ): + root.insert(i, iter_node(node)) + i += 1 + + if ( + tag == 'PropertyGroup' and + not node.attrib.keys() + ): + j = 0 + for sub_item in node[:]: + if ( + sub_item.tag.replace(vcxproj_xmlns, '') != + '_ProjectFileVersion' + ): + node.insert(j, iter_node(sub_item)) + j += 1 + + if tag == 'ItemDefinitionGroup': + root.insert(i, iter_node(node)) + i += 1 + i += 1 + else: + update = False + + with open(path, 'w')as f: + f.write(xml_tostring(root, vcxproj_xmlns)) + + # we return if the file was updated or not. this is a flag that tells up + # if we need to update the sln file. + return update + + +# this is a custom xml writer. it recursively iterates through an +# ElementTree object creating a formatted string that is as close as i can +# get it to what Visual Studio creates. I did this for consistency as well +# as ease of bug testing + +def xml_tostring(node, xmlns, indent=''): + tag = node.tag.replace(xmlns, '') + no_text = node.text is None or not node.text.strip() + + if indent: + output = '' + else: + output = '\n' + if xmlns: + node.attrib['xmlns'] = xmlns.replace('{', '').replace('}', '') + + if no_text and not list(node) and not node.attrib.keys(): + output += '{0}<{1} />\n'.format(indent, tag) + else: + output += '{0}<{1}'.format(indent, tag) + + for key in sorted(node.attrib.keys()): + output += ' {0}="{1}"'.format(key, str(node.attrib[key])) + + if not list(node) and no_text: + output += ' />\n' + elif not no_text and not list(node): + output += '>{0}\n'.format(node.text, tag) + elif list(node) and no_text: + output += '>\n' + for item in node: + output += xml_tostring(item, xmlns, indent + ' ') + output += '{0}\n'.format(indent, tag) + else: + output += '>\n {0}{1}\n'.format(indent, node.text) + for item in node: + output += xml_tostring(item, xmlns, indent + ' ') + output += '{0}\n'.format(indent, tag) + return output + + +# because we no longer use devenv in favor of msbuild there are only 2 commands +# needed. +# one for clean and the other to build +def get_clean_command(msbuild_path, solution_path, build_type, arch, **_): + clean_template = ( + '"{msbuild_path}" ' + '"{solution_path}" ' + '/property:Configuration={build_type} ' + '/property:Platform={arch} ' + '/t:Clean ' + ) + clean_command = clean_template.format( + msbuild_path=msbuild_path, + solution_path=solution_path, + build_type=build_type, + arch=arch + ) + + return clean_command + + +def get_build_command(msbuild_path, solution_path, build_type, arch, **_): + build_template = ( + '"{msbuild_path}" ' + '"{solution_path}" ' + '/property:Configuration={build_type} ' + '/property:Platform={arch} ' + '/t:Build' + ) + + build_command = build_template.format( + msbuild_path=msbuild_path, + solution_path=solution_path, + build_type=build_type, + arch=arch + ) + + return build_command + + +def get_system_context( + ctx, + options, + openzwave="openzwave", + static=False, + debug=False +): + + + if debug: + print("get_system_context for windows") + + # one feature i added is building a debugging version, this is only going + # to happen if sys.executable ends with _d which identifies that the python + # interpreter is a debugging build. + + if static: + if os.path.splitext(sys.executable)[0].endswith('_d'): + options['build_type'] = 'Debug' + ctx['define_macros'] += [('_DEBUG', 1)] + ctx['libraries'] += ["setupapi", "msvcrtd", "ws2_32", "dnsapi"] + else: + options['build_type'] = 'Release' + ctx['libraries'] += ["setupapi", "msvcrt", "ws2_32", "dnsapi"] + else: + if os.path.splitext(sys.executable)[0].endswith('_d'): + options['build_type'] = 'DebugDLL' + ctx['define_macros'] += [('_DEBUG', 1)] + ctx['libraries'] += ["setupapi", "msvcrtd", "ws2_32", "dnsapi"] + else: + options['build_type'] = 'ReleaseDLL' + ctx['libraries'] += ["setupapi", "msvcrt", "ws2_32", "dnsapi"] + + if PYTHON64: + options['arch'] = "x64" + else: + options['arch'] = 'Win32' + + ( + solution_path, + build_path, + msbuild_path, + msbuild_version, + target_platform, + platform_toolset, + tools_version, + sdk_installation_folder + ) = setup_build_environment(openzwave, options['build_type']) + + options['msbuild_path'] = msbuild_path + options['solution_path'] = solution_path + options['build_path'] = build_path + options['msbuild_version'] = msbuild_version + options['target_platform'] = target_platform + options['platform_toolset'] = platform_toolset + options['tools_version'] = tools_version + options['sdk_installation_folder'] = sdk_installation_folder + + if debug: + print('Platform: %s' % target_platform) + print('Platform architecture %s' % ARCH) + print('Platform toolset: %s' % platform_toolset) + print('MSBuild path: %s' % msbuild_path) + print('MSBuild version: %0.1f' % msbuild_version) + print('MSBuild tools version: %s' % tools_version) + print('SDK installation path: %s' % sdk_installation_folder) + print("Found options %s" % options) + + cpp_path = os.path.join(openzwave, 'cpp') + src_path = os.path.join(cpp_path, 'src') + + if static: + ctx['extra_objects'] = [os.path.join(build_path, 'OpenZWave.lib')] + + ctx['include_dirs'] += [ + src_path, + os.path.join(src_path, 'value_classes'), + os.path.join(src_path, 'platform'), + os.path.join(cpp_path, 'build', 'windows'), + build_path, + ] + else: + ctx['libraries'] += ["OpenZWave"] + + ctx['extra_compile_args'] += [ + src_path, + os.path.join(src_path, 'value_classes'), + os.path.join(src_path, 'platform'), + ] + + ctx['define_macros'] += [ + ('CYTHON_FAST_PYCCALL', 1), + ('_MT', 1), + ('_DLL', 1) + ] + + +GLOBAL_SELECTION_TEMPLATE = ''' Debug|x64 = Debug|x64 + DebugDLL|x64 = DebugDLL|x64 + Release|x64 = Release|x64 + ReleaseDLL|x64 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.Debug|x64.ActiveCfg = Debug|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.Debug|x64.Build.0 = Debug|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.Release|x64.ActiveCfg = Release|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.Release|x64.Build.0 = Release|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {497F9828-DEC2-4C80-B9E0-AD066CCB587C}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64''' + + +GLOBAL_SELECTION_KEY = ''' EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution''' + + +def get_openzwave(opzw_dir): + url = 'https://codeload.github.com/OpenZWave/open-zwave/zip/master' + + from io import BytesIO + try: + from urllib2 import urlopen + except ImportError: + from urllib.request import urlopen + + import zipfile + + base_path = os.path.dirname(__file__) + + print('Downloading openzwave...') + + req = urlopen(url) + dest_file = BytesIO(req.read()) + dest_file.seek(0) + + zip_ref = zipfile.ZipFile(dest_file, 'r') + zip_ref.extractall(base_path) + zip_ref.close() + dest_file.close() + + os.rename( + os.path.join(base_path, zip_ref.namelist()[0]), + opzw_dir + ) + + +if __name__ == '__main__': + from subprocess import Popen, PIPE + from setuptools import setup + from distutils.extension import Extension + + print("Start pyozw_win") + + ctx = dict( + name='libopenzwave', + sources=['src-lib\\libopenzwave\\libopenzwave.pyx'], + include_dirs=['src-lib\\libopenzwave'], + define_macros=[ + ('PY_LIB_VERSION', pyozw_version), + ('PY_SSIZE_T_CLEAN', 1), + ('PY_LIB_FLAVOR', 'dev'), + ('PY_LIB_BACKEND', 'cython') + ], + libraries=[], + extra_objects=[], + extra_compile_args=[], + extra_link_args=[], + language='c++' + ) + + ozw_path = os.path.abspath('openzwave') + + if not os.path.exists(ozw_path): + get_openzwave('openzwave') + + options = dict() + + get_system_context( + ctx, + options, + openzwave=ozw_path, + static=True, + debug=True + ) + + clean = get_clean_command(**options) + build = get_build_command(**options) + + def run(command): + print('Running command:', command) + proc = Popen( + command, + shell=True, + stdout=PIPE, + stderr=PIPE, + cwd=os.path.split(options['solution_path'])[0], + ) + + if PY3: + dummy_return = b'' + else: + dummy_return = '' + + for line in iter(proc.stdout.readline, dummy_return): + if line and PY3: + sys.stdout.write(line.decode("utf-8")) + elif line: + sys.stdout.write(line) + + errcode = proc.returncode + print('\n\nerrcode', errcode, '\n\n') + + for line in iter(proc.stderr.readline, dummy_return): + if line and PY3: + sys.stdout.write(line.decode("utf-8")) + elif line: + sys.stdout.write(line) + + # run(clean) + # run(build) + + print( + 'Library built in %s using compiler %s for arch %s' % + (options['build_path'], options['msbuild_path'], options['arch']) + ) + + setup( + script_args=['build_ext'], + version=pyozw_version, + name='libopenzwave', + description='libopenzwave', + verbose=1, + ext_modules=[Extension(**ctx)], + ) diff --git a/setup-api.py b/setup-api.py index ff641aff..040db041 100755 --- a/setup-api.py +++ b/setup-api.py @@ -26,11 +26,7 @@ import os import sys from pyozw_version import pyozw_version - -if sys.hexversion >= 0x3000000: - dispatch_package = 'pydispatcher >= 2.0.5' -else: - dispatch_package = 'Louie >= 1.1' +from pyozw_setup import install_requires DEBIAN_PACKAGE = False filtered_args = [] @@ -81,7 +77,5 @@ def data_files_config(target, source, pattern): #The following line install documentation in share/python-openzwave #data_files = data_files, #recommend : "pysqlite >= 2.6", - install_requires=[ dispatch_package, - 'libopenzwave == %s' % pyozw_version, - ] + install_requires=install_requires()+[ 'libopenzwave == %s' % pyozw_version ] ) diff --git a/setup-lib.py b/setup-lib.py index 47336f29..ab9f22a5 100755 --- a/setup-lib.py +++ b/setup-lib.py @@ -20,122 +20,53 @@ You should have received a copy of the GNU General Public License along with python-openzwave. If not, see http://www.gnu.org/licenses. +Build process : +- ask user what to do (zmq way in pip) +- or parametrizes it + --dev : use local sources and cythonize way (for python-openzwave devs, ...) + --embed : use local sources and cpp file (for third parties packagers, ...) + --git : download openzwave from git (for geeks) + --shared : use pkgconfig and cython (for debian devs and common users) + --pybind : use pybind alternative (not tested) + --auto (default) : try static, shared and cython, fails if it can't """ -from os import name as os_name -import os, sys + from setuptools import setup, find_packages from distutils.extension import Extension -if os.path.isdir(os.path.join(os.getcwd(), '.git')): - #Install from git - from Cython.Distutils import build_ext -else: - #Install from archive - from distutils.command.build_ext import build_ext -from platform import system as platform_system -import glob from pyozw_version import pyozw_version +from pyozw_setup import LOCAL_OPENZWAVE, SETUP_DIR +from pyozw_setup import current_template, parse_template, get_dirs, data_files_config, install_requires +from pyozw_setup import Template, DevTemplate, GitTemplate, EmbedTemplate, SharedTemplate +from pyozw_setup import bdist_egg, build_openzwave, openzwave_config, build, clean, develop, install -DEBIAN_PACKAGE = False -filtered_args = [] - -for arg in sys.argv: - if arg == "--debian-package": - DEBIAN_PACKAGE = True - else: - filtered_args.append(arg) -sys.argv = filtered_args - -def _getDirs(base): - return [x for x in glob.iglob(os.path.join( base, '*')) if os.path.isdir(x) ] - -def data_files_config(target, source, pattern): - ret = list() - tup = list() - tup.append(target) - tup.append(glob.glob(os.path.join(source,pattern))) - ret.append(tup) - dirs = _getDirs(source) - if len(dirs): - for d in dirs: - rd = d.replace(source+os.sep, "", 1) - ret.extend(data_files_config(os.path.join(target,rd), \ - os.path.join(source,rd), pattern)) - return ret - -data_files = data_files_config('config','openzwave/config','*.xml') -data_files.extend(data_files_config('config','openzwave/config','*.xsd')) - -cmdclass = { } -ext_modules = [ ] - -if platform_system() == 'Windows': - ext_modules = [Extension("libopenzwave", - sources=["src-lib/libopenzwave/libopenzwave.pyx"], - libraries=['setupapi', 'msvcrt', 'ws2_32', 'dnsapi'], - language="c++", - extra_objects=['openzwave/cpp/build/windows/vs2010/Release/openzwave.lib'], - include_dirs=['openzwave/cpp/src', 'openzwave/cpp/src/value_classes', 'openzwave/cpp/src/platform', 'openzwave/cpp/build/windows', "src-lib/libopenzwave"] - )] -elif platform_system() == 'Darwin': - ext_modules = [Extension("libopenzwave", - sources=["src-lib/libopenzwave/libopenzwave.pyx"], - libraries=['stdc++'], - language="c++", - extra_link_args=['-framework', 'CoreFoundation', '-framework', 'IOKit'], - extra_objects=['openzwave/libopenzwave.a'], - include_dirs=['openzwave/cpp/src', 'openzwave/cpp/src/value_classes', 'openzwave/cpp/src/platform', 'openzwave/cpp/build/mac', "src-lib/libopenzwave"] - )] -elif platform_system() == 'FreeBSD': - ext_modules = [Extension("libopenzwave", - sources=["src-lib/libopenzwave/libopenzwave.pyx"], - libraries=['usb', 'stdc++'], - language="c++", - define_macros=[ - ('PY_SSIZE_T_CLEAN',1), - ], - extra_objects=['openzwave/libopenzwave.a'], - include_dirs=['openzwave/cpp/src/', 'openzwave/cpp/src/value_classes/', 'openzwave/cpp/src/platform/', 'openzwave/cpp/build/linux/'] - )] -elif DEBIAN_PACKAGE == True: - #For linux dynamic - ext_modules = [Extension("libopenzwave", - sources=["src-lib/libopenzwave/libopenzwave.pyx"], - libraries=['udev', 'stdc++', 'openzwave'], - language="c++", - define_macros=[ - ('PY_SSIZE_T_CLEAN',1), - ], - #extra_objects=['/usr/libopenzwave.a'], - include_dirs=['/usr/include/openzwave', '/usr/include/openzwave/value_classes', '/usr/include/openzwave/platform', "src-lib/libopenzwave"] - )] -else: - #For linux static - ext_modules = [Extension("libopenzwave", - sources=["src-lib/libopenzwave/libopenzwave.pyx"], - libraries=['udev', 'stdc++'], - language="c++", - define_macros=[ - ('PY_SSIZE_T_CLEAN',1), - ], - extra_objects=['openzwave/libopenzwave.a'], - include_dirs=['openzwave/cpp/src/', 'openzwave/cpp/src/value_classes/', 'openzwave/cpp/src/platform/', 'openzwave/cpp/build/linux/'] - )] +print(current_template) +print(current_template.ctx) +print(install_requires()) setup( name = 'libopenzwave', author='Sébastien GALLET aka bibi2100 ', author_email='bibi21000@gmail.com', version = pyozw_version, + #~ scripts=['src-lib/scripts/pyozw_check'], zip_safe = False, url='https://github.com/OpenZWave/python-openzwave', - cmdclass = {'build_ext': build_ext}, - ext_modules = ext_modules, + cmdclass = {'build_ext': current_template.build_ext, + 'bdist_egg': bdist_egg, + 'build': build, + 'build_openzwave': build_openzwave, + 'openzwave_config': openzwave_config, + 'clean': clean, + 'develop': develop, + 'install': install}, + ext_modules = [ + Extension(**current_template.ctx) + ], #ext_modules = cythonize(ext_modules), package_dir = {'' : 'src-lib'}, #The following line install config drectory in share/python-openzwave - data_files = data_files, - packages = find_packages('src-lib', exclude=["scripts"]), - install_requires=[ - 'six', - ] + #~ data_files = data_files, + packages = find_packages('src-lib'), + install_requires = install_requires(), ) + diff --git a/setup-manager.py b/setup-manager.py index 8bcaa59e..5e3403d5 100644 --- a/setup-manager.py +++ b/setup-manager.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!env python # -*- coding: utf-8 -*- """ This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. @@ -25,27 +25,17 @@ import glob import os import sys -from pyozw_version import pyozw_version - -DEBIAN_PACKAGE = False -filtered_args = [] - -for arg in sys.argv: - if arg == "--debian-package": - DEBIAN_PACKAGE = True - else: - filtered_args.append(arg) -sys.argv = filtered_args +import pyozw_version setup( name = 'pyozwman', author='Sébastien GALLET aka bibi2100 ', author_email='bibi21000@gmail.com', url='https://github.com/OpenZWave/python-openzwave', - version = pyozw_version, + version = pyozw_version.pyozw_version, zip_safe = False, - scripts=['src-manager/scripts/ozwsh'], + #~ scripts=['src-manager/scripts/pyozw_shell'], package_dir = {'' : 'src-manager' }, - packages = find_packages('src-manager', exclude=["scripts"]), - install_requires=[ "urwid >= 1.1.1", 'openzwave == %s' % pyozw_version ] + packages = find_packages('src-manager'), + install_requires=pyozw_version.install_requires() + [ "urwid>=1.1.1"], ) diff --git a/setup-web.py b/setup-web.py index b083ecff..12d8f860 100644 --- a/setup-web.py +++ b/setup-web.py @@ -25,29 +25,18 @@ import glob import os import sys -from pyozw_version import pyozw_version - -DEBIAN_PACKAGE = False -filtered_args = [] - -for arg in sys.argv: - if arg == "--debian-package": - DEBIAN_PACKAGE = True - else: - filtered_args.append(arg) -sys.argv = filtered_args +import pyozw_version setup( name = 'pyozwweb', author='Sébastien GALLET aka bibi2100 ', author_email='bibi21000@gmail.com', url='https://github.com/OpenZWave/python-openzwave', - version = pyozw_version, + version = pyozw_version.pyozw_version, zip_safe = False, package_dir = {'' : 'src-web' }, packages = find_packages('src-web', exclude=["scripts", "libraries"]), - install_requires = [ - 'openzwave == %s' % pyozw_version, + install_requires = pyozw_version.install_requires() + [ 'Flask == 0.10.1', 'Flask-WTF == 0.9.5', 'Babel >= 1.0', diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..1aebe8ff --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +[metadata] +description-file = + docs/README.rst + docs/CHANGELOG.rst diff --git a/setup.py b/setup.py new file mode 100755 index 00000000..7d17e584 --- /dev/null +++ b/setup.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + :platform: Unix, Windows, MacOS X, BSD + +.. moduleauthor:: bibi21000 aka Sébastien GALLET + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +Build process : +- ask user what to do (zmq way in pip) +- or parametrizes it + --dev : use local sources and cythonize way (for python-openzwave devs, ...) + --embed : use local sources and cpp file (for third parties packagers, ...) + --git : download openzwave from git (for geeks) + --shared : use pkgconfig and cython (for debian devs and common users) + --pybind : use pybind alternative (not tested) + --auto (default) : try static, shared and cython, fails if it can't +""" +from setuptools import setup, find_packages +from distutils.extension import Extension +from pyozw_version import pyozw_version +from pyozw_setup import LOCAL_OPENZWAVE, SETUP_DIR +from pyozw_setup import current_template, parse_template, get_dirs, data_files_config, install_requires, build_requires +from pyozw_setup import Template, DevTemplate, GitTemplate, EmbedTemplate, SharedTemplate +from pyozw_setup import bdist_egg, build_openzwave, openzwave_config, build, clean, develop, install + +print(current_template) +print(current_template.ctx) +print(install_requires()) + +setup( + name = 'python_openzwave', + author='Sébastien GALLET aka bibi2100', + author_email='bibi21000@gmail.com', + version = pyozw_version, + zip_safe = False, + url='https://github.com/OpenZWave/python-openzwave', + cmdclass = { + 'build_ext': current_template.build_ext, + 'bdist_egg': bdist_egg, + 'build': build, + 'build_openzwave': build_openzwave, + 'openzwave_config': openzwave_config, + 'clean': clean, + 'develop': develop, + 'install': install, + }, + #~ scripts=['src-lib/scripts/pyozw_check', 'src-manager/scripts/pyozw_shell'], + entry_points={'console_scripts':['pyozw_check=python_openzwave.scripts.pyozw_check:main', + 'pyozw_shell=python_openzwave.scripts.pyozw_shell:main'] }, + ext_modules = [ + Extension(**current_template.ctx) + ], + #ext_modules = cythonize(ext_modules), + package_dir = { 'libopenzwave' : 'src-lib', + 'python_openzwave' : 'src-python_openzwave/python_openzwave', + 'openzwave' : 'src-api/openzwave', + 'pyozwman' : 'src-manager/pyozwman' + }, + #The following line install config drectory in share/python-openzwave + #~ data_files = data_files, + packages = find_packages('src-lib', exclude=["scripts"]) + + find_packages('src-api', exclude=["scripts"]) + + find_packages('src-manager', exclude=["scripts"]) + + find_packages('src-python_openzwave', exclude=["scripts"]), + install_requires = install_requires(), + description = 'python_openzwave is a python wrapper for the openzwave c++ library.', + long_description = 'A full API to map the ZWave network in Python objects. Look at examples at : https://github.com/OpenZWave/python-openzwave', + download_url = 'https://raw.githubusercontent.com/OpenZWave/python-openzwave/master/archives/python_openzwave-{0}.zip'.format(pyozw_version), + keywords = [ 'openzwave', 'zwave' ], + classifiers = [ + "Topic :: Home Automation", + "Topic :: System :: Hardware", + "Topic :: System :: Hardware :: Hardware Drivers", + "Topic :: Software Development :: Libraries :: Python Modules", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Operating System :: POSIX :: BSD", + "Programming Language :: C++", + "Programming Language :: Cython", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", + ], + +) diff --git a/src-api/openzwave/command.py b/src-api/openzwave/command.py index a487b9fb..4b6d330c 100755 --- a/src-api/openzwave/command.py +++ b/src-api/openzwave/command.py @@ -357,6 +357,73 @@ def can_wake_up(self): else: return False + def get_configs(self, readonly='All', writeonly='All'): + """ + The command 0x70 (COMMAND_CLASS_CONFIGURATION) of this node. + Retrieve the list of configuration parameters. + + Filter rules are : + command_class = 0x70 + genre = "Config" + readonly = "All" (default) or as passed in arg + + :param readonly: whether to retrieve readonly configs + :param writeonly: whether to retrieve writeonly configs + :return: The list of configuration parameters + :rtype: dict() + """ + return self.get_values(class_id=0x70, genre='Config', readonly=readonly, writeonly=writeonly) + + def set_config(self, value_id, value): + """ + The command 0x70 (COMMAND_CLASS_CONFIGURATION) of this node. + Set config to value (using value value_id) + + :param value_id: The value to retrieve state + :type value_id: int + :param value: Appropriate value for given config + :type value: any + """ + if value_id in self.get_configs(readonly=False): + self.values[value_id].data = value + return True + return False + + + def get_config(self, value_id=None): + """ + The command 0x70 (COMMAND_CLASS_CONFIGURATION) of this node. + Set config to value (using value value_id) + + :param value_id: The value to retrieve value. If None, retrieve the first value + :type value_id: int + :return: The level of this battery + :rtype: int + """ + if value_id is None: + for val in self.get_configs(): + return self.values[val].data + elif value_id in self.get_configs(): + return self.values[value_id].data + return None + + def can_set_indicator(self): + """ + Check if node contain the command class 0x87 (COMMAND_CLASS_INDICATOR). + + Filter rules are : + + command_class = 0x87 + + :return: True if the node can set the indicator + :rtype: bool + """ + res = self.get_values(class_id=0x87) + if res is not None and len(res) > 0: + return True + else: + return False + class ZWaveNodeSwitch(ZWaveNodeInterface): """ Represents an interface to switches and dimmers Commands @@ -590,7 +657,7 @@ def set_rgbw(self, value_id, value): :param value_id: The value to retrieve state :type value_id: String - :param value: The level : a RGBW value + :param value: The level : a RGBW value :type value: int """ @@ -768,7 +835,7 @@ def set_thermostat_heating(self, value): """ logger.debug(u"set_thermostat_heating value:%s", value) for v in self.get_thermostats(): - if self.values[v].command_class == 0x43 and self.values[v].label == 'Heating 1': + if self.values[v].command_class == 0x43 and self.values[v].label in ('Heating 1', 'Heating'): self.values[v].data = value return True return False @@ -785,7 +852,7 @@ def set_thermostat_cooling(self, value): """ logger.debug(u"set_thermostat_cooling value:%s", value) for v in self.get_thermostats(): - if self.values[v].command_class == 0x43 and self.values[v].label == 'Cooling 1': + if self.values[v].command_class == 0x43 and self.values[v].label in ('Cooling 1', 'Cooling'): self.values[v].data = value return True return False @@ -888,3 +955,130 @@ def get_protection_items(self, value_id): if value_id in self.get_protections(): return self.values[value_id].data_items return None + + +class ZWaveNodeDoorLock(ZWaveNodeInterface): + """ + Represents an interface to door lock and user codes associated with door locks + """ + + def get_doorlocks(self): + """ + The command 0x62 (COMMAND_CLASS_DOOR_LOCK) of this node. + Retrieves the list of values to consider as doorlocks. + Filter rules are : + + command_class = 0x62 + genre = "User" + type = "Bool" + readonly = False + writeonly = False + + :return: The list of door locks on this node + :rtype: dict() + + """ + return self.get_values(class_id=0x62, genre='User', type='Bool', readonly=False, writeonly=False) + + def set_doorlock(self, value_id, value): + """ + The command 0x62 (COMMAND_CLASS_DOOR_LOCK) of this node. + Sets doorlock to value (using value_id). + + :param value_id: The value to retrieve state from + :type value_id: int + :param value: True or False + :type value: bool + + """ + if value_id in self.get_doorlocks(): + self.values[value_id].data = value + return True + return False + + def get_usercode(self, index): + """ + Retrieve particular usercode value by index. + Certain values such as user codes have index start from 0 + to max number of usercode supported and is useful for getting + usercodes by the index. + + :param index: The index of usercode value + :type index: int + :return: The user code at given index on this node + :rtype: ZWaveValue + + """ + usercode = self.get_usercodes(index) + if len(usercode) == 0: + return None + return list(usercode.values())[0] + + def get_usercodes(self, index='All'): + """ + The command 0x63 (COMMAND_CLASS_USER_CODE) of this node. + Retrieves the list of value to consider as usercodes. + Filter rules are : + + command_class = 0x63 + genre = "User" + type = "Raw" + readonly = False + writeonly = False + + :return: The list of user codes on this node + :rtype: dict() + + """ + return self.get_values(class_id=0x63, type='Raw', genre='User', readonly=False, writeonly=False, index=index) + + def set_usercode(self, value_id, value): + """ + The command 0x63 (COMMAND_CLASS_USER_CODE) of this node. + Sets usercode to value (using value_id). + + :param value_id: The value to retrieve state from + :type value_id: int + :param value: User Code as string + :type value: str + + """ + if value_id in self.get_usercodes(): + self.values[value_id].data = value + return True + return False + + def set_usercode_at_index(self, index, value): + """ + The command 0x63 (COMMAND_CLASS_USER_CODE) of this node. + Sets usercode to value (using index of value) + + :param index: The index of value to retrieve state from + :type index: int + :param value: User Code as string + :type value: str + + """ + usercode = self.get_usercode(index) + if usercode: + usercode.data = value + return True + return False + + + def get_doorlock_logs(self): + """ + The command 0x4c (COMMAND_CLASS_DOOR_LOCK_LOGGING) of this node. + Retrieves the value consisting of log records. + Filter rules are : + + command_class = 0x4c + genre = "User" + type = "String" + readonly = True + + :return: The dict of log records with value_id as key + :rtype: dict() + + """ + return self.get_values(class_id=0x4c, type='String', genre='User', readonly=True) diff --git a/src-api/openzwave/controller.py b/src-api/openzwave/controller.py index a4f0d68a..745740a9 100755 --- a/src-api/openzwave/controller.py +++ b/src-api/openzwave/controller.py @@ -24,15 +24,22 @@ along with python-openzwave. If not, see http://www.gnu.org/licenses. """ -import sys +import os, sys import six if six.PY3: from pydispatch import dispatcher + from urllib.request import urlopen else: from louie import dispatcher + from urllib2 import urlopen +import zipfile +import tempfile +import threading +import shutil +import time + from openzwave.object import ZWaveObject, deprecated from libopenzwave import PyStatDriver, PyControllerState -import threading # Set default logging handler to avoid "No handler found" warnings. import logging @@ -326,6 +333,17 @@ def library_version(self): """ return self._network.manager.getLibraryVersion(self._network.home_id) + @property + def python_library_flavor(self): + """ + The flavor of the python library. + + :return: The python library flavor + :rtype: str + + """ + return self._network.manager.getPythonLibraryFlavor() + @property def python_library_version(self): """ @@ -337,6 +355,23 @@ def python_library_version(self): """ return self._network.manager.getPythonLibraryVersionNumber() + @property + def python_library_config_version(self): + """ + The version of the config for python library. + + :return: The python library config version + :rtype: str + + """ + tversion = "Original %s" % self.library_version + fversion = os.path.join(self.library_config_path, 'pyozw_config.version') + if os.path.isfile(fversion): + with open(fversion, 'r') as f: + val = f.read() + tversion = "Git %s" % val + return tversion + @property def ozw_library_version(self): """ @@ -980,8 +1015,10 @@ def _lock_controller(self): }) def request_controller_status(self): - """Generate a notification with the current status of the controller. + """ + Generate a notification with the current status of the controller. You can check the lock in your code using something like this: + if controllerState in network.controller.STATES_UNLOCKED: hide_cancel_button() show_command_buttons() @@ -1048,6 +1085,7 @@ def to_dict(self, extras=['all']): ret["zw_description"] = self.library_description ret["oz_version"] = self.ozw_library_version ret["py_version"] = self.python_library_version + ret["py_config_version"] = self.python_library_config_version return ret @deprecated @@ -1314,3 +1352,58 @@ def zwcallback(self, args): dispatcher.send(self.SIGNAL_CONTROLLER, \ **{'state': state, 'message': message, 'network': self._network, 'controller': self}) + + def update_ozw_config(self): + """ + Update the openzwave config from github. + Not available for shared flavor as we don't want to update the config of the precompiled config. + + """ + if self.python_library_flavor in ['shared']: + logger.warning(u"Can't update_ozw_config for this flavor (%s)."%self.python_library_flavor) + return + logger.info(u'Update_ozw_config from github.') + dest = tempfile.mkdtemp() + dest_file = os.path.join(dest, 'open-zwave.zip') + try: + req = urlopen('https://codeload.github.com/OpenZWave/open-zwave/zip/master') + with open(dest_file, 'wb') as f: + f.write(req.read()) + zip_ref = zipfile.ZipFile(dest_file, 'r') + zip_ref.extractall(dest) + zip_ref.close() + except Exception: + logger.exception("Can't get zip from github. Cancelling") + try: + shutil.rmtree(dest) + except Exception: + pass + + if os.path.isdir(self.library_config_path): + #Try to remove old config + try: + shutil.rmtree(self.library_config_path) + except Exception: + logger.exception("Can't remove old config directory") + + try: + shutil.copytree(os.path.join(dest, 'open-zwave-master', 'config'), self.library_config_path) + except Exception: + logger.exception("Can't copy to %s", self.library_config_path) + + try: + with open(os.path.join(self.library_config_path, 'pyozw_config.version'), 'w') as f: + f.write(time.strftime("%Y-%m-%d %H:%M")) + except Exception: + logger.exception("Can't update %s", os.path.join(self.library_config_path, 'pyozw_config.version')) + + try: + with open(os.path.join(self.library_config_path, '__init__.py'), 'a') as f: + f.write("#This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave.") + except Exception: + logger.exception("Can't create %s", os.path.join(self.library_config_path, '__init__.py')) + + shutil.rmtree(dest) + + + diff --git a/src-api/openzwave/group.py b/src-api/openzwave/group.py index 177c3992..22c96d62 100755 --- a/src-api/openzwave/group.py +++ b/src-api/openzwave/group.py @@ -44,7 +44,7 @@ class ZWaveGroup(ZWaveObject): Also used to retrieve information about the library, ... """ - def __init__(self, group_index, network=None, node_id=None): + def __init__(self, group_index, network, node_id): """ Initialize driver object diff --git a/src-api/openzwave/network.py b/src-api/openzwave/network.py index 8d93eb10..91fa48b9 100755 --- a/src-api/openzwave/network.py +++ b/src-api/openzwave/network.py @@ -30,11 +30,10 @@ import six if six.PY3: from pydispatch import dispatcher - import _thread as thread else: from louie import dispatcher - import thread import threading + import libopenzwave import openzwave from openzwave.object import ZWaveException, ZWaveTypeException, ZWaveObject @@ -43,7 +42,6 @@ from openzwave.option import ZWaveOption from openzwave.scene import ZWaveScene from openzwave.singleton import Singleton -import json # Set default logging handler to avoid "No handler found" warnings. import logging @@ -64,10 +62,10 @@ def emit(self, record): class ZWaveNetwork(ZWaveObject): """ - The network objet = homeid. + The network object = homeid. It contains a reference to the manager and the controller. - It dispatch the following louie signals : + It dispatches the following louie signals : * SIGNAL_NETWORK_FAILED = 'NetworkFailed' * SIGNAL_NETWORK_STARTED = 'NetworkStarted' @@ -101,8 +99,12 @@ class ZWaveNetwork(ZWaveObject): * SIGNAL_NODE_QUERIES_COMPLETE = 'NodeQueriesComplete' * SIGNAL_AWAKE_NODES_QUERIED = 'AwakeNodesQueried' * SIGNAL_ALL_NODES_QUERIED = 'AllNodesQueried' + * SIGNAL_ALL_NODES_QUERIED_SOME_DEAD = 'AllNodesQueriedSomeDead' * SIGNAL_MSG_COMPLETE = 'MsgComplete' * SIGNAL_ERROR = 'Error' + * SIGNAL_NOTIFICATION = 'Notification' + * SIGNAL_CONTROLLER_COMMAND = 'ControllerCommand' + * SIGNAL_CONTROLLER_WAITING = 'ControllerWaiting' The table presented below sets notifications in the order they might typically be received, and grouped into a few logically related categories. Of course, given the variety @@ -221,10 +223,10 @@ class ZWaveNetwork(ZWaveObject): * ValueRemoved : Sent when a value associated with a node has been removed. * Group : Sent when a node’s group association has changed. * NodeRemoved : Sent when a node has been removed from the ZWave network. - * NodeEvent : Sent when a node sends a Basic_Set command to the controller. This notification can be generated by certain sensors, for example, motion detectors, to indicate that an event has been sensed. + * NodeEvent : Sent when a node sends a Basic_Set command to the controller. This notification can be generated by certain sensors, for example, motion detectors, to indicate that an event has been sensed. * PollingEnabled : Sent when node/value polling has been enabled. * PollingDisabled : Sent when node/value polling has been disabled. - * DriverReset : Sent to indicate when a controller has been reset. This notification is intended to replace the potentially hundreds of notifications representing each value and node removed from the network. + * DriverReset : Sent to indicate when a controller has been reset. This notification is intended to replace the potentially hundreds of notifications representing each value and node removed from the network. About the use of louie signals : For network, python-openzwave send the following louie signal : @@ -300,8 +302,8 @@ def __init__(self, options, log=None, autostart=True, kvals=True): :type log: :param autostart: should we start the network. :type autostart: bool - :param autostart: Enable kvals (use pysqlite) - :type autostart: bool + :param kvals: Enable kvals (use pysqlite) + :type kvals: bool """ logger.debug("Create network object.") @@ -674,7 +676,7 @@ def heal(self, upNodeRoute=False): """ if self.network.state < self.network.STATE_AWAKED: - logger.warning(u'Network state must a minimum set to awake') + logger.warning(u'Network must be awake') return False self.manager.healNetwork(self.home_id, upNodeRoute) return True @@ -1029,8 +1031,9 @@ def _handle_driver_ready(self, args): logger.info(u'Driver ready using library %s', self._controller.library_description) logger.info(u'home_id 0x%0.8x, controller node id is %d', self.home_id, self._controller.node_id) logger.debug(u'Network %s', self) - dispatcher.send(self.SIGNAL_DRIVER_READY, \ - **{'network': self, 'controller': self._controller}) + #Not needed. Already sent by the lib + #~ dispatcher.send(self.SIGNAL_DRIVER_READY, \ + #~ **{'network': self, 'controller': self._controller}) self._state = self.STATE_STARTED dispatcher.send(self.SIGNAL_NETWORK_STARTED, \ **{'network': self}) diff --git a/src-api/openzwave/node.py b/src-api/openzwave/node.py index 35391ab1..1c399d80 100755 --- a/src-api/openzwave/node.py +++ b/src-api/openzwave/node.py @@ -23,12 +23,14 @@ along with python-openzwave. If not, see http://www.gnu.org/licenses. """ +import sys +from libopenzwave import PyStatNode from openzwave.object import ZWaveObject from openzwave.group import ZWaveGroup from openzwave.value import ZWaveValue from openzwave.command import ZWaveNodeBasic, ZWaveNodeSwitch from openzwave.command import ZWaveNodeSensor, ZWaveNodeThermostat -from openzwave.command import ZWaveNodeSecurity +from openzwave.command import ZWaveNodeSecurity, ZWaveNodeDoorLock # Set default logging handler to avoid "No handler found" warnings. import logging @@ -45,7 +47,7 @@ def emit(self, record): class ZWaveNode(ZWaveObject, ZWaveNodeBasic, ZWaveNodeSwitch, ZWaveNodeSensor, ZWaveNodeThermostat, - ZWaveNodeSecurity): + ZWaveNodeSecurity, ZWaveNodeDoorLock): """ Represents a single Node within the Z-Wave Network. @@ -77,8 +79,12 @@ def __str__(self): :rtype: str """ - return u'home_id: [%s] id: [%s] name: [%s] model: [%s]' % \ - (self._network.home_id_str, self._object_id, self.name, self.product_name) + try: + return u'home_id: [%s] id: [%s] name: [%s] model: [%s]' % \ + (self._network.home_id_str, self._object_id, self.name, self.product_name) + except UnicodeDecodeError: + return u'home_id: [%s] id: [%s] name: [%s] model: [%s]' % \ + (self._network.home_id_str, self._object_id, self.name.decode('utf-8', 'ignore'), self.product_name.decode('utf-8', 'ignore')) @property def node_id(self): @@ -244,6 +250,8 @@ def capabilities(self): caps.add('security') if self.is_beaming_device: caps.add('beaming') + if self.is_zwave_plus: + caps.add('zwave_plus') if self.node_id == self._network.controller.node_id: for cap in self._network.controller.capabilities: caps.add(cap) @@ -414,8 +422,8 @@ def get_values_for_command_class(self, class_id): #print class_id return self.get_values(class_id=class_id) - def get_values(self, class_id='All', genre='All', \ - type='All', readonly='All', writeonly='All'): + def get_values(self, class_id='All', genre='All', type='All', \ + readonly='All', writeonly='All', index='All', label='All'): """ Retrieve the set of values. You can optionnaly filter for a command class, a genre and/or a type. You can also filter readonly and writeonly params. @@ -433,16 +441,23 @@ def get_values(self, class_id='All', genre='All', \ :type readonly: 'All' or True or False :param writeonly: Is this value writeonly :type writeonly: 'All' or True or False + :param index: Index of value within all the values + :type index: int + :param label: Label of the value as set by openzwave + :type label: str :rtype: set() of Values """ ret = dict() - for value in self.values: + valkeys = self.values.keys() + for value in valkeys: if (class_id == 'All' or self.values[value].command_class == class_id) and \ (genre == 'All' or self.values[value].genre == genre) and \ (type == 'All' or self.values[value].type == type) and \ (readonly == 'All' or self.values[value].is_read_only == readonly) and \ - (writeonly == 'All' or self.values[value].is_write_only == writeonly): + (writeonly == 'All' or self.values[value].is_write_only == writeonly) and \ + (index == 'All' or self.values[value].index == index) and \ + (label == 'All' or self.values[value].label == label): ret[value] = self.values[value] return ret @@ -1041,3 +1056,45 @@ def type(self): :rtype: str """ return self._network.manager.getNodeType(self.home_id, self.object_id) + + @property + def stats(self): + """ + Retrieve statistics for node. + + Statistics: + + * sentCnt : Number of messages sent from this node. + * sentFailed : Number of sent messages failed + * retries : Number of message retries + * receivedCnt : Number of messages received from this node. + * receivedDups : Number of duplicated messages received; + * receivedUnsolicited : Number of messages received unsolicited + * lastRequestRTT : Last message request RTT + * lastResponseRTT : Last message response RTT + * sentTS : Last message sent time + * receivedTS : Last message received time + * averageRequestRTT : Average Request round trip time. + * averageResponseRTT : Average Response round trip time. + * quality : Node quality measure + * lastReceivedMessage[254] : Place to hold last received message + * errors : Count errors for dead node detection + + :return: Statistics of the node + :rtype: dict() + + """ + return self._network.manager.getNodeStatistics(self.home_id, self.object_id) + + def get_stats_label(self, stat): + """ + Retrieve label of the statistic for node. + + :param stat: The code of the stat label to retrieve. + :type stat: + :return: The label or the stat. + :rtype: str + + """ + #print "stat = %s" % stat + return PyStatNode[stat] diff --git a/src-api/openzwave/option.py b/src-api/openzwave/option.py index 8ee3e709..7fc68990 100755 --- a/src-api/openzwave/option.py +++ b/src-api/openzwave/option.py @@ -43,16 +43,42 @@ def emit(self, record): logger = logging.getLogger('openzwave') logger.addHandler(NullHandler()) + +VENDOR_IDS = ('0658',) + + +def _get_z_stick(): + try: + import serial.tools.list_ports + except ImportError: + return None + + for port in serial.tools.list_ports.comports(include_links=False): + if port.vid is None: + continue + if port.product is not None and 'Zigbee' in port.product: + continue + if port.interface is not None and 'Zigbee' in port.interface: + continue + if port.description is not None and 'Zigbee' in port.description: + continue + + for vid in VENDOR_IDS: + if vid.upper() == hex(port.vid)[2:].upper().zfill(4): + return port.device + return None + + class ZWaveOption(libopenzwave.PyOptions): """ Represents a Zwave option used to start the manager. """ - def __init__(self, device=None, config_path=None, user_path=".", cmd_line=""): + def __init__(self, device=None, config_path=None, user_path=None, cmd_line=None): """ Create an option object and check that parameters are valid. - :param device: The device to use + :param device: The device to use or None for auto detection (pyserial needs to be installed for auto detection). :type device: str :param config_path: The openzwave config directory. If None, try to configure automatically. :type config_path: str @@ -62,7 +88,13 @@ def __init__(self, device=None, config_path=None, user_path=".", cmd_line=""): :type cmd_line: str """ + if device is None: + device = _get_z_stick() + if platform_system() == 'Windows': + if device and not device.startswith('\\\\.\\'): + device = '\\\\.\\' + device + self._device = device else: #For linux @@ -80,8 +112,6 @@ def __init__(self, device=None, config_path=None, user_path=".", cmd_line=""): import sys, traceback raise ZWaveException(u"Error when retrieving device %s : %s" % (device, traceback.format_exception(*sys.exc_info()))) libopenzwave.PyOptions.__init__(self, config_path=config_path, user_path=user_path, cmd_line=cmd_line) - self._user_path = user_path - self._config_path = config_path def set_log_file(self, logfile): """ diff --git a/src-api/openzwave/scene.py b/src-api/openzwave/scene.py index 2d5a722e..5911c9b8 100755 --- a/src-api/openzwave/scene.py +++ b/src-api/openzwave/scene.py @@ -42,7 +42,7 @@ class ZWaveScene(ZWaveObject): Represents a single scene within the Z-Wave Network """ - def __init__(self, scene_id, network=None): + def __init__(self, scene_id, network): """ Initialize zwave scene diff --git a/src-api/openzwave/value.py b/src-api/openzwave/value.py index 46793800..8f4498d9 100755 --- a/src-api/openzwave/value.py +++ b/src-api/openzwave/value.py @@ -555,8 +555,10 @@ def to_dict(self, extras=['all']): :rtype: dict() """ + attrs = [] if 'all' in extras: - extras = ['kvals'] + extras = ['kvals'] + attrs = ['data_items', 'command_class', 'is_read_only', 'is_write_only', 'type', 'index'] ret={} ret['label'] = self.label ret['value_id'] = self.value_id @@ -564,6 +566,9 @@ def to_dict(self, extras=['all']): ret['units'] = self.units ret['genre'] = self.genre ret['data'] = self.data + + for k in attrs: + ret[k] = getattr(self, k) if 'kvals' in extras and self.network.dbcon is not None: vals = self.kvals for key in vals.keys(): diff --git a/src-lib/libopenzwave/libopenzwave.pyx b/src-lib/libopenzwave/libopenzwave.pyx index aec83ad1..2753a7d5 100644 --- a/src-lib/libopenzwave/libopenzwave.pyx +++ b/src-lib/libopenzwave/libopenzwave.pyx @@ -58,6 +58,7 @@ import os import sys import warnings import six +from shutil import copyfile # Set default logging handler to avoid "No handler found" warnings. import logging @@ -72,23 +73,33 @@ logger = logging.getLogger('libopenzwave') logger.addHandler(NullHandler()) from pkg_resources import get_distribution, DistributionNotFound -__version__ = "0.3.1" + +cdef extern from 'pyversion.h': + string PY_LIB_VERSION_STRING + string PY_LIB_FLAVOR_STRING + string PY_LIB_BACKEND_STRING + string PY_LIB_DATE_STRING + string PY_LIB_TIME_STRING + +__version__ = PY_LIB_VERSION_STRING + +#For historical ways of working libopenzwave_location = 'not_installed' libopenzwave_file = 'not_installed' try: _dist = get_distribution('libopenzwave') except DistributionNotFound: - __version__ = 'Not installed' + pass else: - __version__ = _dist.version libopenzwave_location = _dist.location if libopenzwave_location == 'not_installed' : try: _dist = get_distribution('libopenzwave') - __version__ = _dist.version libopenzwave_file = _dist.__file__ except AttributeError: libopenzwave_file = 'not_installed' + except DistributionNotFound: + libopenzwave_file = 'not_installed' cdef string str_to_cppstr(str s): if isinstance(s, unicode): @@ -309,7 +320,7 @@ PyOptionList = { 'IntervalBetweenPolls' : {'doc' : "If false, try to execute the entire poll list within the PollInterval time frame. If true, wait for PollInterval milliseconds between polls.", 'type' : "Bool"}, 'SuppressValueRefresh' : {'doc' : "If true, notifications for refreshed (but unchanged) values will not be sent.", 'type' : "Bool"}, 'PerformReturnRoutes' : {'doc' : "If true, return routes will be updated.", 'type' : "Bool"}, - 'NetworkKey' : {'doc' : ".", 'type' : "String"}, + 'NetworkKey' : {'doc' : "Key used to negotiate and communicate with devices that support Security Command Class", 'type' : "String"}, 'RefreshAllUserCodes' : {'doc' : "If true, during startup, we refresh all the UserCodes the device reports it supports. If False, we stop after we get the first 'Available' slot (Some devices have 250+ usercode slots! - That makes our Session Stage Very Long ).", 'type' : "Bool"}, 'RetryTimeout' : {'doc' : "How long do we wait to timeout messages sent.", 'type' : "Int"}, 'EnableSIS' : {'doc' : "Automatically become a SUC if there is no SUC on the network.", 'type' : "Bool"}, @@ -317,6 +328,7 @@ PyOptionList = { 'NotifyOnDriverUnload' : {'doc' : "Should we send the Node/Value Notifications on Driver Unloading - Read comments in Driver::~Driver() method about possible race conditions.", 'type' : "Bool"}, 'SecurityStrategy' : {'doc' : "Should we encrypt CC's that are available via both clear text and Security CC?.", 'type' : "String", 'value' : 'SUPPORTED'}, 'CustomSecuredCC' : {'doc' : "What List of Custom CC should we always encrypt if SecurityStrategy is CUSTOM.", 'type' : "String", 'value' : '0x62,0x4c,0x63'}, + 'EnforceSecureReception' : {'doc' : "If we recieve a clear text message for a CC that is Secured, should we drop the message", 'type' : "Bool"}, } PyStatDriver = { @@ -342,6 +354,24 @@ PyStatDriver = { 'broadcastWriteCnt' : "Number of broadcasts sent", } +PyStatNode = { + 'sentCnt' : "Number of messages sent from this node", + 'sentFailed' : "Number of sent messages failed", + 'retries' : "Number of message retries", + 'receivedCnt' : "Number of messages received from this node", + 'receivedDups' : "Number of duplicated messages received", + 'receivedUnsolicited' : "Number of messages received unsolicited", + 'lastRequestRTT' : "Last message request RTT", + 'lastResponseRTT' : "Last message response RTT", + 'sentTS' : "Last message sent time", + 'receivedTS' : "Last message received time", + 'averageRequestRTT' : "Average Request round trip time", + 'averageResponseRTT' : "Average Response round trip time", + 'quality' : "Node quality measure", + 'lastReceivedMessage' : "Place to hold last received message", + 'errors' : "Count errors for dead node detection", + } + PyLogLevels = { 'Invalid' : {'doc':'Invalid Log Status', 'value':0}, 'None' : {'doc':'Disable all logging', 'value':1}, @@ -435,7 +465,6 @@ cdef addValueId(ValueID v, n): return logger.debug("addValueId : GetCommandClassId : %s, GetType : %s", v.GetCommandClassId(), v.GetType()) cdef Manager *manager = GetManager() - #values_map.insert(pair[uint64_t, ValueID](v.GetId(), v)) item = new pair[uint64_t, ValueID](v.GetId(), v) values_map.insert(deref(item)) del item @@ -490,18 +519,18 @@ cdef void notif_callback(const_notification _notification, void* _context) with try: n['groupIdx'] = notification.GetGroupIdx() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_Group") elif notification.GetType() == Type_NodeEvent: try: n['event'] = notification.GetEvent() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_NodeEvent") raise elif notification.GetType() == Type_Notification: try: n['notificationCode'] = notification.GetNotification() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_Notification") raise elif notification.GetType() == Type_ControllerCommand: try: @@ -515,45 +544,45 @@ cdef void notif_callback(const_notification _notification, void* _context) with n['controllerError'] = PyControllerError[error] n['controllerErrorDoc'] = PyControllerError[error].doc except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_ControllerCommand") raise elif notification.GetType() in (Type_CreateButton, Type_DeleteButton, Type_ButtonOn, Type_ButtonOff): try: n['buttonId'] = notification.GetButtonId() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_CreateButton, Type_DeleteButton, Type_ButtonOn, Type_ButtonOff") raise elif notification.GetType() == Type_DriverRemoved: try: logger.debug("Notification : Type_DriverRemoved received : clean all valueids") values_map.empty() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_DriverRemoved") raise elif notification.GetType() == Type_DriverReset: try: logger.debug("Notification : Type_DriverReset received : clean all valueids") values_map.empty() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_DriverReset") raise elif notification.GetType() == Type_SceneEvent: try: n['sceneId'] = notification.GetSceneId() except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_SceneEvent") raise elif notification.GetType() in (Type_ValueAdded, Type_ValueChanged, Type_ValueRefreshed): try: addValueId(notification.GetValueID(), n) except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_ValueAdded, Type_ValueChanged, Type_ValueRefreshed") raise elif notification.GetType() == Type_ValueRemoved: try: n['valueId'] = {'id' : notification.GetValueID().GetId()} except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_ValueRemoved") raise #elif notification.GetType() in (Type_PollingEnabled, Type_PollingDisabled): # #Maybe we should enable/disable this @@ -564,7 +593,7 @@ cdef void notif_callback(const_notification _notification, void* _context) with try: delValueId(notification.GetValueID(), n) except: - logger.exception("notif_callback exception") + logger.exception("notif_callback exception Type_ValueRemoved delete") raise logger.debug("notif_callback : end") @@ -592,23 +621,42 @@ def configPath(): :rtype: str ''' - if os.path.isdir(os.path.join("/usr",PY_OZWAVE_CONFIG_DIRECTORY)): - return os.path.join("/usr",PY_OZWAVE_CONFIG_DIRECTORY) - elif os.path.isdir(os.path.join("/etc","openzwave")): - return os.path.join("/etc","openzwave") - elif os.path.isdir(os.path.join("/usr/local",PY_OZWAVE_CONFIG_DIRECTORY)): - return os.path.join("/usr/local",PY_OZWAVE_CONFIG_DIRECTORY) - elif os.path.isdir(os.path.join("/usr",OZWAVE_CONFIG_DIRECTORY)): - return os.path.join("/usr",OZWAVE_CONFIG_DIRECTORY) - elif os.path.isdir(os.path.join("/usr/local",OZWAVE_CONFIG_DIRECTORY)): - return os.path.join("/usr/local",OZWAVE_CONFIG_DIRECTORY) - else: - if os.path.isdir(os.path.join(os.path.dirname(libopenzwave_file),PY_OZWAVE_CONFIG_DIRECTORY)): - return os.path.join(os.path.dirname(libopenzwave_file), PY_OZWAVE_CONFIG_DIRECTORY) - if os.path.isdir(os.path.join(os.getcwd(),CWD_CONFIG_DIRECTORY)): - return os.path.join(os.getcwd(),CWD_CONFIG_DIRECTORY) - if os.path.isdir(os.path.join(libopenzwave_location,PY_OZWAVE_CONFIG_DIRECTORY)): - return os.path.join(libopenzwave_location, PY_OZWAVE_CONFIG_DIRECTORY) + if os.path.isfile(os.path.join("/etc/openzwave/",'device_classes.xml')): + #At first, check in /etc/openzwave + return "/etc/openzwave/" + elif os.path.isfile(os.path.join("/usr/local/etc/openzwave/",'device_classes.xml')): + #Next, check in /usr/local/etc/openzwave + return "/usr/local/etc/openzwave/" + else : + #Check in python_openzwave.resources + dirn = None + try: + from pkg_resources import resource_filename + dirn = resource_filename('python_openzwave.ozw_config', '__init__.py') + dirn = os.path.dirname(dirn) + except ImportError: + dirn = None + if dirn is not None and os.path.isfile(os.path.join(dirn,'device_classes.xml')): + #At first, check in /etc/openzwave + return dirn + elif os.path.isfile(os.path.join("openzwave/config",'device_classes.xml')): + return os.path.abspath('openzwave/config') + #For historical reasons. + elif os.path.isdir(os.path.join("/usr",PY_OZWAVE_CONFIG_DIRECTORY)): + return os.path.join("/usr",PY_OZWAVE_CONFIG_DIRECTORY) + elif os.path.isdir(os.path.join("/usr/local",PY_OZWAVE_CONFIG_DIRECTORY)): + return os.path.join("/usr/local",PY_OZWAVE_CONFIG_DIRECTORY) + elif os.path.isdir(os.path.join("/usr",OZWAVE_CONFIG_DIRECTORY)): + return os.path.join("/usr",OZWAVE_CONFIG_DIRECTORY) + elif os.path.isdir(os.path.join("/usr/local",OZWAVE_CONFIG_DIRECTORY)): + return os.path.join("/usr/local",OZWAVE_CONFIG_DIRECTORY) + else: + if os.path.isdir(os.path.join(os.path.dirname(libopenzwave_file),PY_OZWAVE_CONFIG_DIRECTORY)): + return os.path.join(os.path.dirname(libopenzwave_file), PY_OZWAVE_CONFIG_DIRECTORY) + if os.path.isdir(os.path.join(os.getcwd(),CWD_CONFIG_DIRECTORY)): + return os.path.join(os.getcwd(),CWD_CONFIG_DIRECTORY) + if os.path.isdir(os.path.join(libopenzwave_location,PY_OZWAVE_CONFIG_DIRECTORY)): + return os.path.join(libopenzwave_location, PY_OZWAVE_CONFIG_DIRECTORY) return None cdef class PyOptions: @@ -616,13 +664,13 @@ cdef class PyOptions: Manage options manager """ - cdef str _config_path - cdef str _user_path - cdef str _cmd_line + cdef readonly str _config_path + cdef readonly str _user_path + cdef readonly str _cmd_line cdef Options *options - def __init__(self, config_path=None, user_path=".", cmd_line=""): + def __init__(self, config_path=None, user_path=None, cmd_line=None): """ Create an option object and check that parameters are valid. @@ -710,6 +758,11 @@ cdef class PyOptions: :see: areLocked_ """ + if not os.path.isfile(os.path.join(self._user_path,'options.xml')): + if os.path.isfile(os.path.join(self._config_path,'options.xml')): + copyfile(os.path.join(self._config_path,'options.xml'), os.path.join(self._user_path,'options.xml')) + else: + logger.warning("Can't find options.xml in %s"%self._config_path) return self.options.Lock() def areLocked(self): @@ -1026,8 +1079,8 @@ sleeping) have been polled, an "AllNodesQueried" notification is sent. 0x56: 'COMMAND_CLASS_CRC_16_ENCAP', 0x5A: 'COMMAND_CLASS_DEVICE_RESET_LOCALLY', 0x5B: 'COMMAND_CLASS_CENTRAL_SCENE', - 0x5E: 'COMMAND_CLASS_ZWAVE_PLUS_INFO', - 0x60: 'COMMAND_CLASS_MULTI_CHANNEL_V2', + 0x5E: 'COMMAND_CLASS_ZWAVEPLUS_INFO', + 0x60: 'COMMAND_CLASS_MULTI_INSTANCE/CHANNEL', 0x61: 'COMMAND_CLASS_DISPLAY', 0x62: 'COMMAND_CLASS_DOOR_LOCK', 0x63: 'COMMAND_CLASS_USER_CODE', @@ -1060,7 +1113,7 @@ sleeping) have been polled, an "AllNodesQueried" notification is sent. 0x8B: 'COMMAND_CLASS_TIME_PARAMETERS', 0x8C: 'COMMAND_CLASS_GEOGRAPHIC_LOCATION', 0x8D: 'COMMAND_CLASS_COMPOSITE', - 0x8E: 'COMMAND_CLASS_MULTI_INSTANCE_ASSOCIATION', + 0x8E: 'COMMAND_CLASS_MULTI_CHANNEL_ASSOCIATION', 0x8F: 'COMMAND_CLASS_MULTI_CMD', 0x90: 'COMMAND_CLASS_ENERGY_PRODUCTION', 0x91: 'COMMAND_CLASS_MANUFACTURER_PROPRIETARY', @@ -1331,6 +1384,19 @@ Get the version of the Z-Wave API library used by a controller. cdef string c_string = self.manager.GetLibraryVersion(homeid) return cstr_to_str(c_string.c_str()) + def getPythonLibraryFlavor(self): + ''' +.. _getPythonLibraryFlavor: + +Get the flavor of the python library. + +:return: A string containing the python library flavor. For example, "embed". +:rtype: str +:see: getLibraryTypeName_, getLibraryVersion_, getOzwLibraryVersion_, getOzwLibraryLongVersion + + ''' + return "%s" % (PY_LIB_FLAVOR_STRING) + def getPythonLibraryVersion(self): ''' .. _getPythonLibraryVersion: @@ -1342,7 +1408,7 @@ Get the version of the python library. :see: getLibraryTypeName_, getLibraryVersion_, getOzwLibraryVersion_, getOzwLibraryLongVersion ''' - return "python-openzwave version %s" % PYLIBRARY + return "python_openzwave version %s (%s-%s / %s - %s)" % (PYLIBRARY, PY_LIB_FLAVOR_STRING, PY_LIB_BACKEND_STRING, PY_LIB_DATE_STRING, PY_LIB_TIME_STRING) def getPythonLibraryVersionNumber(self): """ @@ -1762,10 +1828,6 @@ Statistics: * averageResponseRTT #Average Reponse round trip time. * quality # Node quality measure * lastReceivedMessage[254] # Place to hold last received message - * ccData # List of statistic - * commandClassId # Num of commandClass id. - * sentCnt # Number of messages sent from this CommandClass. - * receivedCnt # Number of messages received from this CommandClass. :param homeId: The Home ID of the Z-Wave controller. :type homeId: int @@ -1798,16 +1860,6 @@ Statistics: ret['lastReceivedMessage'] = [] for i in range( 0, 254) : ret['lastReceivedMessage'] .append(data.m_lastReceivedMessage[i]) - listccdata =[] - while not data.m_ccData.empty() : - ccd = {} - temp = data.m_ccData.back() - ccd['commandClassId'] = temp.m_commandClassId - ccd['sentCnt'] = temp.m_sentCnt - ccd['receivedCnt'] = temp.m_receivedCnt - listccdata.append(ccd) - data.m_ccData.pop_back(); - ret['ccData'] = listccdata return ret def requestNodeDynamic(self, homeid, nodeid): @@ -2824,7 +2876,10 @@ if the Z-Wave message actually failed to get through. Notification callbacks wi cret = self.manager.SetValue(values_map.at(id), type_short) ret = 1 if cret else 0 elif datatype == "String": - type_string = string(value) + if six.PY3: + type_string = str_to_cppstr(value) + else: + type_string = str_to_cppstr(string(value)) cret = self.manager.SetValue(values_map.at(id), type_string) ret = 1 if cret else 0 elif datatype == "Button": @@ -2832,8 +2887,11 @@ if the Z-Wave message actually failed to get through. Notification callbacks wi cret = self.manager.SetValue(values_map.at(id), type_bool) ret = 1 if cret else 0 elif datatype == "List": - type_string = string(value) logger.debug("SetValueListSelection %s", value) + if six.PY3: + type_string = str_to_cppstr(value) + else: + type_string = str_to_cppstr(string(value)) cret = self.manager.SetValueListSelection(values_map.at(id), type_string) logger.debug("SetValueListSelection %s", cret) ret = 1 if cret else 0 @@ -3309,6 +3367,24 @@ getValueType_, getValueInstance_, getValueIndex_ Gets a value as a string. +:param id: The ID of a value. +:type id: int +:return: The value +:rtype: str +:see: isValueSet_, getValue_, getValueAsBool_, getValueAsByte_, \ +getValueListSelectionStr_ , getValueListSelectionNum_, \ +getValueAsFloat_, getValueAsShort_, getValueAsInt_, getValueListItems_, \ +getValueType_, getValueInstance_, getValueIndex_ + + ''' + return getValueFromType(self.manager,id) + + def getValueAsRaw(self, id): + ''' +.. _getValueAsRaw: + +Gets a value as raw. + :param id: The ID of a value. :type id: int :return: The value diff --git a/src-lib/libopenzwave/node.pxd b/src-lib/libopenzwave/node.pxd index f8e076f1..9f99d72d 100755 --- a/src-lib/libopenzwave/node.pxd +++ b/src-lib/libopenzwave/node.pxd @@ -18,8 +18,6 @@ along with python-openzwave. If not, see http://www.gnu.org/licenses. """ from libc.stdint cimport uint32_t, int32_t, int16_t, uint8_t, int8_t -from libcpp.vector cimport vector -#from libcpp.string cimport string from mylibc cimport string cdef extern from "Node.h" namespace "OpenZWave::Node": @@ -46,15 +44,15 @@ cdef extern from "Node.h" namespace "OpenZWave::Node": uint32_t m_receivedCnt # Number of messages received from this node. uint32_t m_receivedDups # Number of duplicated messages received; uint32_t m_receivedUnsolicited # Number of messages received unsolicited + uint32_t m_lastRequestRTT # Last message request RTT + uint32_t m_lastResponseRTT # Last message response RTT string m_sentTS # Last message sent time string m_receivedTS # Last message received time - uint32_t m_lastRequestRTT # Last message request RTT uint32_t m_averageRequestRTT # Average Request Round Trip Time (ms). - uint32_t m_lastResponseRTT # Last message response RTT uint32_t m_averageResponseRTT #Average Reponse round trip time. uint8_t m_quality # Node quality measure uint8_t m_lastReceivedMessage[254] # Place to hold last received message - vector[CommandClassData] m_ccData # List of statistic on each command_class + uint8_t m_errors # Count errors for dead node detection ctypedef NodeData NodeData_t diff --git a/src-lib/libopenzwave/pyversion.h b/src-lib/libopenzwave/pyversion.h new file mode 100644 index 00000000..09834e8b --- /dev/null +++ b/src-lib/libopenzwave/pyversion.h @@ -0,0 +1,22 @@ +#define STRINGIZER(arg) #arg +#define STR_VALUE(arg) STRINGIZER(arg) +#ifdef PY_LIB_VERSION +#define PY_LIB_VERSION_STRING STR_VALUE(PY_LIB_VERSION) +#endif +#ifndef PY_LIB_VERSION +#define PY_LIB_VERSION_STRING STR_VALUE("Undef") +#endif +#ifdef PY_LIB_FLAVOR +#define PY_LIB_FLAVOR_STRING STR_VALUE(PY_LIB_FLAVOR) +#endif +#ifndef PY_LIB_FLAVOR +#define PY_LIB_FLAVOR_STRING STR_VALUE("embed") +#endif +#define PY_LIB_DATE_STRING __DATE__ +#define PY_LIB_TIME_STRING __TIME__ +#ifdef PY_LIB_BACKEND +#define PY_LIB_BACKEND_STRING STR_VALUE(PY_LIB_BACKEND) +#endif +#ifndef PY_LIB_BACKEND +#define PY_LIB_BACKEND_STRING STR_VALUE("cython") +#endif diff --git a/src-manager/pyozwman/ozwsh_main.py b/src-manager/pyozwman/ozwsh_main.py index c036cbc2..f5150e4a 100755 --- a/src-manager/pyozwman/ozwsh_main.py +++ b/src-manager/pyozwman/ozwsh_main.py @@ -31,12 +31,18 @@ from select import select import sys import os +from traceback import format_exc +import logging +import six +if six.PY3: + from pydispatch import dispatcher +else: + from louie import dispatcher import urwid from urwid.raw_display import Screen #import headerpanel #import dirpanel #import setuppanel -from traceback import format_exc #from ucp import UrwidCmdProc, isUCP #from utils import utilInit, log from openzwave.node import ZWaveNode @@ -59,8 +65,6 @@ from pyozwman.ozwsh_widgets import ScenesTree, ScenesBox, ScenesItem from pyozwman.ozwsh_widgets import StatTree, StatBox -from louie import dispatcher, All -import logging MAIN_TITLE = "openzwave Shell" """ diff --git a/src-manager/pyozwman/ozwsh_widgets.py b/src-manager/pyozwman/ozwsh_widgets.py index 7784422b..9c892614 100755 --- a/src-manager/pyozwman/ozwsh_widgets.py +++ b/src-manager/pyozwman/ozwsh_widgets.py @@ -30,16 +30,21 @@ from select import select import sys import os +from traceback import format_exc +import six +if six.PY3: + from pydispatch import dispatcher +else: + from louie import dispatcher import urwid from urwid.raw_display import Screen -from traceback import format_exc from openzwave.node import ZWaveNode from openzwave.value import ZWaveValue from openzwave.scene import ZWaveScene from openzwave.controller import ZWaveController from openzwave.network import ZWaveNetwork from openzwave.option import ZWaveOption -from louie import dispatcher, All + import logging class OldestTree(urwid.ListWalker): @@ -423,9 +428,11 @@ def read_lines(self): self.lines.append(urwid.Text( " %s:%s" % (groups[group].index,groups[group].label), align='left')) self.size += 1 for assoc in groups[group].associations: - self.lines.append(AssociationItem(assoc, \ - self.window.network.nodes[assoc].name - )) + if assoc in self.window.network.nodes: + aname = self.window.network.nodes[assoc].name + else: + aname = "[%d missing]" % (assoc) + self.lines.append(AssociationItem(assoc, aname)) self.size += 1 self._modified() @@ -473,7 +480,7 @@ def remove(self, param, value): self.window.status_bar.update(status="Invalid index or node ID %s/%s" % (param, value)) return False if param in self.window.network.nodes[self.node_id].groups: - if value in self.window.network.nodes[self.node_id].groups : + if value in self.window.network.nodes[self.node_id].groups[param].associations : self.window.network.nodes[self.node_id].groups[param].remove_association(value) self.window.status_bar.update(status='Group %s updated' % param) return True @@ -1335,7 +1342,7 @@ def add(self, param, value): def set(self, param, value): values = self.window.network.nodes[self.node_id].values try: - param = long(param) + param = int(param) except: ok = False for val in values: @@ -1368,7 +1375,7 @@ def set(self, param, value): def poll(self, param, value): values = self.window.network.nodes[self.node_id].values try: - param = long(param) + param = int(param) except: ok = False for val in values: @@ -1968,7 +1975,7 @@ def cd(self, directory): def delete(self, value): valueid = None try: - valueid = long(value) + valueid = int(value) except: ok = False try: diff --git a/src-python_openzwave/python_openzwave/__init__.py b/src-python_openzwave/python_openzwave/__init__.py new file mode 100755 index 00000000..ea37a028 --- /dev/null +++ b/src-python_openzwave/python_openzwave/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +__license__ = """ + +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. +""" +__copyright__ = "Copyright © 2012-2015 Sébastien GALLET aka bibi21000" +__author__ = 'Sébastien GALLET aka bibi21000' +__email__ = 'bibi21000@gmail.com' + +try: + __import__('pkg_resources').declare_namespace("python_openzwave") +except: + # bootstrapping + pass diff --git a/src-python_openzwave/python_openzwave/ozw_config/__init__.py b/src-python_openzwave/python_openzwave/ozw_config/__init__.py new file mode 100755 index 00000000..63fadf1a --- /dev/null +++ b/src-python_openzwave/python_openzwave/ozw_config/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +__license__ = """ + +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. +""" +__copyright__ = "Copyright © 2012-2015 Sébastien GALLET aka bibi21000" +__author__ = 'Sébastien GALLET aka bibi21000' +__email__ = 'bibi21000@gmail.com' diff --git a/src-python_openzwave/python_openzwave/scripts/__init__.py b/src-python_openzwave/python_openzwave/scripts/__init__.py new file mode 100755 index 00000000..240ad6d1 --- /dev/null +++ b/src-python_openzwave/python_openzwave/scripts/__init__.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +__license__ = """ + +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. +""" +__copyright__ = "Copyright © 2012-2015 Sébastien GALLET aka bibi21000" +__author__ = 'Sébastien GALLET aka bibi21000' +__email__ = 'bibi21000@gmail.com' + +try: + __import__('pkg_resources').declare_namespace("openzwave") +except: + # bootstrapping + pass diff --git a/src-python_openzwave/python_openzwave/scripts/pyozw_check.py b/src-python_openzwave/python_openzwave/scripts/pyozw_check.py new file mode 100644 index 00000000..0d888a2f --- /dev/null +++ b/src-python_openzwave/python_openzwave/scripts/pyozw_check.py @@ -0,0 +1,284 @@ +#!python +# -*- coding: utf-8 -*- +""" +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + :platform: Unix, Windows, MacOS X + +.. moduleauthor:: bibi21000 aka Sébastien GALLET + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +""" +import logging +h = logging.NullHandler() +logger = logging.getLogger(__name__).addHandler(h) +import time +import argparse + +network_state = None +home_id = None +args = None + +def imports(args): + if args.timeout is None: + args.timeout = 2 + if args.output == 'txt': + print("-------------------------------------------------------------------------------") + print("Import libs") + print("Try to import libopenzwave") + import libopenzwave + print("Try to import libopenzwave.PyLogLevels") + from libopenzwave import PyLogLevels + print("Try to get options") + options = libopenzwave.PyOptions(user_path=".", cmd_line="--logging false") + options.lock() + time.sleep(0.5) + print("Try to get manager") + manager = libopenzwave.PyManager() + manager.create() + print("Try to get python_openzwave version") + print(manager.getPythonLibraryVersionNumber()) + print("Try to get python_openzwave full version") + print(manager.getPythonLibraryVersion()) + print("Try to get openzwave version") + print(manager.getPythonLibraryVersion()) + print("Try to get openzwave version") + print(manager.getOzwLibraryVersion()) + print("Try to get default config path") + print(libopenzwave.configPath()) + print("Try to destroy manager") + manager.destroy() + print("Try to destroy options") + options.destroy() + time.sleep(0.5) + print("Try to import openzwave (API)") + import openzwave + + elif args.output == 'raw': + import libopenzwave + from libopenzwave import PyLogLevels + options = libopenzwave.PyOptions(user_path=".", cmd_line="--logging false") + options.lock() + time.sleep(0.5) + manager = libopenzwave.PyManager() + manager.create() + print("{0}|{1}|{2}|{3}".format( + manager.getOzwLibraryVersion(), + manager.getPythonLibraryVersionNumber(), + manager.getPythonLibraryVersion(), + libopenzwave.configPath() + )) + manager.destroy() + options.destroy() + time.sleep(0.5) + import openzwave + +def zwcallback(zwargs): + import libopenzwave + global args + if args.output == 'txt': + print('--------------------------------- zwcallback with args=[%s]' % zwargs) + notify_type = zwargs['notificationType'] + global network_state + network_state = notify_type + if notify_type == "DriverReady": + global home_id + home_id = zwargs['homeId'] + + #~ print("Received {0} : {1}".format(notify_type,libopenzwave.PyNotifications[notify_type].doc)) + if args.output == 'txt': + print("Received {0}".format(notify_type)) + +def init_device(args): + global home_id + if args.timeout is None: + args.timeout = 15 + if args.output == 'txt': + print("-------------------------------------------------------------------------------") + print("Intialize device {0}".format(args.device)) + import libopenzwave + print("Try to get options") + options = libopenzwave.PyOptions(config_path=args.config_path, user_path=args.user_path, cmd_line="--logging true") + options.lock() + time.sleep(1.0) + print("Try to get manager") + manager = libopenzwave.PyManager() + manager.create() + print("Try to get python_openzwave version") + print(manager.getPythonLibraryVersionNumber()) + print("Try to get python_openzwave full version") + print(manager.getPythonLibraryVersion()) + print("Try to get openzwave version") + print(manager.getOzwLibraryVersion()) + print("Try to get default config path") + print(libopenzwave.configPath()) + print("Try to add watcher") + manager.addWatcher(zwcallback) + time.sleep(1.0) + manager.addDriver(args.device) + print("Wait for notifications ({0}s)".format(args.timeout)) + next_print = args.timeout/10 + delta = 0.1 + for i in range(0, int(args.timeout/delta)): + time.sleep(delta) + next_print -= delta + if next_print < 0: + next_print = args.timeout/10 + print('.') + print("Try to remove driver") + manager.removeDriver(args.device) + time.sleep(3.0) + print("Try to remove watcher") + manager.removeWatcher(zwcallback) + print("Try to destroy manager") + manager.destroy() + time.sleep(0.2) + print("Try to destroy options") + options.destroy() + time.sleep(1.0) + print("Retrieve HomeID") + print("{0:08x}".format(home_id)) + elif args.output == 'raw': + import libopenzwave + options = libopenzwave.PyOptions(config_path=args.config_path, user_path=args.user_path, cmd_line="--logging false") + options.lock() + time.sleep(1.0) + manager = libopenzwave.PyManager() + manager.create() + manager.addWatcher(zwcallback) + time.sleep(1.0) + manager.addDriver(args.device) + next_print = args.timeout/10 + delta = 0.1 + for i in range(0, int(args.timeout/delta)): + time.sleep(delta) + print("{0}|{1}|{2}|{3}|{4:08x}".format( + manager.getOzwLibraryVersion(), + manager.getPythonLibraryVersionNumber(), + manager.getPythonLibraryVersion(), + libopenzwave.configPath(), + home_id, + )) + manager.removeDriver(args.device) + time.sleep(0.5) + manager.removeWatcher(zwcallback) + manager.destroy() + time.sleep(0.2) + options.destroy() + +def list_nodes(args): + global home_id + if args.timeout is None: + args.timeout = 60*60*4+1 + import openzwave + from openzwave.node import ZWaveNode + from openzwave.value import ZWaveValue + from openzwave.scene import ZWaveScene + from openzwave.controller import ZWaveController + from openzwave.network import ZWaveNetwork + from openzwave.option import ZWaveOption + + #Define some manager options + print("-------------------------------------------------------------------------------") + print("Define options for device {0}".format(args.device)) + options = ZWaveOption(device=args.device, config_path=args.config_path, user_path=args.user_path) + options.set_log_file("OZW_Log.log") + options.set_append_log_file(False) + options.set_console_output(False) + options.set_save_log_level("Debug") + options.set_logging(True) + options.lock() + + print("Start network") + network = ZWaveNetwork(options, log=None) + + delta = 0.5 + for i in range(0, int(args.timeout/delta)): + time.sleep(delta) + if network.state >= network.STATE_AWAKED: + break + + print("-------------------------------------------------------------------------------") + print("Network is awaked. Talk to controller.") + print("Get python_openzwave version : {}".format(network.controller.python_library_version)) + print("Get python_openzwave config version : {}".format(network.controller.python_library_config_version)) + print("Get python_openzwave flavor : {}".format(network.controller.python_library_flavor)) + print("Get openzwave version : {}".format(network.controller.ozw_library_version)) + print("Get config path : {}".format(network.controller.library_config_path)) + print("Controller capabilities : {}".format(network.controller.capabilities)) + print("Controller node capabilities : {}".format(network.controller.node.capabilities)) + print("Nodes in network : {}".format(network.nodes_count)) + + print("-------------------------------------------------------------------------------") + if args.timeout > 1800: + print("You defined a really long timneout. Please use --help to change this feature.") + print("Wait for network ready ({0}s)".format(args.timeout)) + for i in range(0, int(args.timeout/delta)): + time.sleep(delta) + if network.state == network.STATE_READY: + break + print("-------------------------------------------------------------------------------") + if network.state == network.STATE_READY: + print("Network is ready. Get nodes") + elif network.state == network.STATE_AWAKED: + print("Network is awake. Some sleeping devices may miss. You can increase timeout to get them. But will continue.") + else: + print("Network is still starting. You MUST increase timeout. But will continue.") + + for node in network.nodes: + + print("------------------------------------------------------------") + print("{} - Name : {} ( Location : {} )".format(network.nodes[node].node_id, network.nodes[node].name, network.nodes[node].location)) + print(" {} - Ready : {} / Awake : {} / Failed : {}".format(network.nodes[node].node_id, network.nodes[node].is_ready, network.nodes[node].is_awake, network.nodes[node].is_failed)) + print(" {} - Manufacturer : {} ( id : {} )".format(network.nodes[node].node_id, network.nodes[node].manufacturer_name, network.nodes[node].manufacturer_id)) + print(" {} - Product : {} ( id : {} / type : {} / Version : {})".format(network.nodes[node].node_id, network.nodes[node].product_name, network.nodes[node].product_id, network.nodes[node].product_type, network.nodes[node].version)) + print(" {} - Command classes : {}".format(network.nodes[node].node_id, network.nodes[node].command_classes_as_string)) + print(" {} - Capabilities : {}".format(network.nodes[node].node_id, network.nodes[node].capabilities)) + print(" {} - Neighbors : {} / Power level : {}".format(network.nodes[node].node_id, network.nodes[node].neighbors, network.nodes[node].get_power_level())) + print(" {} - Is sleeping : {} / Can wake-up : {} / Battery level : {}".format(network.nodes[node].node_id, network.nodes[node].is_sleeping, network.nodes[node].can_wake_up(), network.nodes[node].get_battery_level())) + + print("------------------------------------------------------------") + print("Driver statistics : {}".format(network.controller.stats)) + print("------------------------------------------------------------") + print("Stop network") + network.stop() + print("Exit") + +def pyozw_parser(): + parser = argparse.ArgumentParser(description='Run python_openzwave basics checks.') + parser.add_argument('-o', '--output', action='store', help='The format (txt, raw, ...)', choices=['txt', 'raw'], default='txt') + parser.add_argument('-d', '--device', action='store', help='The device port', default=None) + parser.add_argument('-m', '--imports', action='store_true', help='Import all libs', default=True) + parser.add_argument('-i', '--init_device', action='store_true', help='Intialize the device', default=False) + parser.add_argument('-l', '--list_nodes', action='store_true', help='List the nodes on zwave network', default=False) + parser.add_argument('-t', '--timeout', action='store',type=int, help='The default timeout for zwave network sniffing', default=None) + parser.add_argument('--config_path', action='store', help='The config_path for openzwave', default=None) + parser.add_argument('--user_path', action='store', help='The user_path for openzwave', default=".") + return parser + +def main(): + parser = pyozw_parser() + global args + args = parser.parse_args() + if args.init_device: + init_device(args) + elif args.list_nodes: + list_nodes(args) + elif args.imports: + imports(args) + +if __name__ == '__main__': + main() + diff --git a/src-manager/scripts/ozwsh b/src-python_openzwave/python_openzwave/scripts/pyozw_shell.py similarity index 95% rename from src-manager/scripts/ozwsh rename to src-python_openzwave/python_openzwave/scripts/pyozw_shell.py index ead125c2..b6b67fb7 100755 --- a/src-manager/scripts/ozwsh +++ b/src-python_openzwave/python_openzwave/scripts/pyozw_shell.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- """ -.. module:: ozwsh +.. module:: pyozw_shell This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. :platform: Unix, Windows, MacOS X @@ -29,6 +29,7 @@ import sys, os, optparse, re, shutil, datetime import logging +import urwid from pyozwman.ozwsh_main import MainWindow from libopenzwave import configPath import signal @@ -42,13 +43,13 @@ def signal_term_handler(signal, frame): def main(): parser = optparse.OptionParser( - usage="ozwsh [--device=/dev/ttyUSB0] [--log=Debug] ...") + usage="pyozw_shell [--device=/dev/ttyUSB0] [--log=Debug] ...") parser.add_option( '-d', '--device', dest='device', type="str", - default="/dev/ttyUSB0", + default=None, help="The path to your ZWave device") parser.add_option( diff --git a/tests/api/common.py b/tests/api/common.py index 7ef48a57..b771cf64 100644 --- a/tests/api/common.py +++ b/tests/api/common.py @@ -30,7 +30,6 @@ import unittest import threading import logging -import json as mjson import shutil from nose.plugins.skip import SkipTest import libopenzwave @@ -51,7 +50,7 @@ from louie import dispatcher from tests.common import SLEEP -from tests.common import TestPyZWave +from tests.common import TestPyZWave, json_dumps, json_loads class TestApi(TestPyZWave): """ @@ -68,9 +67,8 @@ def setUpClass(self): self.options.set_save_log_level(self.ozwlog) self.options.set_logging(True) self.options.lock() - self.node_result = None - dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE) self.network = ZWaveNetwork(self.options) + self.node_result = None self.ctrl_command_result = None self.ctrl_command_signal = None #dispatcher.connect(self.ctrl_message, ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND) @@ -86,7 +84,21 @@ def tearDownClass(self): self.network = None def setUp(self): + dispatcher.connect(self.node_update, ZWaveNetwork.SIGNAL_NODE) + self.node_result = None + self.ctrl_command_result = None + self.ctrl_command_signal = None self.wait_for_network_state(self.network.STATE_AWAKED, 1) + time.sleep(2.0) + self.wait_for_queue() + self.active_nodes = {} + for node in self.network.nodes: + if self.network.nodes[node].is_info_received: + self.active_nodes[node] = self.network.nodes[node] + print('active nodes : %s' % self.active_nodes) + + def tearDown(self): + dispatcher.disconnect(self.node_update, ZWaveNetwork.SIGNAL_NODE) def wait_for_queue(self): for i in range(0,60): diff --git a/tests/api/test_battery.py b/tests/api/test_command.py similarity index 63% rename from tests/api/test_battery.py rename to tests/api/test_command.py index a1149306..264fe0d3 100644 --- a/tests/api/test_battery.py +++ b/tests/api/test_command.py @@ -55,17 +55,37 @@ from tests.api.common import TestApi from tests.common import TestPyZWave -class TestBattery(TestApi): +class TestCommand(TestApi): def test_010_battery_item(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_battery_levels() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_battery_levels() : ran = True - self.assertEqual(type(self.network.nodes[node].get_battery_level(val)), type(0)) - if not ran : + self.assertTrue(isinstance(self.active_nodes[node].get_battery_level(val), + six.integer_types)) + if ran == False : self.skipTest("No battery found") + def test_020_config_item(self): + ran = False + for node in self.active_nodes: + for val in self.active_nodes[node].get_configs() : + ran = True + self.assertNotEqual(self.active_nodes[node].get_config(val), None) + if ran == False : + self.skipTest("No config param found") + + def test_030_door_locks(self): + ran = False + for node in self.active_nodes: + for val in self.active_nodes[node].get_doorlocks() : + ran = True + self.assertNotEqual(self.active_nodes[node].get_usercodes(), None) + self.assertNotEqual(self.active_nodes[node].get_doorlock_logs(), None) + if ran == False : + self.skipTest("No door_locks found") + if __name__ == '__main__': sys.argv.append('-v') unittest.main() diff --git a/tests/api/test_controller.py b/tests/api/test_controller.py index ca511bb0..5254c2a3 100644 --- a/tests/api/test_controller.py +++ b/tests/api/test_controller.py @@ -33,15 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -54,7 +52,6 @@ from tests.common import SLEEP from tests.api.common import TestApi from tests.common import TestPyZWave -from six import string_types class TestController(TestApi): @@ -62,18 +59,30 @@ def test_010_controller(self): self.assertTrue(isinstance(self.network.controller.name, string_types)) self.assertTrue(isinstance(self.network.controller.ozw_library_version, string_types)) self.assertTrue(isinstance(self.network.controller.python_library_version, string_types)) + self.assertTrue(isinstance(self.network.controller.python_library_flavor, string_types)) self.assertTrue(isinstance(self.network.controller.library_description, string_types)) def test_020_controller_capabilities(self): self.assertEqual(type(self.network.controller.capabilities), type(set())) def test_030_controller_send_queue(self): - self.assertEqual(type(self.network.controller.send_queue_count), type(0)) + self.assertTrue(isinstance(self.network.controller.send_queue_count, integer_types)) self.assertTrue(self.network.controller.send_queue_count >= 0) def test_040_controller_stats(self): self.assertEqual(type(self.network.controller.stats), type(dict())) + def test_050_controller_update_ozw_config(self): + #Remove old config version + try: + os.remove(os.path.join(self.network.controller.library_config_path, 'pyozw_config.version')) + except: + pass + self.assertTrue(self.network.controller.python_library_config_version.startswith('Original')) + if not ( self.network.controller.python_library_flavor in ['shared']): + self.network.controller.update_ozw_config() + self.assertTrue(self.network.controller.python_library_config_version.startswith('Git')) + def test_110_controller_soft_reset(self): time.sleep(5) self.network.controller.soft_reset() @@ -81,9 +90,9 @@ def test_110_controller_soft_reset(self): time.sleep(5) def test_310_controller_node(self): - self.assertEqual(type(self.network.controller.node.node_id), type(0)) + self.assertTrue(isinstance(self.network.controller.node_id, integer_types)) self.assertTrue(self.network.controller.node.node_id > 0) - self.assertEqual(type(self.network.controller.node.version), type(0)) + self.assertTrue(isinstance(self.network.controller.node.version, integer_types)) self.assertTrue(self.network.controller.node.version > 0) def test_320_controller_node_capabilities(self): @@ -93,7 +102,7 @@ def test_330_controller_node_neighbors(self): self.assertEqual(type(self.network.controller.node.neighbors), type(set())) def test_340_controller_node_baud_rate(self): - self.assertTrue(type(self.network.controller.node.max_baud_rate) in [type(long()), type(int())]) + self.assertTrue(isinstance(self.network.controller.node.max_baud_rate, integer_types)) self.assertTrue(self.network.controller.node.max_baud_rate > 0) def test_410_controller_node_product(self): @@ -136,13 +145,13 @@ def test_810_controller_node_values(self): self.assertEqual(type(self.network.controller.node.get_values()), type(dict())) def test_820_controller_node_generic(self): - self.assertEqual(type(self.network.controller.node.generic), type(0)) + self.assertTrue(isinstance(self.network.controller.node.generic, integer_types)) self.assertTrue(self.network.controller.node.generic > 0) - self.assertEqual(type(self.network.controller.node.basic), type(0)) + self.assertTrue(isinstance(self.network.controller.node.basic, integer_types)) self.assertTrue(self.network.controller.node.basic > 0) - self.assertEqual(type(self.network.controller.node.specific), type(0)) + self.assertTrue(isinstance(self.network.controller.node.specific, integer_types)) self.assertTrue(self.network.controller.node.specific >= 0) - self.assertEqual(type(self.network.controller.node.security), type(0)) + self.assertTrue(isinstance(self.network.controller.node.security, integer_types)) self.assertTrue(self.network.controller.node.security >= 0) def test_830_controller_node_refresh(self): @@ -162,7 +171,7 @@ def test_910_controller_stats_poll(self): break else: time.sleep(1.0) - self.assertEqual(type(self.stats_received), type({})) + self.assertEqual(type(self.stats_received), type(dict())) self.assertTrue('SOFCnt' in self.stats_received) self.stats_received = None for i in range(0,10): @@ -171,7 +180,7 @@ def test_910_controller_stats_poll(self): break else: time.sleep(1.0) - self.assertEqual(type(self.stats_received), type({})) + self.assertEqual(type(self.stats_received), type(dict())) self.network.controller.poll_stats = 0 self.stats_received = None for i in range(0,12): diff --git a/tests/api/test_controller_command.py b/tests/api/test_controller_command.py index 366aa211..0e5c3b51 100644 --- a/tests/api/test_controller_command.py +++ b/tests/api/test_controller_command.py @@ -33,14 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -65,9 +64,10 @@ def tearDownClass(self): super(TestControllerCommand, self).tearDownClass() def setUp(self): - self.wait_for_network_state(self.network.STATE_READY, 1) - self.wait_for_queue() - self.ctrl_state_result = None + # ~ self.wait_for_network_state(self.network.STATE_READY, 1) + # ~ self.wait_for_queue() + # ~ self.ctrl_state_result = None + TestApi.setUp(self) dispatcher.connect(self.ctrl_message, ZWaveNetwork.SIGNAL_CONTROLLER_COMMAND) dispatcher.connect(self.ctrl_waiting, ZWaveNetwork.SIGNAL_CONTROLLER_WAITING) time.sleep(2.0) @@ -107,9 +107,10 @@ def test_005_request_controller_status(self): def test_010_command_send_node_information_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: - node_id = max(self.network.nodes.keys()) + # ~ node_id = max(self.network.nodes.keys()) + # ~ node_id = self.active_nodes.keys()[1] ret = self.network.controller.send_node_information(node_id) self.assertTrue(ret) current = None @@ -121,7 +122,9 @@ def test_010_command_send_node_information_nodes(self): break else: time.sleep(1.0) + print(self.ctrl_command_signal) self.assertEqual(current, self.network.controller.STATE_COMPLETED) + self.assertEqual(self.ctrl_command_signal['node_id'], node_id) def test_015_command_send_node_information_controller(self): self.ctrl_state_result = None @@ -139,9 +142,10 @@ def test_015_command_send_node_information_controller(self): self.assertEqual(current, self.network.controller.STATE_FAILED) def test_020_command_request_node_neighbor_update_nodes(self): - #~ self.wipTest() + self.wipTest() self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: ret = self.network.controller.request_node_neighbor_update(node_id) self.assertTrue(ret) @@ -174,7 +178,7 @@ def test_025_command_request_node_neighbor_update_controller(self): def test_030_command_request_network_update_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.request_network_update(node_id) @@ -207,7 +211,7 @@ def test_035_command_request_network_update_controller(self): def test_040_command_delete_all_return_routes_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.delete_all_return_routes(node_id) @@ -240,7 +244,7 @@ def test_045_command_delete_all_return_routes_controller(self): def test_050_command_assign_return_route_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.assign_return_route(node_id) @@ -273,7 +277,7 @@ def test_055_command_assign_return_route_controller(self): def test_060_command_has_node_failed_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.has_node_failed(node_id) @@ -288,10 +292,11 @@ def test_060_command_has_node_failed_nodes(self): else: time.sleep(1.0) self.assertEqual(current, self.network.controller.STATE_NODEOK) + self.assertEqual(self.ctrl_command_signal['node_id'], node_id) def test_070_command_remove_failed_node_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.remove_failed_node(node_id) @@ -309,7 +314,7 @@ def test_070_command_remove_failed_node_nodes(self): def test_080_command_replace_failed_node_nodes(self): self.ctrl_state_result = None - node_ids = [ k for k in self.network.nodes.keys() if k != self.network.controller.node_id ] + node_ids = [ k for k in self.active_nodes.keys() if k != self.network.controller.node_id ] for node_id in node_ids: node_id = max(self.network.nodes.keys()) ret = self.network.controller.replace_failed_node(node_id) diff --git a/tests/api/test_dimmer.py b/tests/api/test_dimmer.py index 678f027e..c2104ccd 100644 --- a/tests/api/test_dimmer.py +++ b/tests/api/test_dimmer.py @@ -33,14 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -58,30 +57,30 @@ class TestDimmer(TestApi): def test_010_dimmer_level(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_dimmers() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_dimmers() : ran = True - self.assertTrue(self.network.nodes[node].get_dimmer_level(val) in range(0,256)) - if not ran : + self.assertTrue(self.active_nodes[node].get_dimmer_level(val) in range(0,256)) + if ran == False : self.skipTest("No Dimmer found") def test_110_dimmer_on_off(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_dimmers() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_dimmers() : ran = True level = 80 - self.network.nodes[node].set_dimmer(val,level) + self.active_nodes[node].set_dimmer(val,level) time.sleep(1) - if self.network.nodes[node].get_dimmer_level(val) not in range(level-5,level+5): + if self.active_nodes[node].get_dimmer_level(val) not in range(level-5,level+5): time.sleep(5) - self.assertTrue(self.network.nodes[node].get_dimmer_level(val) in range(level-5,level+5)) - self.network.nodes[node].set_dimmer(val,0) + self.assertTrue(self.active_nodes[node].get_dimmer_level(val) in range(level-5,level+5)) + self.active_nodes[node].set_dimmer(val,0) time.sleep(2) - if self.network.nodes[node].get_dimmer_level(val) != 0: + if self.active_nodes[node].get_dimmer_level(val) != 0: time.sleep(5) - self.assertEqual(self.network.nodes[node].get_dimmer_level(val), 0) - if not ran : + self.assertEqual(self.active_nodes[node].get_dimmer_level(val), 0) + if ran == False : self.skipTest("No Dimmer found") if __name__ == '__main__': diff --git a/tests/api/test_network.py b/tests/api/test_network.py index 201cc66d..17db3cd4 100644 --- a/tests/api/test_network.py +++ b/tests/api/test_network.py @@ -33,15 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -53,8 +51,7 @@ from tests.common import pyozw_version from tests.common import SLEEP from tests.api.common import TestApi -from tests.common import TestPyZWave -import json +from tests.common import TestPyZWave, json_dumps, json_loads class TestNetwork(TestApi): @@ -83,15 +80,15 @@ def test_120_network_poll(self): def test_200_network_to_dict(self): dnetwork = self.network.to_dict() - self.assertEqual(type(dnetwork), type({})) - res = json.dumps(dnetwork) + self.assertEqual(type(dnetwork), type(dict())) + res = json_dumps(dnetwork) self.assertNotEqual(res, None) self.assertTrue(len(res)>0) def test_220_network_nodes_to_dict(self): dnodes = self.network.nodes_to_dict() - self.assertEqual(type(dnodes), type({})) - res = json.dumps(dnodes) + self.assertEqual(type(dnodes), type(dict())) + res = json_dumps(dnodes) self.assertNotEqual(res, None) self.assertTrue(len(res)>0) diff --git a/tests/api/test_network_start.py b/tests/api/test_network_start.py index 2fde17f6..84a95ff8 100644 --- a/tests/api/test_network_start.py +++ b/tests/api/test_network_start.py @@ -33,15 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -71,21 +69,23 @@ def tearDownClass(self): self.network = None super(TestNetworkStartStop, self).tearDownClass() - def driver_ready_message(self, network, controller): + def driver_ready_message(self, network): self.driver_ready = True def driver_removed_message(self, network): self.driver_removed = True def network_started_message(self, network): - self.driver_removed = True + self.network_started = True def network_stopped_message(self, network): - self.driver_removed = True + self.network_stopped = True def test_000_network_start_stop(self): self.driver_ready = False self.driver_removed = False + self.network_started = False + self.network_stopped = False self.options = ZWaveOption(device=self.device, user_path=self.userpath) self.options.set_log_file("OZW_Log.log") self.options.set_append_log_file(False) @@ -95,13 +95,18 @@ def test_000_network_start_stop(self): self.options.lock() dispatcher.connect(self.driver_ready_message, ZWaveNetwork.SIGNAL_DRIVER_READY) dispatcher.connect(self.driver_removed_message, ZWaveNetwork.SIGNAL_DRIVER_REMOVED) + dispatcher.connect(self.driver_ready_message, ZWaveNetwork.SIGNAL_NETWORK_STARTED) + dispatcher.connect(self.driver_removed_message, ZWaveNetwork.SIGNAL_DRIVER_REMOVED) self.network = ZWaveNetwork(self.options) for i in range(0, SLEEP): - if self.network.state>=self.network.STATE_AWAKED: + if self.network.state>=self.network.STATE_STARTED: break else: time.sleep(1.0) + time.sleep(5.0) self.assertTrue(self.driver_ready) + #~ time.sleep(5.0) + #~ self.assertTrue(self.network_started) self.network.stop() for i in range(0, SLEEP): if self.network.state==self.network.STATE_STOPPED: @@ -109,7 +114,8 @@ def test_000_network_start_stop(self): else: time.sleep(1.0) self.assertEqual(self.network.state, self.network.STATE_STOPPED) - #self.assertTrue(self.driver_removed) + #~ self.assertTrue(self.network_stopped) + #~ self.assertTrue(self.driver_removed) def test_010_network_start_stop_start_stop(self): self.driver_ready = False diff --git a/tests/api/test_node.py b/tests/api/test_node.py index b0024d44..9bd33f73 100644 --- a/tests/api/test_node.py +++ b/tests/api/test_node.py @@ -33,15 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import openzwave from openzwave.node import ZWaveNode from openzwave.group import ZWaveGroup @@ -55,7 +53,6 @@ from tests.common import SLEEP from tests.api.common import TestApi from tests.common import TestPyZWave -from six import string_types, integer_types class TestNode(TestApi): @@ -63,14 +60,19 @@ def test_020_node_capabilities(self): node_id = max(self.network.nodes.keys()) self.assertEqual(type(self.network.nodes[node_id].capabilities), type(set())) + def test_030_node_statistics(self): + node_id = max(self.network.nodes.keys()) + self.assertEqual(type(self.network.nodes[node_id].stats), type(dict())) + def test_310_node(self): node_id = max(self.network.nodes.keys()) - self.assertEqual(type(self.network.nodes[node_id].node_id), type(0)) + self.assertTrue(isinstance(self.network.nodes[node_id].node_id, integer_types)) self.assertTrue(self.network.nodes[node_id].node_id > 0) def test_330_node_neighbors(self): - node_id = max(self.network.nodes.keys()) - self.assertEqual(type(self.network.nodes[node_id].neighbors), type(set())) + #~ node_id = max(self.network.nodes.keys()) + for node_id in self.active_nodes: + self.assertEqual(type(self.network.nodes[node_id].neighbors), type(set())) def test_340_node_baud_rate(self): node_id = max(self.network.nodes.keys()) @@ -148,7 +150,7 @@ def test_520_node_group_associations(self): for grp in groups.keys(): associations = groups[grp].associations for ass in associations: - self.assertEqual(type(ass), type(0)) + self.assertTrue(isinstance(ass, integer_types)) self.assertTrue(0 <= ass <= 255) def test_530_node_group_associations_instances(self): @@ -159,7 +161,8 @@ def test_530_node_group_associations_instances(self): for grp in groups.keys(): associations = groups[grp].associations_instances for ass in associations: - self.assertEqual(type(ass), type((0,0))) + self.assertTrue(isinstance(ass[0], integer_types)) + self.assertTrue(isinstance(ass[1], integer_types)) self.assertTrue(0 <= ass[0] <= 255) self.assertTrue(0 <= ass[1] <= 255) diff --git a/tests/api/test_nodes.py b/tests/api/test_nodes.py index 16635d66..9fe5baa1 100644 --- a/tests/api/test_nodes.py +++ b/tests/api/test_nodes.py @@ -33,15 +33,13 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher else: from louie import dispatcher +from six import string_types, integer_types import libopenzwave import openzwave from openzwave.node import ZWaveNode @@ -53,31 +51,34 @@ from tests.common import pyozw_version from tests.common import SLEEP from tests.api.common import TestApi -from tests.common import TestPyZWave -import json +from tests.common import TestPyZWave, json_dumps, json_loads class TestNodes(TestApi): def test_000_nodes_count(self): - self.assertEqual(type(self.network.nodes_count), type(0)) + self.assertTrue(isinstance(self.network.nodes_count, integer_types)) self.assertTrue(self.network.nodes_count>0) def test_100_nodes_test(self): - for node in self.network.nodes: - self.network.nodes[node].test(5) + for node in self.active_nodes: + self.active_nodes[node].test(5) def test_110_nodes_heal(self): - for node in self.network.nodes: - self.network.nodes[node].heal() - for node in self.network.nodes: - self.network.nodes[node].heal(True) + for node in self.active_nodes: + self.active_nodes[node].heal() + for node in self.active_nodes: + self.active_nodes[node].heal(True) def test_200_nodes_to_dict(self): - for node in self.network.nodes: + for node in self.active_nodes: try : - nodes = self.network.nodes[node].to_dict() - self.assertEqual(type(nodes), type({})) - res = json.dumps(nodes) + noded = self.active_nodes[node].to_dict() + self.assertEqual(type(noded), type(dict())) + self.assertTrue('values' in noded) + self.assertTrue('groups' in noded) + self.assertTrue('neighbors' in noded) + self.assertTrue('capabilities' in noded) + res = json_dumps(noded) except TypeError: res = None self.assertNotEqual(res, None) @@ -85,18 +86,19 @@ def test_200_nodes_to_dict(self): def test_210_controller_to_dict(self): try : nodes = self.network.controller.to_dict() - self.assertEqual(type(nodes), type({})) - res = json.dumps(nodes) + self.assertEqual(type(nodes), type(dict())) + res = json_dumps(nodes) except TypeError: res = None self.assertNotEqual(res, None) def test_220_nodes_groups_to_dict(self): - for node in self.network.nodes: + for node in self.active_nodes: try : - groups = self.network.nodes[node].groups_to_dict() - self.assertEqual(type(groups), type({})) - res = json.dumps(groups) + groups = self.active_nodes[node].groups_to_dict() + self.assertTrue(type(groups), type(dict())) + self.assertEqual(type(groups), type(dict())) + res = json_dumps(groups) except TypeError: res = None self.assertNotEqual(res, None) diff --git a/tests/api/test_protection.py b/tests/api/test_protection.py index 2c341d6a..cac09c37 100644 --- a/tests/api/test_protection.py +++ b/tests/api/test_protection.py @@ -33,10 +33,7 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher @@ -60,50 +57,50 @@ class TestProtection(TestApi): def test_010_protection_item(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_protections() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_protections() : ran = True - self.assertTrue(isinstance(self.network.nodes[node].get_protection_item(val), string_types)) - if not ran : + self.assertTrue(isinstance(self.active_nodes[node].get_protection_item(val), string_types)) + if ran == False : self.skipTest("No Protection found") def test_020_protection_set_item_no_operation(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_protections() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_protections() : ran = True - old_value = self.network.nodes[node].get_protection_item(val) + old_value = self.active_nodes[node].get_protection_item(val) new_value = "No Operation Possible" - self.network.nodes[node].set_protection(val, new_value) + self.active_nodes[node].set_protection(val, new_value) time.sleep(1) - self.assertEqual(self.network.nodes[node].get_protection_item(val), new_value) - self.network.nodes[node].set_protection(val, old_value) + self.assertEqual(self.active_nodes[node].get_protection_item(val), new_value) + self.active_nodes[node].set_protection(val, old_value) time.sleep(1) - if not ran : + if ran == False : self.skipTest("No Protection found") def test_030_protection_set_item_unprotected(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_protections() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_protections() : ran = True - old_value = self.network.nodes[node].get_protection_item(val) + old_value = self.active_nodes[node].get_protection_item(val) new_value = "Unprotected" - self.network.nodes[node].set_protection(val, new_value) + self.active_nodes[node].set_protection(val, new_value) time.sleep(1) - self.assertEqual(self.network.nodes[node].get_protection_item(val), new_value) - self.network.nodes[node].set_protection(val, old_value) + self.assertEqual(self.active_nodes[node].get_protection_item(val), new_value) + self.active_nodes[node].set_protection(val, old_value) time.sleep(1) - if not ran : + if ran == False : self.skipTest("No Protection found") def test_050_protection_items(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_protections() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_protections() : ran = True - self.assertTrue(type(self.network.nodes[node].get_protection_items(val)) == type(set()) or isinstance(self.network.nodes[node].get_protection_items(val), string_types)) - if not ran : + self.assertTrue(type(self.active_nodes[node].get_protection_items(val)) == type(set()) or isinstance(self.active_nodes[node].get_protection_items(val), string_types)) + if ran == False : self.skipTest("No Protection found") if __name__ == '__main__': diff --git a/tests/api/test_scene.py b/tests/api/test_scene.py index 6386eb69..22f3229e 100644 --- a/tests/api/test_scene.py +++ b/tests/api/test_scene.py @@ -33,10 +33,7 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher @@ -53,8 +50,7 @@ from tests.common import pyozw_version from tests.common import SLEEP from tests.api.common import TestApi -from tests.common import TestPyZWave -import json +from tests.common import TestPyZWave, json_dumps, json_loads class TestScene(TestApi): count = 0 @@ -66,13 +62,13 @@ def test_005_scene_add_remove(self): self.sceneid = self.network.create_scene("TestUnit Scene") self.assertTrue(self.sceneid > 0) scene = self.network.get_scenes()[self.sceneid] - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches() : ret = scene.add_value(val, True) self.assertTrue(ret) scene = self.network.get_scenes()[self.sceneid] - for node in self.network.nodes: - for val in self.network.nodes[node].get_dimmers() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_dimmers() : ret = scene.add_value(val, self.level) self.assertTrue(ret) self.assertTrue(self.network.scene_exists(self.sceneid)) @@ -85,8 +81,8 @@ def test_005_scene_add_remove(self): def test_010_scenes_to_dict(self): dscenes = self.network.scenes_to_dict() - self.assertEqual(type(dscenes), type({})) - res = json.dumps(dscenes) + self.assertEqual(type(dscenes), type(dict())) + res = json_dumps(dscenes) self.assertNotEqual(res, None) self.assertTrue(len(res)>0) @@ -95,8 +91,8 @@ def test_020_scene_to_dict(self): for scene in scenes: try : scene = scenes[scene].to_dict() - self.assertEqual(type(scene), type({})) - res = json.dumps(scene) + self.assertEqual(type(scene), type(dict())) + res = json_dumps(scene) except TypeError: res = None self.assertNotEqual(res, None) diff --git a/tests/api/test_sensor.py b/tests/api/test_sensor.py index 658c2560..9b1b92b7 100644 --- a/tests/api/test_sensor.py +++ b/tests/api/test_sensor.py @@ -33,10 +33,7 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher @@ -59,77 +56,77 @@ class TestSensor(TestApi): def test_010_sensor_bool(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_sensors(type='Bool') : + for node in self.active_nodes: + for val in self.active_nodes[node].get_sensors(type='Bool') : ran = True - self.assertTrue(self.network.nodes[node].get_sensor_value(val) in [True, False]) - if not ran : + self.assertTrue(self.active_nodes[node].get_sensor_value(val) in [True, False]) + if ran == False : self.skipTest("No Bool sensor found") def test_110_sensor_byte(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_sensors(type='Byte') : + for node in self.active_nodes: + for val in self.active_nodes[node].get_sensors(type='Byte') : ran = True good = True try : - newval = int(self.network.nodes[node].get_sensor_value(val)) + newval = int(self.active_nodes[node].get_sensor_value(val)) except : good = False self.assertTrue(good) - if not ran : + if ran == False : self.skipTest("No Byte sensor found") def test_210_sensor_short(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_sensors(type='Short') : + for node in self.active_nodes: + for val in self.active_nodes[node].get_sensors(type='Short') : ran = True good = True try : - newval = int(self.network.nodes[node].get_sensor_value(val)) + newval = int(self.active_nodes[node].get_sensor_value(val)) except : good = False self.assertTrue(good) - if not ran : + if ran == False : self.skipTest("No Short sensor found") def test_310_sensor_int(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_sensors(type='Int') : + for node in self.active_nodes: + for val in self.active_nodes[node].get_sensors(type='Int') : ran = True good = True try : - newval = int(self.network.nodes[node].get_sensor_value(val)) + newval = int(self.active_nodes[node].get_sensor_value(val)) except : good = False self.assertTrue(good) - if not ran : + if ran == False : self.skipTest("No Int sensor found") def test_410_sensor_decimal(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_sensors(type='Decimal') : + for node in self.active_nodes: + for val in self.active_nodes[node].get_sensors(type='Decimal') : ran = True good = True try : - newval = float(self.network.nodes[node].get_sensor_value(val)) + newval = float(self.active_nodes[node].get_sensor_value(val)) except : good = False self.assertTrue(good) - if not ran : + if ran == False : self.skipTest("No Decimal sensor found") def test_510_sensor_label(self): ran = False - for node in self.network.nodes: - for sensorid, sensor in self.network.nodes[node].get_sensors().items(): + for node in self.active_nodes: + for sensorid, sensor in self.active_nodes[node].get_sensors().items(): ran = True label = sensor.label self.assertTrue(isinstance(label, str)) - if not ran : + if ran == False : self.skipTest("No sensor found") if __name__ == '__main__': diff --git a/tests/api/test_switch.py b/tests/api/test_switch.py index 86831f09..697bfff4 100644 --- a/tests/api/test_switch.py +++ b/tests/api/test_switch.py @@ -26,17 +26,16 @@ """ -import os, shutil +import os +import shutil +import sys import time import unittest from pprint import pprint import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher @@ -59,78 +58,78 @@ class TestSwitch(TestApi): def test_010_switch_state(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches(): + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches(): ran = True - self.assertTrue(self.network.nodes[node].get_switch_state(val) in [True, False]) - if not ran : + self.assertTrue(self.active_nodes[node].get_switch_state(val) in [True, False]) + if ran == False : self.skipTest("No Switch found") def test_020_switch_rgb_state(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_rgbbulbs(): + for node in self.active_nodes: + for val in self.active_nodes[node].get_rgbbulbs(): ran = True - self.assertTrue(self.network.nodes[node].get_switch_state(val) in [True, False]) - if not ran : + self.assertTrue(self.active_nodes[node].get_switch_state(val) in [True, False]) + if ran == False : self.skipTest("No RGB bulb found") def test_110_switch_on_off(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches(): + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches(): ran = True time.sleep(1) - self.network.nodes[node].set_switch(val,True) + self.active_nodes[node].set_switch(val,True) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_switch_state(val) == False : + if self.active_nodes[node].get_switch_state(val) == False : time.sleep(5) - self.assertTrue(self.network.nodes[node].get_switch_state(val)) - self.network.nodes[node].set_switch(val,False) + self.assertTrue(self.active_nodes[node].get_switch_state(val)) + self.active_nodes[node].set_switch(val,False) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_switch_state(val) == True : + if self.active_nodes[node].get_switch_state(val) == True : time.sleep(5) - self.assertFalse(self.network.nodes[node].get_switch_state(val)) - if not ran : + self.assertFalse(self.active_nodes[node].get_switch_state(val)) + if ran == False : self.skipTest("No Switch found") def test_120_switch_rgbbulbs(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_rgbbulbs(): + for node in self.active_nodes: + for val in self.active_nodes[node].get_rgbbulbs(): ran = True time.sleep(1) - self.network.nodes[node].set_switch(val,True) + self.active_nodes[node].set_switch(val,True) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_switch_state(val) == False : + if self.active_nodes[node].get_switch_state(val) == False : time.sleep(5) - self.assertTrue(self.network.nodes[node].get_switch_state(val)) + self.assertTrue(self.active_nodes[node].get_switch_state(val)) - oldrgbw = self.network.nodes[node].get_rgbw(val) + oldrgbw = self.active_nodes[node].get_rgbw(val) rgbw = 114 - self.network.nodes[node].set_rgbw(val,rgbw) + self.active_nodes[node].set_rgbw(val,rgbw) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_rgbw(val) != rgbw: + if self.active_nodes[node].get_rgbw(val) != rgbw: time.sleep(5) - self.assertEqual(rgbw, self.network.nodes[node].get_rgbw(val)) - self.network.nodes[node].set_rgbw(val,oldrgbw) + self.assertEqual(rgbw, self.active_nodes[node].get_rgbw(val)) + self.active_nodes[node].set_rgbw(val,oldrgbw) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_rgbw(val) != rgbw : + if self.active_nodes[node].get_rgbw(val) != rgbw : time.sleep(5) - self.assertEqual(oldrgbw, self.network.nodes[node].get_rgbw(val)) + self.assertEqual(oldrgbw, self.active_nodes[node].get_rgbw(val)) - self.network.nodes[node].set_switch(val,False) + self.active_nodes[node].set_switch(val,False) #self.wait_for_queue() time.sleep(1) - if self.network.nodes[node].get_switch_state(val) == True : + if self.active_nodes[node].get_switch_state(val) == True : time.sleep(5) - self.assertFalse(self.network.nodes[node].get_switch_state(val)) - if not ran : + self.assertFalse(self.active_nodes[node].get_switch_state(val)) + if ran == False : self.skipTest("No RGB bulb found") if __name__ == '__main__': diff --git a/tests/api/test_switch_all.py b/tests/api/test_switch_all.py index 6a57e733..48af21fa 100644 --- a/tests/api/test_switch_all.py +++ b/tests/api/test_switch_all.py @@ -33,10 +33,7 @@ import datetime import random import socket -import libopenzwave import re -import time -import sys import six if six.PY3: from pydispatch import dispatcher @@ -60,75 +57,75 @@ class TestSwitchAll(TestApi): def test_010_switch_all_item(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches_all() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches_all() : ran = True - self.assertTrue(isinstance(self.network.nodes[node].get_switch_all_item(val), string_types)) - if not ran : + self.assertTrue(isinstance(self.active_nodes[node].get_switch_all_item(val), string_types)) + if ran == False : self.skipTest("No Switch_All found") def test_015_switch_all_set_item(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches_all() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches_all() : self.wait_for_queue() ran = True - old_value = self.network.nodes[node].get_switch_all_item(val) + old_value = self.active_nodes[node].get_switch_all_item(val) new_value = "Disabled" - self.network.nodes[node].set_switch_all(val, new_value) + self.active_nodes[node].set_switch_all(val, new_value) time.sleep(1) self.wait_for_queue() - self.assertEqual(self.network.nodes[node].get_switch_all_item(val), new_value) - self.network.nodes[node].set_switch_all(val, old_value) + self.assertEqual(self.active_nodes[node].get_switch_all_item(val), new_value) + self.active_nodes[node].set_switch_all(val, old_value) time.sleep(1) - if not ran : + if ran == False : self.skipTest("No Switch_All found") def test_020_switch_all_items(self): ran = False - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches_all() : + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches_all() : ran = True - self.assertTrue(isinstance(self.network.nodes[node].get_switch_all_item(val), string_types) or type(self.network.nodes[node].get_switch_all_items(val)) == type("")) - if not ran : + self.assertTrue(isinstance(self.active_nodes[node].get_switch_all_item(val), string_types) or type(self.active_nodes[node].get_switch_all_items(val)) == type("")) + if ran == False : self.skipTest("No Switch_All found") def test_110_switch_all_on(self): - self.wipTest() + #~ self.wipTest() self.wait_for_queue() time.sleep(2) ran = False self.network.switch_all(True) - time.sleep(3) + time.sleep(5) self.wait_for_queue() - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches_all() : - item = self.network.nodes[node].get_switch_all_item(val) + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches_all() : + item = self.active_nodes[node].get_switch_all_item(val) if item == "On and Off Enabled" or item == "On Enabled": ran = True - print "Node/State : %s/%s" % (node, self.network.nodes[node].get_switch_all_state(val)) - self.assertTrue(self.network.nodes[node].get_switch_all_state(val)) - if not ran : + print("Node/State : %s/%s" % (node, self.active_nodes[node].get_switch_all_state(val))) + self.assertTrue(self.active_nodes[node].get_switch_all_state(val)) + if ran == False : self.skipTest("No Switch_All with 'On and Off Enabled' or 'On Enabled' found") else: time.sleep(5) def test_120_switch_all_off(self): - self.wipTest() + #~ self.wipTest() self.wait_for_queue() time.sleep(2) ran = False self.network.switch_all(False) - time.sleep(3) + time.sleep(5) self.wait_for_queue() - for node in self.network.nodes: - for val in self.network.nodes[node].get_switches_all() : - item = self.network.nodes[node].get_switch_all_item(val) + for node in self.active_nodes: + for val in self.active_nodes[node].get_switches_all() : + item = self.active_nodes[node].get_switch_all_item(val) if item == "On and Off Enabled" or item == "Off Enabled": ran = True - print "Node/State : %s/%s" % (node, self.network.nodes[node].get_switch_all_state(val)) - self.assertFalse(self.network.nodes[node].get_switch_all_state(val)) - if not ran : + print("Node/State : %s/%s" % (node, self.active_nodes[node].get_switch_all_state(val))) + self.assertFalse(self.active_nodes[node].get_switch_all_state(val)) + if ran == False : self.skipTest("No Switch_All with 'On and Off Enabled' or 'Off Enabled' found") else: time.sleep(5) diff --git a/tests/api/test_value.py b/tests/api/test_value.py index 360aa773..77c23192 100644 --- a/tests/api/test_value.py +++ b/tests/api/test_value.py @@ -53,26 +53,29 @@ from tests.common import pyozw_version from tests.common import SLEEP from tests.api.common import TestApi -from tests.common import TestPyZWave -import json +from tests.common import TestPyZWave, json_dumps, json_loads class TestValue(TestApi): def test_200_values_to_dict(self): - for node in self.network.nodes: - for value in self.network.nodes[node].values: - val = self.network.nodes[node].values[value].to_dict() - self.assertEqual(type(val), type({})) - try : - res = json.dumps(val) - except TypeError: - res = None + for node in self.active_nodes: + for value in self.active_nodes[node].values: + val = self.active_nodes[node].values[value].to_dict() + print(val) + self.assertEqual(type(val), type(dict())) + self.assertTrue('data_items' in val) + self.assertTrue('command_class' in val) + self.assertTrue('is_read_only' in val) + self.assertTrue('is_write_only' in val) + self.assertTrue('type' in val) + self.assertTrue('index' in val) + res = json_dumps(val) self.assertNotEqual(res, None) def test_210_values_check_data(self): - for node in self.network.nodes: - for value in self.network.nodes[node].values: - val = self.network.nodes[node].values[value] + for node in self.active_nodes: + for value in self.active_nodes[node].values: + val = self.active_nodes[node].values[value] if val.is_read_only == False: if val.type == "Bool": for data in ['False', 'false', '0']: diff --git a/tests/common.py b/tests/common.py index 03c12ff7..badec123 100644 --- a/tests/common.py +++ b/tests/common.py @@ -25,19 +25,36 @@ """ -#The common sleep dealy to wait for network -#We wait 1*SLEEP for network.STATE_AWAKED -#After that we wait 1*SLEEP for network.STATE_READY -SLEEP = 45 - -import sys, os +import os +import shutil +import sys import time import unittest import threading import logging -import json as mjson +import json +#~ import bson import six +#The common sleep dealy to wait for network +#We wait 1*SLEEP for network.STATE_AWAKED +#After that we wait 1*SLEEP for network.STATE_READY +SLEEP = 45 + +class SetEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, set): + return list(obj) + return json.JSONEncoder.default(self, obj) + +def json_dumps(data_as_object): + #~ return json.dumps(data_as_object, default=json_util.default) + return json.dumps(data_as_object, cls=SetEncoder) + +def json_loads(data_as_string): + #~ return json.loads(data_as_string, object_hook=json_util.object_hook) + return json.loads(data_as_string) + from nose.plugins.skip import SkipTest sys.path.insert(1, os.path.abspath('..')) @@ -50,7 +67,7 @@ class TestPyZWave(unittest.TestCase): """ device = "/dev/ttyUSB0" ozwlog = "Debug" - ozwout = False + ozwout = True pylog = logging.DEBUG userpath = ".tests_user_path" @@ -75,6 +92,7 @@ def setUpClass(self): except: pass + @classmethod def skipTest(self, message): """Skip a test """ diff --git a/tests/lib/autobuild/test_lib.py b/tests/lib/autobuild/test_lib.py index e944a8c1..e7e05eae 100644 --- a/tests/lib/autobuild/test_lib.py +++ b/tests/lib/autobuild/test_lib.py @@ -56,8 +56,14 @@ def test_010_options_exceptions(self): shutil.rmtree(self.userpath) except: pass - os.makedirs(self.userpath) - os.makedirs(fake_config_dir) + try: + os.makedirs(self.userpath) + except: + pass + try: + os.makedirs(fake_config_dir) + except: + pass os.chmod(fake_config_dir, stat.S_IREAD|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH) with self.assertRaises(libopenzwave.LibZWaveException): options = libopenzwave.PyOptions(config_path=fake_config_dir, user_path=None, cmd_line=None) @@ -66,8 +72,14 @@ def test_010_options_exceptions(self): shutil.rmtree(self.userpath) except: pass - os.makedirs(self.userpath) - os.makedirs(fake_config_dir) + try: + os.makedirs(self.userpath) + except: + pass + try: + os.makedirs(fake_config_dir) + except: + pass os.chmod(fake_config_dir, stat.S_IREAD|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWRITE|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) with self.assertRaises(libopenzwave.LibZWaveException): options = libopenzwave.PyOptions(config_path=fake_config_dir, user_path=None, cmd_line=None) @@ -90,6 +102,20 @@ def test_030_options_with_command_line(self): self.assertEqual(1, options.getOptionAsInt("SaveLogLevel")) self.assertTrue(options.destroy()) + def test_050_version(self): + time.sleep(1.0) + from pyozw_version import pyozw_version + manager = libopenzwave.PyManager() + version = manager.getPythonLibraryVersion() + self.assertEqual(version.find("None"), -1) + + def test_060_options_lock(self): + options = libopenzwave.PyOptions(user_path=self.userpath) + self.assertTrue(options.lock()) + self.assertTrue(options.areLocked()) + self.assertTrue(os.path.isfile(os.path.join(self.userpath,'options.xml'))) + self.assertTrue(options.destroy()) + class TestOptions(TestLib): def test_010_options_string(self): diff --git a/tests/lib/autobuild/test_ozw_src.py b/tests/lib/autobuild/test_ozw_src.py new file mode 100644 index 00000000..1804146f --- /dev/null +++ b/tests/lib/autobuild/test_ozw_src.py @@ -0,0 +1,257 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +.. module:: tests + +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + :platform: Unix, Windows, MacOS X + :sinopsis: openzwave Library + +.. moduleauthor: bibi21000 aka Sébastien GALLET + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +""" + +import sys, os, shutil, stat +import time +import unittest +from pprint import pprint +import datetime +import random +import socket +import libopenzwave +from tests.lib.common import TestLib +import re +import glob +from tests.common import pyozw_version +import six + +OZWDIR = "openzwave" + +class TestOzwSrc(TestLib): + + def test_010_command_classes(self): + manager = libopenzwave.PyManager() + CLASSID = re.compile(r"StaticGetCommandClassId\(\)\{ return (.*);") + CLASSST = re.compile(r'StaticGetCommandClassName\(\)\{ return "(.*)";') + headers = glob.glob(os.path.join (OZWDIR, 'cpp', 'src', 'command_classes', '*.h')) + for header in headers: + classid = None + classst = None + if not (header.endswith('CommandClass.h') or header.endswith('CommandClasses.h')): + with open(header, 'r') as f: + lines = f.readlines() + for line in lines: + match = CLASSID.search(line) + if match: + classid = match.group(1) + else: + match = CLASSST.search(line) + if match: + classst = match.group(1) + print(header) + print(classid, ':', classst) + self.assertEqual(classst, manager.COMMAND_CLASS_DESC[int(classid,16)]) + + def test_020_notification_types(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Notification.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + types = re.search(r"enum NotificationType.*\{(.*)\}.*enum NotificationCode", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(types) + alls = re.findall(r"Type_(\w*)", types, re.MULTILINE) + #~ print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyNotifications[i], j) + self.assertEqual(libopenzwave.PyNotifications[i], j) + + def test_030_notification_codes(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Notification.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + types = re.search(r"enum NotificationCode.*\{(.*)\}.*NotificationType GetType", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(types) + alls = re.findall(r"Code_(\w*)", types, re.MULTILINE) + #~ print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyNotificationCodes[i], j) + self.assertEqual(libopenzwave.PyNotificationCodes[i], j) + + def test_040_value_genres(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'value_classes', 'ValueID.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ValueGenre.*\{(.*)\}.*enum ValueType", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ValueGenre_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)-1),alls): + print(libopenzwave.PyGenres[i], j) + self.assertEqual(libopenzwave.PyGenres[i], j) + + def test_050_value_types(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'value_classes', 'ValueID.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ValueType.*\{(.*)\}.*uint32 GetHomeId", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ValueType_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)-2),alls): + print(libopenzwave.PyValueTypes[i], j) + self.assertEqual(libopenzwave.PyValueTypes[i], j) + + def test_060_controller_command(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Driver.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ControllerCommand.*\{(.*)\}.*enum ControllerState", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ControllerCommand_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyControllerCommand[i], j) + self.assertEqual(libopenzwave.PyControllerCommand[i], j) + + def test_070_controller_state(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Driver.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ControllerState.*\{(.*)\}.*enum ControllerError", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ControllerState_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyControllerState[i], j) + self.assertEqual(libopenzwave.PyControllerState[i], j) + + def test_080_controller_error(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Driver.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ControllerError.*\{(.*)\}.*typedef void", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ControllerError_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyControllerError[i], j) + self.assertEqual(libopenzwave.PyControllerError[i], j) + + def test_090_controller_interface(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Driver.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum ControllerInterface.*\{(.*)\}.*private:", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"ControllerInterface_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyControllerInterface[i], j) + self.assertEqual(libopenzwave.PyControllerInterface[i], j) + + def test_100_option_types(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Options.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum OptionType.*\{(.*)\}.*static Options", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"OptionType_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyOptionType[i], j) + self.assertEqual(libopenzwave.PyOptionType[i], j) + + def test_110_option_names(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Options.cpp'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"s_instance = new Options(.*)return s_instance", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r's_instance->AddOption(\w*).*\([\t]*"(\w*)",[\t]*(.*);(.*)$', values, re.MULTILINE) + #~ alls = re.findall(r's_instance->AddOption(\w*).*\(\t"(\w*).*\t(.*) \);(.*)$', values, re.MULTILINE) + print(alls) + for i in alls: + print(i) + self.assertTrue(i[1] in libopenzwave.PyOptionList) + self.assertEqual(libopenzwave.PyOptionList[i[1]]['type'], i[0]) + + def test_120_log_level(self): + with open(os.path.join (OZWDIR, 'cpp', 'src', 'platform', 'Log.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + values = re.search(r"enum LogLevel.*\{(.*)\}.*class i_LogImpl", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(values) + alls = re.findall(r"LogLevel_(\w*)", values, re.MULTILINE) + print(alls) + for i,j in zip(range(len(alls)),alls): + print(libopenzwave.PyLogLevels[j]) + self.assertTrue(j in libopenzwave.PyLogLevels) + self.assertEqual(libopenzwave.PyLogLevels[j]['value'], i) + + def test_130_manager_functions(self): + PRIVATES = ['SetDriverReady', 'NotifyWatchers'] + RENAMES = [('SoftReset', ['SoftResetController']), + ('GetValueListSelection', ['GetValueListSelectionStr','GetValueListSelectionNum']), + ('SetValueListSelection', ['SetValue']), + ('AddSceneValueListSelection', ['AddSceneValue','AddSceneValue']), + ('SceneGetValueAsBool', ['SceneGetValues']), + ('SceneGetValueAsByte', ['SceneGetValues']), + ('SceneGetValueAsFloat', ['SceneGetValues']), + ('SceneGetValueAsInt', ['SceneGetValues']), + ('SceneGetValueAsShort', ['SceneGetValues']), + ('SceneGetValueAsString', ['SceneGetValues']), + ('SceneGetValueListSelection', ['SceneGetValues']), + ('SetSceneValueListSelection', ['setSceneValue']), + ] + with open(os.path.join (OZWDIR, 'cpp', 'src', 'Manager.h'), 'r') as f: + lines = ''.join(f.readlines()) + #~ print(lines) + code = re.search(r"namespace OpenZWave(.*)\} // namespace OpenZWave", lines, re.MULTILINE|re.DOTALL).group(1) + #~ print(code) + funcvoids = re.findall(r"void (\w*)\( ", code, re.MULTILINE) + print(funcvoids) + funcbools = re.findall(r"bool (\w*)\( ", code, re.MULTILINE) + print(funcbools) + funcuint8s = re.findall(r"uint8 (\w*)\( ", code, re.MULTILINE) + print(funcuint8s) + funcstrings = re.findall(r"string (\w*)\( ", code, re.MULTILINE) + print(funcstrings) + funcint32s = re.findall(r"int32 (\w*)\( ", code, re.MULTILINE) + print(funcint32s) + funcuint32s = re.findall(r"uint32 (\w*)\( ", code, re.MULTILINE) + print(funcuint32s) + funcuint16s = re.findall(r"uint16 (\w*)\( ", code, re.MULTILINE) + print(funcuint16s) + funcs = funcvoids + funcbools + funcuint8s + funcstrings + funcint32s + funcuint32s + funcuint16s + funcs2 = funcs[:] + for f in funcs2: + if f in PRIVATES: + funcs.remove(f) + for g in RENAMES: + #~ print g + if g[0] == f: + funcs.remove(g[0]) + funcs += g[1] + print(funcs) + for i in funcs: + py = i[0].lower() + i[1:] + print("Check %s (%s)"%(i, py)) + self.assertTrue(hasattr(libopenzwave.PyManager,py)) + +if __name__ == '__main__': + sys.argv.append('-v') + unittest.main() diff --git a/tests/lib/common.py b/tests/lib/common.py index ac8a078d..2f10f621 100644 --- a/tests/lib/common.py +++ b/tests/lib/common.py @@ -30,10 +30,11 @@ import unittest import threading import logging -import json as mjson import shutil from nose.plugins.skip import SkipTest +import libopenzwave + from tests.common import SLEEP from tests.common import TestPyZWave @@ -41,11 +42,327 @@ class TestLib(TestPyZWave): """ Parent test class for lib """ + + SIGNAL_NETWORK_FAILED = 'NetworkFailed' + SIGNAL_NETWORK_STARTED = 'NetworkStarted' + SIGNAL_NETWORK_READY = 'NetworkReady' + SIGNAL_NETWORK_STOPPED = 'NetworkStopped' + SIGNAL_NETWORK_RESETTED = 'DriverResetted' + SIGNAL_NETWORK_AWAKED = 'DriverAwaked' + SIGNAL_DRIVER_FAILED = 'DriverFailed' + SIGNAL_DRIVER_READY = 'DriverReady' + SIGNAL_DRIVER_RESET = 'DriverReset' + SIGNAL_DRIVER_REMOVED = 'DriverRemoved' + SIGNAL_GROUP = 'Group' + SIGNAL_NODE = 'Node' + SIGNAL_NODE_ADDED = 'NodeAdded' + SIGNAL_NODE_EVENT = 'NodeEvent' + SIGNAL_NODE_NAMING = 'NodeNaming' + SIGNAL_NODE_NEW = 'NodeNew' + SIGNAL_NODE_PROTOCOL_INFO = 'NodeProtocolInfo' + SIGNAL_NODE_READY = 'NodeReady' + SIGNAL_NODE_REMOVED = 'NodeRemoved' + SIGNAL_SCENE_EVENT = 'SceneEvent' + SIGNAL_VALUE = 'Value' + SIGNAL_VALUE_ADDED = 'ValueAdded' + SIGNAL_VALUE_CHANGED = 'ValueChanged' + SIGNAL_VALUE_REFRESHED = 'ValueRefreshed' + SIGNAL_VALUE_REMOVED = 'ValueRemoved' + SIGNAL_POLLING_ENABLED = 'PollingEnabled' + SIGNAL_POLLING_DISABLED = 'PollingDisabled' + SIGNAL_CREATE_BUTTON = 'CreateButton' + SIGNAL_DELETE_BUTTON = 'DeleteButton' + SIGNAL_BUTTON_ON = 'ButtonOn' + SIGNAL_BUTTON_OFF = 'ButtonOff' + SIGNAL_ESSENTIAL_NODE_QUERIES_COMPLETE = 'EssentialNodeQueriesComplete' + SIGNAL_NODE_QUERIES_COMPLETE = 'NodeQueriesComplete' + SIGNAL_AWAKE_NODES_QUERIED = 'AwakeNodesQueried' + SIGNAL_ALL_NODES_QUERIED = 'AllNodesQueried' + SIGNAL_ALL_NODES_QUERIED_SOME_DEAD = 'AllNodesQueriedSomeDead' + SIGNAL_MSG_COMPLETE = 'MsgComplete' + SIGNAL_NOTIFICATION = 'Notification' + SIGNAL_CONTROLLER_COMMAND = 'ControllerCommand' + SIGNAL_CONTROLLER_WAITING = 'ControllerWaiting' + + STATE_STOPPED = 0 + STATE_FAILED = 1 + STATE_RESETTED = 3 + STATE_STARTED = 5 + STATE_AWAKED = 7 + STATE_READY = 10 + @classmethod def setUpClass(self): super(TestPyZWave, self).setUpClass() + self.options = None + self.homeid = None + self.ready = False + self.manager = None + self.nodes = {} + self.driver_state = None + self.driver_ready = None + self.driver_removed = None + self.driver_failed = None + self.driver_reset = None + self.network_state = None + self.network_ready = None + self.network_awake = None @classmethod def tearDownClass(self): + self.stop_lib() super(TestPyZWave, self).tearDownClass() + def start_lib(self): + if self.options is None: + self.options = libopenzwave.PyOptions(config_path="openzwave/config", \ + user_path=self.userpath, cmd_line="--logging false") + self.options.lock() + if self.manager is None: + self.homeid = None + self.nodes = {} + self.ready = False + self.driver_state = None + self.driver_ready = None + self.driver_removed = None + self.driver_failed = None + self.driver_reset = None + self.network_state = None + self.network_ready = None + self.network_awake = None + self.manager = libopenzwave.PyManager() + self.manager.create() + self.manager.addWatcher(self.zwcallback) + time.sleep(1.0) + self.manager.addDriver(self.device) + time.sleep(5.0) + + @classmethod + def stop_lib(self): + if self.manager is not None: + print("Remove driver") + self.manager.removeDriver(self.device) + time.sleep(2.0) + print("Remove watcher") + self.manager.removeWatcher(self.zwcallback) + time.sleep(2.0) + print("Destroy manager") + self.manager.destroy() + time.sleep(1.0) + self.manager = None + if self.options is not None: + self.options.destroy() + print("Destroy options") + time.sleep(1.0) + self.options = None + self.homeid = None + self.ready = False + self.manager = None + self.driver_state = None + self.driver_ready = None + self.driver_removed = None + self.driver_failed = None + self.driver_reset = None + self.network_state = None + self.network_ready = None + self.network_awake = None + + def zwcallback(self, args): + print('zwcallback args=[%s]' % args) + try: + notify_type = args['notificationType'] + if notify_type == self.SIGNAL_DRIVER_FAILED: + self._handle_driver_failed(args) + elif notify_type == self.SIGNAL_DRIVER_READY: + self._handle_driver_ready(args) + elif notify_type == self.SIGNAL_DRIVER_RESET: + self._handle_driver_reset(args) + elif notify_type == self.SIGNAL_NODE_ADDED: + self._handle_node_added(args) + elif notify_type == self.SIGNAL_NODE_EVENT: + self._handle_node_event(args) + elif notify_type == self.SIGNAL_NODE_NAMING: + self._handle_node_naming(args) + elif notify_type == self.SIGNAL_NODE_NEW: + self._handle_node_new(args) + elif notify_type == self.SIGNAL_NODE_PROTOCOL_INFO: + self._handle_node_protocol_info(args) + elif notify_type == self.SIGNAL_NODE_READY: + self._handleNodeReady(args) + elif notify_type == self.SIGNAL_NODE_REMOVED: + self._handle_node_removed(args) + elif notify_type == self.SIGNAL_GROUP: + self._handle_group(args) + elif notify_type == self.SIGNAL_SCENE_EVENT: + self._handle_scene_event(args) + elif notify_type == self.SIGNAL_VALUE_ADDED: + self._handle_value_added(args) + elif notify_type == self.SIGNAL_VALUE_CHANGED: + self._handle_value_changed(args) + elif notify_type == self.SIGNAL_VALUE_REFRESHED: + self._handle_value_refreshed(args) + elif notify_type == self.SIGNAL_VALUE_REMOVED: + self._handle_value_removed(args) + elif notify_type == self.SIGNAL_POLLING_DISABLED: + self._handle_polling_disabled(args) + elif notify_type == self.SIGNAL_POLLING_ENABLED: + self._handle_polling_enabled(args) + elif notify_type == self.SIGNAL_CREATE_BUTTON: + self._handle_create_button(args) + elif notify_type == self.SIGNAL_DELETE_BUTTON: + self._handle_delete_button(args) + elif notify_type == self.SIGNAL_BUTTON_ON: + self._handle_button_on(args) + elif notify_type == self.SIGNAL_BUTTON_OFF: + self._handle_button_off(args) + elif notify_type == self.SIGNAL_ALL_NODES_QUERIED: + self._handle_all_nodes_queried(args) + elif notify_type == self.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD: + self._handle_all_nodes_queried_some_dead(args) + elif notify_type == self.SIGNAL_AWAKE_NODES_QUERIED: + self._handle_awake_nodes_queried(args) + elif notify_type == self.SIGNAL_ESSENTIAL_NODE_QUERIES_COMPLETE: + self._handle_essential_node_queries_complete(args) + elif notify_type == self.SIGNAL_NODE_QUERIES_COMPLETE: + self._handle_node_queries_complete(args) + elif notify_type == self.SIGNAL_MSG_COMPLETE: + self._handle_msg_complete(args) + elif notify_type == self.SIGNAL_NOTIFICATION: + self._handle_notification(args) + elif notify_type == self.SIGNAL_DRIVER_REMOVED: + self._handle_driver_removed(args) + elif notify_type == self.SIGNAL_CONTROLLER_COMMAND: + self._handle_controller_command(args) + else: + print('Skipping unhandled notification [%s]' % args) + except: + import sys, traceback + print('Error in manager callback : %s' % traceback.format_exception(*sys.exc_info())) + + def wait_for_ready(self): + for i in range(0,20): + if self.ready == True: + break + else: + time.sleep(1.0) + print("Network ready : %s"%self.ready) + + def wait_for_queue(self): + for i in range(0,60): + if self.manager.getSendQueueCount(self.homeid) <= 0: + break + else: + time.sleep(0.5) + + def _handle_driver_failed(self, args): + self.driver_state = "DriverFailed" + self.driver_failed = True + print('Z-Wave Notification DriverFailed : %s' % args) + + def _handle_driver_ready(self, args): + self.driver_state = "DriverReady" + self.homeid = int(args['homeId']) + self.driver_ready = True + print('Z-Wave Notification DriverReady : %s' % args) + + def _handle_driver_reset(self, args): + self.driver_state = "DriverReset" + self.driver_reset = True + print('Z-Wave Notification DriverReset : %s' % args) + + def _handle_driver_removed(self, args): + print('Z-Wave Notification DriverRemoved : %s' % args) + self.driver_state = "DriverRemoved" + self.driver_removed = True + + def _handle_group(self, args): + print('Z-Wave Notification Group : %s' % args) + + def _handle_node(self, node): + print('Z-Wave Notification Node : %s' % node) + + def _handle_node_added(self, args): + print('Z-Wave Notification NodeAdded : %s' % args) + self.nodes[args['nodeId']] = {} + + def _handle_scene_event(self, args): + print('Z-Wave Notification SceneEvent : %s' % args) + + def _handle_node_event(self, args): + print('Z-Wave Notification NodeEvent : %s' % args) + + def _handle_node_naming(self, args): + print('Z-Wave Notification NodeNaming : %s' % args) + self.nodes[args['nodeId']] = {'NodeNaming' : True } + + def _handle_node_new(self, args): + print('Z-Wave Notification NodeNew : %s' % args) + + def _handle_node_protocol_info(self, args): + print('Z-Wave Notification NodeProtocolInfo : %s' % args) + + def _handle_node_removed(self, args): + print('Z-Wave Notification NodeRemoved : %s' % args) + + def _handle_essential_node_queries_complete(self, args): + print('Z-Wave Notification EssentialNodeQueriesComplete : %s' % args) + + def _handle_node_queries_complete(self, args): + print('Z-Wave Notification NodeQueriesComplete : %s' % args) + + def _handle_all_nodes_queried(self, args): + self.network_state = "AllNodesQueried" + self.network_ready = True + self.ready = True + print('Z-Wave Notification AllNodesQueried : %s' % args) + + def _handle_all_nodes_queried_some_dead(self, args): + self.network_state = "AllNodesQueriedSomeDead" + self.network_ready = True + self.ready = True + print('Z-Wave Notification AllNodesQueriedSomeDead : %s' % args) + + def _handle_awake_nodes_queried(self, args): + self.network_state = "AwakeNodesQueried" + self.network_awake = True + print('Z-Wave Notification AwakeNodesQueried : %s' % args) + + def _handle_polling_disabled(self, args): + print('Z-Wave Notification PollingDisabled : %s' % args) + + def _handle_polling_enabled(self, args): + print('Z-Wave Notification PollingEnabled : %s' % args) + + def _handle_create_button(self, args): + print('Z-Wave Notification CreateButton : %s' % args) + + def _handle_delete_button(self, args): + print('Z-Wave Notification DeleteButton : %s' % args) + + def _handle_button_on(self, args): + print('Z-Wave Notification ButtonOn : %s' % args) + + def _handle_button_off(self, args): + print('Z-Wave Notification ButtonOff : %s' % args) + + def _handle_value_added(self, args): + print('Z-Wave Notification ValueAdded : %s' % args) + + def _handle_value_changed(self, args): + print('Z-Wave Notification ValueChanged : %s' % args) + + def _handle_value_refreshed(self, args): + print('Z-Wave Notification ValueRefreshed : %s' % args) + + def _handle_value_removed(self, args): + print('Z-Wave Notification ValueRemoved : %s' % args) + + def _handle_notification(self, args): + print('Z-Wave Notification : %s' % args) + + def _handle_controller_command(self, args): + print('Z-Wave ControllerCommand : %s' % args) + + def _handle_msg_complete(self, args): + print('Z-Wave Notification MsgComplete : %s' % args) + diff --git a/tests/lib/test_driver.py b/tests/lib/test_driver.py new file mode 100644 index 00000000..087033cd --- /dev/null +++ b/tests/lib/test_driver.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +.. module:: tests + +This file is part of **python-openzwave** project https://github.com/OpenZWave/python-openzwave. + :platform: Unix, Windows, MacOS X + :sinopsis: openzwave Library + +.. moduleauthor: bibi21000 aka Sébastien GALLET + +License : GPL(v3) + +**python-openzwave** is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +**python-openzwave** is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with python-openzwave. If not, see http://www.gnu.org/licenses. + +""" + +import sys, os, shutil, stat +import time +import unittest +from pprint import pprint +import datetime +import random +import socket +import libopenzwave +from .common import TestLib +import re +from tests.common import pyozw_version +from six import string_types + +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + """NullHandler logger for python 2.6""" + def emit(self, record): + pass + +class TestDriver(TestLib): + + def setUp(self): + self.options = libopenzwave.PyOptions(config_path="openzwave/config", \ + user_path=self.userpath, cmd_line="--logging false") + self.options.lock() + + def test_100_start(self): + time.sleep(1.0) + self.manager = libopenzwave.PyManager() + self.manager.create() + self.manager.addWatcher(self.zwcallback) + time.sleep(1.0) + self.manager.addDriver(self.device) + for i in range(0,600): + if self.driver_ready: + break + else: + time.sleep(0.1) + self.assertTrue(self.driver_ready) + #~ for i in range(0,600): + #~ if self.network_awake: + #~ break + #~ else: + #~ time.sleep(0.1) + #~ self.assertTrue(self.network_awake) + for i in range(0,1200): + if self.network_ready: + break + else: + time.sleep(0.1) + self.assertTrue(self.network_ready) + self.manager.removeDriver(self.device) + for i in range(0,600): + if self.driver_removed: + break + else: + time.sleep(0.1) + self.assertTrue(self.driver_removed) + time.sleep(1.0) + self.manager.removeWatcher(self.zwcallback) + time.sleep(1.0) + self.manager.destroy() + time.sleep(1.0) + self.manager = None + + +if __name__ == '__main__': + sys.argv.append('-v') + unittest.main() diff --git a/tests/lib/test_node.py b/tests/lib/test_node.py index 2dc13b63..b7b504fc 100644 --- a/tests/lib/test_node.py +++ b/tests/lib/test_node.py @@ -33,11 +33,11 @@ import datetime import random import socket -import libopenzwave -from common import TestLib +from .common import TestLib import re from tests.common import pyozw_version from six import string_types +import libopenzwave import logging try: # Python 2.7+ @@ -47,297 +47,16 @@ class NullHandler(logging.Handler): """NullHandler logger for python 2.6""" def emit(self, record): pass -logger = logging.getLogger('test') - -class TestInit(TestLib): +class TestNode(TestLib): - SIGNAL_NETWORK_FAILED = 'NetworkFailed' - SIGNAL_NETWORK_STARTED = 'NetworkStarted' - SIGNAL_NETWORK_READY = 'NetworkReady' - SIGNAL_NETWORK_STOPPED = 'NetworkStopped' - SIGNAL_NETWORK_RESETTED = 'DriverResetted' - SIGNAL_NETWORK_AWAKED = 'DriverAwaked' - SIGNAL_DRIVER_FAILED = 'DriverFailed' - SIGNAL_DRIVER_READY = 'DriverReady' - SIGNAL_DRIVER_RESET = 'DriverReset' - SIGNAL_DRIVER_REMOVED = 'DriverRemoved' - SIGNAL_GROUP = 'Group' - SIGNAL_NODE = 'Node' - SIGNAL_NODE_ADDED = 'NodeAdded' - SIGNAL_NODE_EVENT = 'NodeEvent' - SIGNAL_NODE_NAMING = 'NodeNaming' - SIGNAL_NODE_NEW = 'NodeNew' - SIGNAL_NODE_PROTOCOL_INFO = 'NodeProtocolInfo' - SIGNAL_NODE_READY = 'NodeReady' - SIGNAL_NODE_REMOVED = 'NodeRemoved' - SIGNAL_SCENE_EVENT = 'SceneEvent' - SIGNAL_VALUE = 'Value' - SIGNAL_VALUE_ADDED = 'ValueAdded' - SIGNAL_VALUE_CHANGED = 'ValueChanged' - SIGNAL_VALUE_REFRESHED = 'ValueRefreshed' - SIGNAL_VALUE_REMOVED = 'ValueRemoved' - SIGNAL_POLLING_ENABLED = 'PollingEnabled' - SIGNAL_POLLING_DISABLED = 'PollingDisabled' - SIGNAL_CREATE_BUTTON = 'CreateButton' - SIGNAL_DELETE_BUTTON = 'DeleteButton' - SIGNAL_BUTTON_ON = 'ButtonOn' - SIGNAL_BUTTON_OFF = 'ButtonOff' - SIGNAL_ESSENTIAL_NODE_QUERIES_COMPLETE = 'EssentialNodeQueriesComplete' - SIGNAL_NODE_QUERIES_COMPLETE = 'NodeQueriesComplete' - SIGNAL_AWAKE_NODES_QUERIED = 'AwakeNodesQueried' - SIGNAL_ALL_NODES_QUERIED = 'AllNodesQueried' - SIGNAL_ALL_NODES_QUERIED_SOME_DEAD = 'AllNodesQueriedSomeDead' - SIGNAL_MSG_COMPLETE = 'MsgComplete' - SIGNAL_NOTIFICATION = 'Notification' - SIGNAL_CONTROLLER_COMMAND = 'ControllerCommand' - SIGNAL_CONTROLLER_WAITING = 'ControllerWaiting' - - STATE_STOPPED = 0 - STATE_FAILED = 1 - STATE_RESETTED = 3 - STATE_STARTED = 5 - STATE_AWAKED = 7 - STATE_READY = 10 - - @classmethod - def setUpClass(self): - super(TestLib, self).setUpClass() - self.options = libopenzwave.PyOptions(config_path="openzwave/config", \ - user_path=self.userpath, cmd_line="--logging false") - self.options.lock() - self.homeid = None - self.ready = False - time.sleep(1.0) - self.manager = libopenzwave.PyManager() - self.manager.create() - self.manager.addWatcher(self.zwcallback) - time.sleep(1.0) - self.manager.addDriver(self.device) - self.nodes = {} - time.sleep(1.0) + def setUp(self): + self.start_lib() self.wait_for_ready() - @classmethod - def tearDownClass(self): - self.manager.removeDriver(self.device) - self.manager.removeWatcher(self.zwcallback) - self.manager.destroy() - self.options.destroy() - super(TestLib, self).tearDownClass() - - @classmethod - def zwcallback(self, args): - logger.debug('zwcallback args=[%s]', args) - try: - notify_type = args['notificationType'] - if notify_type == self.SIGNAL_DRIVER_FAILED: - self._handle_driver_failed(args) - elif notify_type == self.SIGNAL_DRIVER_READY: - self._handle_driver_ready(args) - elif notify_type == self.SIGNAL_DRIVER_RESET: - self._handle_driver_reset(args) - elif notify_type == self.SIGNAL_NODE_ADDED: - self._handle_node_added(args) - elif notify_type == self.SIGNAL_NODE_EVENT: - self._handle_node_event(args) - elif notify_type == self.SIGNAL_NODE_NAMING: - self._handle_node_naming(args) - elif notify_type == self.SIGNAL_NODE_NEW: - self._handle_node_new(args) - elif notify_type == self.SIGNAL_NODE_PROTOCOL_INFO: - self._handle_node_protocol_info(args) - elif notify_type == self.SIGNAL_NODE_READY: - self._handleNodeReady(args) - elif notify_type == self.SIGNAL_NODE_REMOVED: - self._handle_node_removed(args) - elif notify_type == self.SIGNAL_GROUP: - self._handle_group(args) - elif notify_type == self.SIGNAL_SCENE_EVENT: - self._handle_scene_event(args) - elif notify_type == self.SIGNAL_VALUE_ADDED: - self._handle_value_added(args) - elif notify_type == self.SIGNAL_VALUE_CHANGED: - self._handle_value_changed(args) - elif notify_type == self.SIGNAL_VALUE_REFRESHED: - self._handle_value_refreshed(args) - elif notify_type == self.SIGNAL_VALUE_REMOVED: - self._handle_value_removed(args) - elif notify_type == self.SIGNAL_POLLING_DISABLED: - self._handle_polling_disabled(args) - elif notify_type == self.SIGNAL_POLLING_ENABLED: - self._handle_polling_enabled(args) - elif notify_type == self.SIGNAL_CREATE_BUTTON: - self._handle_create_button(args) - elif notify_type == self.SIGNAL_DELETE_BUTTON: - self._handle_delete_button(args) - elif notify_type == self.SIGNAL_BUTTON_ON: - self._handle_button_on(args) - elif notify_type == self.SIGNAL_BUTTON_OFF: - self._handle_button_off(args) - elif notify_type == self.SIGNAL_ALL_NODES_QUERIED: - self._handle_all_nodes_queried(args) - elif notify_type == self.SIGNAL_ALL_NODES_QUERIED_SOME_DEAD: - self._handle_all_nodes_queried_some_dead(args) - elif notify_type == self.SIGNAL_AWAKE_NODES_QUERIED: - self._handle_awake_nodes_queried(args) - elif notify_type == self.SIGNAL_ESSENTIAL_NODE_QUERIES_COMPLETE: - self._handle_essential_node_queries_complete(args) - elif notify_type == self.SIGNAL_NODE_QUERIES_COMPLETE: - self._handle_node_queries_complete(args) - elif notify_type == self.SIGNAL_MSG_COMPLETE: - self._handle_msg_complete(args) - elif notify_type == self.SIGNAL_NOTIFICATION: - self._handle_notification(args) - elif notify_type == self.SIGNAL_DRIVER_REMOVED: - self._handle_driver_removed(args) - elif notify_type == self.SIGNAL_CONTROLLER_COMMAND: - self._handle_controller_command(args) - else: - logger.warning('Skipping unhandled notification [%s]', args) - except: - import sys, traceback - logger.error('Error in manager callback : %s', traceback.format_exception(*sys.exc_info())) - - @classmethod - def wait_for_ready(self): - for i in range(0,15): - if self.ready == True: - break - else: - time.sleep(1.0) - - @classmethod - def _handle_driver_failed(self, args): - logger.warning('Z-Wave Notification DriverFailed : %s', args) - - @classmethod - def _handle_driver_ready(self, args): - logger.debug('Z-Wave Notification DriverReady : %s', args) - self.homeid = args['homeId'] - - @classmethod - def _handle_driver_reset(self, args): - logger.debug('Z-Wave Notification DriverReset : %s', args) - - @classmethod - def _handle_driver_removed(self, args): - logger.debug('Z-Wave Notification DriverRemoved : %s', args) - - @classmethod - def _handle_group(self, args): - logger.debug('Z-Wave Notification Group : %s', args) - - @classmethod - def _handle_node(self, node): - logger.debug('Z-Wave Notification Node : %s', node) - - @classmethod - def _handle_node_added(self, args): - logger.debug('Z-Wave Notification NodeAdded : %s', args) - self.nodes[args['nodeId']] = {} - - @classmethod - def _handle_scene_event(self, args): - logger.debug('Z-Wave Notification SceneEvent : %s', args) - - @classmethod - def _handle_node_event(self, args): - logger.debug('Z-Wave Notification NodeEvent : %s', args) - - @classmethod - def _handle_node_naming(self, args): - logger.debug('Z-Wave Notification NodeNaming : %s', args) - self.nodes[args['nodeId']] = {'NodeNaming' : True } - - @classmethod - def _handle_node_new(self, args): - logger.debug('Z-Wave Notification NodeNew : %s', args) - - @classmethod - def _handle_node_protocol_info(self, args): - logger.debug('Z-Wave Notification NodeProtocolInfo : %s', args) - - @classmethod - def _handle_node_removed(self, args): - logger.debug('Z-Wave Notification NodeRemoved : %s', args) - - @classmethod - def _handle_essential_node_queries_complete(self, args): - logger.debug('Z-Wave Notification EssentialNodeQueriesComplete : %s', args) - - @classmethod - def _handle_node_queries_complete(self, args): - logger.debug('Z-Wave Notification NodeQueriesComplete : %s', args) - - @classmethod - def _handle_all_nodes_queried(self, args): - logger.debug('Z-Wave Notification AllNodesQueried : %s', args) - self.ready = True - - @classmethod - def _handle_all_nodes_queried_some_dead(self, args): - logger.debug('Z-Wave Notification AllNodesQueriedSomeDead : %s', args) - - @classmethod - def _handle_awake_nodes_queried(self, args): - logger.debug('Z-Wave Notification AwakeNodesQueried : %s', args) - - @classmethod - def _handle_polling_disabled(self, args): - logger.debug('Z-Wave Notification PollingDisabled : %s', args) - - @classmethod - def _handle_polling_enabled(self, args): - logger.debug('Z-Wave Notification PollingEnabled : %s', args) - - @classmethod - def _handle_create_button(self, args): - logger.debug('Z-Wave Notification CreateButton : %s', args) - - @classmethod - def _handle_delete_button(self, args): - logger.debug('Z-Wave Notification DeleteButton : %s', args) - - @classmethod - def _handle_button_on(self, args): - logger.debug('Z-Wave Notification ButtonOn : %s', args) - - @classmethod - def _handle_button_off(self, args): - logger.debug('Z-Wave Notification ButtonOff : %s', args) - - @classmethod - def _handle_value_added(self, args): - logger.debug('Z-Wave Notification ValueAdded : %s', args) - - @classmethod - def _handle_value_changed(self, args): - logger.debug('Z-Wave Notification ValueChanged : %s', args) - - @classmethod - def _handle_value_refreshed(self, args): - logger.debug('Z-Wave Notification ValueRefreshed : %s', args) - - @classmethod - def _handle_value_removed(self, args): - logger.debug('Z-Wave Notification ValueRemoved : %s', args) - - @classmethod - def _handle_notification(self, args): - logger.debug('Z-Wave Notification : %s', args) - - @classmethod - def _handle_controller_command(self, args): - logger.debug('Z-Wave ControllerCommand : %s', args) - - @classmethod - def _handle_msg_complete(self, args): - logger.debug('Z-Wave Notification MsgComplete : %s', args) - - def test_100_controller_name(self): - #~ oldname = self.manager.getNodeName(self.homeid, 1) - #~ self.assertTrue(isinstance(oldname, string_types)) + def skip_100_controller_name(self): + oldname = self.manager.getNodeName(self.homeid, 1) + self.assertTrue(isinstance(oldname, string_types)) self.manager.setNodeName(self.homeid, 1, "test lib name") newname = self.manager.getNodeName(self.homeid, 1) self.assertTrue(isinstance(newname, string_types)) @@ -349,11 +68,6 @@ def test_101_controller_name_accent(self): newname = self.manager.getNodeName(self.homeid, 1) self.assertTrue(isinstance(newname, string_types)) - def test_110_controller_name_notification(self): - self.nodes[1]['NodeNaming'] = False - self.manager.setNodeName(self.homeid, 1, "test lib name") - time.sleep(1) - self.assertTrue(self.nodes[1]['NodeNaming']) if __name__ == '__main__': sys.argv.append('-v') diff --git a/tests/manager/autobuild/test_manager.py b/tests/manager/autobuild/test_manager.py index 9b9cebf8..d8568016 100644 --- a/tests/manager/autobuild/test_manager.py +++ b/tests/manager/autobuild/test_manager.py @@ -32,7 +32,7 @@ import sys import time import logging -import json as mjson +import unittest from tests.manager.common import TestManager @@ -40,6 +40,7 @@ class ManagerTest(TestManager): def test_000_import(self): from pyozwman.ozwsh_main import MainWindow + from pyozwman.ozwsh_widgets import NodeTree if __name__ == '__main__': sys.argv.append('-v') diff --git a/tests/manager/common.py b/tests/manager/common.py index 89356f06..926cee57 100644 --- a/tests/manager/common.py +++ b/tests/manager/common.py @@ -29,7 +29,6 @@ import sys, os import time import logging -import json as mjson from tests.common import SLEEP from tests.common import TestPyZWave diff --git a/tests/web/autobuild/test_web.py b/tests/web/autobuild/test_web.py index ddfa4f8d..52488258 100644 --- a/tests/web/autobuild/test_web.py +++ b/tests/web/autobuild/test_web.py @@ -32,16 +32,16 @@ import sys import time import logging -import json as mjson +import unittest -from tests.web.common import FlaskTestBase +#~ from tests.web.common import FlaskTestBase -class FlaskTest(FlaskTestBase): +#~ class FlaskTest(FlaskTestBase): - def test_000_import_listener(self): - self.skipPython3() - from pyozwweb.app.listener import ListenerThread, start_listener, stop_listener - from pyozwweb.app import run_app, create_app + #~ def test_000_import_listener(self): + #~ self.skipPython3() + #~ from pyozwweb.app.listener import ListenerThread, start_listener, stop_listener + #~ from pyozwweb.app import run_app, create_app if __name__ == '__main__': sys.argv.append('-v') diff --git a/tests/web/common.py b/tests/web/common.py index 655f54bd..bb869546 100644 --- a/tests/web/common.py +++ b/tests/web/common.py @@ -29,7 +29,6 @@ import sys, os import time import logging -import json as mjson from flask import Flask diff --git a/tests/web/test_server.py b/tests/web/test_server.py index 1ada13f4..b5833cfe 100644 --- a/tests/web/test_server.py +++ b/tests/web/test_server.py @@ -32,49 +32,49 @@ import sys import time import logging -import json as mjson +import unittest -from flask.ext.socketio import SocketIO, emit, join_room, leave_room, close_room, disconnect -from flask.ext.socketio.test_client import SocketIOTestClient -from tests.web.common import FlaskTestCase +#~ from flask.ext.socketio import SocketIO, emit, join_room, leave_room, close_room, disconnect +#~ from flask.ext.socketio.test_client import SocketIOTestClient +#~ from tests.web.common import FlaskTestCase -class FlaskServerTest(FlaskTestCase): +#~ class FlaskServerTest(FlaskTestCase): - def test_000_server_start(self): - rv = self.client.get('/') - self.assertTrue('Welcome to PyOzwWeb' in rv.data) + #~ def test_000_server_start(self): + #~ rv = self.client.get('/') + #~ self.assertTrue('Welcome to PyOzwWeb' in rv.data) - def test_001_error_404(self): - rv = self.client.get('/bad_page') - self.assertEqual(rv.status,'404 NOT FOUND') + #~ def test_001_error_404(self): + #~ rv = self.client.get('/bad_page') + #~ self.assertEqual(rv.status,'404 NOT FOUND') - def test_100_home_is_up(self): - rv = self.client.get('/') - self.assertEqual(rv.status,'200 OK') + #~ def test_100_home_is_up(self): + #~ rv = self.client.get('/') + #~ self.assertEqual(rv.status,'200 OK') - def test_200_controller_is_up(self): - rv = self.client.get('/controller') - self.assertEqual(rv.status,'200 OK') + #~ def test_200_controller_is_up(self): + #~ rv = self.client.get('/controller') + #~ self.assertEqual(rv.status,'200 OK') - def test_300_values_is_up(self): - rv = self.client.get('/values') - self.assertEqual(rv.status,'200 OK') + #~ def test_300_values_is_up(self): + #~ rv = self.client.get('/values') + #~ self.assertEqual(rv.status,'200 OK') - def test_400_controller_is_up(self): - rv = self.client.get('/debug') - self.assertEqual(rv.status,'200 OK') + #~ def test_400_controller_is_up(self): + #~ rv = self.client.get('/debug') + #~ self.assertEqual(rv.status,'200 OK') - def test_500_node_is_up(self): - rv = self.client.get('/node/1') - self.assertEqual(rv.status,'200 OK') + #~ def test_500_node_is_up(self): + #~ rv = self.client.get('/node/1') + #~ self.assertEqual(rv.status,'200 OK') - def test_600_map_is_up(self): - rv = self.client.get('/map') - self.assertEqual(rv.status,'200 OK') + #~ def test_600_map_is_up(self): + #~ rv = self.client.get('/map') + #~ self.assertEqual(rv.status,'200 OK') - def test_700_scenes_is_up(self): - rv = self.client.get('/scenes') - self.assertEqual(rv.status,'200 OK') + #~ def test_700_scenes_is_up(self): + #~ rv = self.client.get('/scenes') + #~ self.assertEqual(rv.status,'200 OK') #def test_500_socketio_home(self): # rv = self.app.get('/socketio/')