Package: pyduofern
pyduofernDisclaimer:this library isnotendorsed by the company Rademacher, the manufacturer of home automation products
under the label duofern. The name pyduofern was chosen to indicate the function of the library: communicating with
duofern devices via python.These are my efforts in porting theFHEMDuofern USB-Stickbased module toHomeassistant. As of now the port is rather ugly, but it is usable enough to control
my Duofern blinds. I did not port the Weather-Station related features of the original module – Mainly because I
do not own the corresponding hardware and have no means to test if it works. I only tested it with the modelRolloTron Standard DuoFern 14233011 Funk-Gurtwickler Aufputz.As reported in#3110-Digit codes recently announced by Rademacher are not supported as of now as the handshake/
protocol for these devices was not reverse engineered by anyone as far as I know.This requires the Duofern USB Stick Art.-Nr.: 70000093 by Rademacher.I do not provide any guarantees for the usability of this software. Use at your own risk.License:python interface for dufoern usb stick
Copyright (C) 2017 Paul Görgen
Rough python python translation of the FHEM duofern modules by telekatz
           (also licensed under GPLv2)
This re-write does not literally contain contain any verbatim lines
of the original code (given it was translated to another language)
apart from some comments to facilitate translation of the not-yet
translated parts of the original software. Modification dates are
documented as submits to the git repository of this code, currently
maintained at `https://github.com/gluap/pyduofern.git <https://github.com/gluap/pyduofern.git>`_

This program 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 2 of the License, or
(at your option) any later version.

This program 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 this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USAGetting StartedInstall via:pip3 install pyduofernor if you want the development version from github:pip3 install git+https://github.com/gluap/pyduofern.git@devudev configurationto make your usb stick easy to identify deploy anudev rulesfile in/etc/udev/rules.d/98-duofern.rulesor the equivalent of your distribution. The following worked for my
stick:SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="duofernstick"Or, if you use several USB-Serial adapters with vendor0403and product6001find out the serial number of your
stick (assuming it is currently registered as/dev/ttyUSB0`):user@host:~ > udevadm info -a -n /dev/ttyUSB0 | grep '{serial}' | head -n1
ATTRS{serial}=="WR04ZFP4"As you can se for me the serial isWR04ZFP4. Use the following udev line (use the serial you found above):SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="WR04ZFP4", SYMLINK+="duofernstick"Once the rule is deployed your stick should show up as/dev/duofernstickas soon as you plug it in. This
helps avoid confusion if you use other usb-serial devices. Also be warned: The line also makes the stick
accessible to non-root users. But likely on your system you will be the only user anyhow.Getting StartedTo start using your stick you can use theduofern_cli.pyscript which should have been installed together
with the pyduofern module. Begin by choosing a 4 hex-digit system code. If you have already used the roller shutters
with FHEM use the last 4 digits of your FHEM code to preserve pairings. Ideally write it down, if you forget
it, you will likely have to chose a new system code and reset your devices in order to be able to pair them again.
It is also a security feature which is why no default is provided.Decide for a system configuration file. By default it will reside as a hidden config file in your home directory in~/.duofern.json. Pass the config file toduofern_cli.pyvia the command line option--configfile.
The default has the advantage that you do not always have to pass the config file when using the script. Initialize
the config file with your system code with the following command:duofern_cli.py --code <your chosen 4 digit hex code here>
# or if you prefer your own configfile location
doufern_cli.py --code <your chosen 4 digit hex code here> --configfile <your config file path>Now RTFM of the shutter to find out how to start pairing. Set the maximum and minimum positions according to the manual.
If you want to experiment with the shutter first, chose the two positions very near each other. The motors shut down
after a certain maximum runtime and you could exceed that while experimenting if you move the shutters up and down
several times unless the min and max positions are close to each other.Start out by pairing your first rollershutter:duofern_cli.py --pair --pairtime 60now initiate pairing via the buttons on your shutter. Once a shutter is paired it should show up in your
config file and you can name it. Say the blind that popped up has the ID408ea2, run the following to give it
the namekitchen:duofern_cli.py --set_name 408ea2 kitchen
# you can now try to also have it move up or down:
duofern_cli.py --up kitchen
# or try to set the position of a blind (0=down, 100=up)
duofern_cli.py --position 42 kitchenHopefully you now have working command line interface that knows how to move up or down your shutters. But the python
interface can do more, (which I was so far too lazy to expose via the command line):Indexing paired blindsIf you have the system code of your system but lost the list of configured blinds you can use the CLI to refresh
the config file with all paired blinds.:# assuming you lost the config file
duofern_cli.py --code <your code> --refresh --refreshtime 60will start up the stick and listen for connecting blinds for 60 seconds. It will store all the blinds that were found
in the default config file.aUsage with HomeassistantThere is a custom component for homeassistant that can be easily deployed via hacs athttps://github.com/gluap/pyduofern-hacsUsage from pythonfrompyduofern.duofern_stickimportDuofernStickThreadedimporttimestick=DuofernStickThreaded(device="/dev/duofernstick")# by default looks for /dev/duofernstickstick._initialize()# do some initialization sequence with the stickstick.start()# start the stick in a thread so it keeps communicating with your blindstime.sleep(10)# let it settle to be able to talk to your blinds.# your code here# this uses internal variables of the duofern parser module and likely I will wrap it in# the future.print(stick.duofern_parser.modules['by_code']['1ff1d3']['position'])command("1ff1d3","up")# open the blind with code 1ff1d3stick.command("1ff1d3","down")# down the blind with code 1ff1d3stick.command("1ff1d3","stop")# stop the blind with code 1ff1d3stick.command("1ff1d3","position",30)# set position of the blind with code 1ff1d3 to 30%Look for an indication of possible commands inpyduofern/definitions.pyI just translated them into python and did not explore what might be possible.
It looks like a lot of functionality requires a weather station, but you can just as
easily automate the stuff using your home automation and having it send the up and down
commands instead of buying a weather station.Changelog0.36add periodic requests for status updates.0.36add rudimentary tracking of successfully sent messages and resending of unacknowledged ones.0.35.1fix issue with crashes when “sets” was not defined because a bogous device type was present in duofern config.0.35.0limit message sending frequency.0.34.3Fix issue with asynchronous code in synchronous part of the code that was breaking homeassistant.0.34.2merged pull request by [@realbuxtehuder](https://github.com/realbuxtehuder) that adds stop command to cli0.34.1functionally equivalent to 0.34.0, removed shebangs where not required, moved unit tests outside of packaging0.34.0merge callback state updates for covers introduced by @DomiStyle in #21 to master0.33.0add smokedetector introduced by @DomiStyle in #20 to master0.32.0fix case to try and fix #18 for sensorMsg0.30.0breaking change: instead of creating multiple devices for single physical devices with multiple actor channels which was rather buggy add achannelparameter to the respective functions inpyduofern.duofern.Duofern() which allows to handle channels in a consistent manner. See discussion inhttps://github.com/gluap/pyduofern/pull/9. For each device available channels are listed in in Duofern().modules[‘by_code’][code][‘channels’]. The default channel available for all devices isNone, otherwise anintis expected.0.25.2try to fixhttps://github.com/gluap/pyduofern/issues/20.25.1changed custom component to fix bug in switch implementation accidentally introduced recently.0.25restarted from 0.23 to get somewhat working auto detection0.24somewhat broken changes for auto detection0.23.5python 3.7 support should enable current hassio version0.23.3added--positionto CLI0.23.2renamed README.rst and moved version number fromsetup.pyto__init__.py0.23.1fixed references to repository urlupped version for pypi release0.23added recordings and increased coverage of unit tests (no result-based tests yet though – just checking if every replay runs until the end without hanging)0.22Added recording of actions for replay in integration testsImproved unit testsEnable travisEnable coveralls0.21.1fixed bug where device IDs containingccwould be be messed up when inserting channel number.