I still haven’t learned how to use asyncio properly, but I think you may need a way to pass in the HASS event loop to use rather than starting your own? Or does that happen somehow magically?
edit: I’m guessing it’s not an issue since I see a zone sensor bit of code in example.py and I assume it works.
Your code certainly seems cleaner than mine, and more elegant. And, being asyncio, is more “correct” way of doing things for HASS. I hadn’t used asyncio yet and instead stuck to threads because threading is a concept I more or less understand and asyncio hurts my brain (before working on Elk support and some minor other bits for HASS, I never wrote any Python code, so that doesn’t help either). I suspect we’d be best served by adding to your code, and switching to using it versus continuing to debug / enhance / etc my code.
I may fork my HASS code and do a quick and dirty modification to use your elk code (just as far as trying to scan everything on the Elk and create entities, not necessarily to work 100% for the moment) and see if it makes it through startup in a timely fashion when running on a Pi (the problem with my code at the moment … I took an approach to improving startup time that seems to halt and catch fire on a Pi but works fine on my x86 systems - basically abusing many threads pounding on HASS at the same time with complete disregard for asyncio)
As far as supporting real serial connections (not TCP/SSL sockets), probably the path of least resistance is using pyserial-asyncio? http://pyserial-asyncio.readthedocs.io/en/latest/api.html#module-serial_asyncio It looks like the pattern is nearly the same as the existing TCP/SSL asyncio connection pattern, just sub in the serial_asyncio module as needed and potentially throw in extra parameters for baudrate, etc.
Thank you for looking at the code! I appreciate your feedback!
Some quick answers for now, but look forward to engaging more.
The “example.py” used to work - it does not work at present. I have not updated it in a while. It should not take much. I created it more as a proof of concept when I started working with asyncio to see if I understood it enough to make it work. Building out the example is next on my backlog, using the same pattern I describe below for the main ElkM1 library. Although if you get your home-assistant code up and running on asyncio that would be cool!
Working with async and event driven code certainly turns your head upside down. Luckily for me I’ve written many event-driven pieces of software over the years.
This was my first python project, so learning how to do things “properly” took a fair bit of time. I have no idea if things are correct Pythonic code, but at least it feels right.
The code you see was many hours of refining. I started with just zones. I rewrote it a dozen times, looking to create SOLID code. Once I was comfortable with zones I then moved on to see if the pattern would work for other Elements on the Elk panel. I probably refactored another half dozen times as I learned about how the other Elements work.
My goals were asyncio first. Then just clean code that is easy to maintain. As I got into testing that is when the elk -i came into fruition. It became necessary to simply the code/test/feedback loop. I kept all message encode/decode in a single module (file??) and I refactored multiple times to get the the cleanest concepts that I could imagine. Learning about decorators was cool and I think helped create some pretty clean, simple, and easily maintainable code. I happy with that code.
With respect to serial IO… right on. I already have that dependency in the setup.py. I didn’t bother implementing it as I had no easy way to test it (other than pulling the serial off my ethernet board and finding a computer to plug it into – which I don’t have readily accessible). Once there is a serial “customer” who can stay engaged for an evening I’m happy to add serial support. It “should” be just a line of code to add serial and then a few bits of code to deal with baud rate etc.
If you have not tried the code I’d encourage you to go near the bottom of the README and try the three programs listed there.
All development I did was on a MacBook Pro. Should be interesting to see how well it works on Windows, et. al. The mkdoc program came out of necessity of trying to keep track of what Elk messages that needed to still be supported.
I’ll strap your code on my test rig pi. Spin it up and let you know how it behaves. As with BioSehnsucht your welcome to have remote access if debugging will be needed.
I have a JS module for the ELK I crafted for IRidium if you need any references
is the current version working at all? I just updated to the latest release, and I am getting some very unpredictable behavior. After restarting multiple times, sometimes devices show up, sometimes they do not. In addition to this, no devices seem to update their status either.
My experience is the current version has worked fine when running on beefier hardware (on a regular computer/server/etc) but is not suitable to run on anything lower end (like any kind of Pi device or similar).
Well as promised, I cloned down the repo to my HASS PI, which i use for testing, and have shared at the moment with @BioSehnsucht for his ELK driver, as its having some reliability issues on this hardware due to queuing etc.
HASS in its normal configuration suggests that we install a container which hosts an SSH environment that can be used to manage the configuration which is loaded by the main home assistant container. It turns out that the SSH container includes a Python3 build, but only responds when using the python3 command name.
Also PIP does not recognise the -p option for your Pipfile; a small tweak to the first line in the elk utility and running pip3 install [module name from Pipfile], and we are good to go.
First impression is that this is fast. very fast; its much more elegant than my own JS code;
I get all my Zones - there are over 180 cabled up!, and my outputs (about 40 cabled, but only using 8 or so actively); sending commands from the ELK syntax is toggling these on and off perfectly.
I have no errors to report…
Next step - connect this module to the Home Assistant, either directly (preferred), or via MQTT;
Top work, and really nice coding, my python skills are almost zero, but this is great code to learn from
One option you might want to consider is wrapping this code with an MQTT conversion and presenting it to HA that way. The upsides are that you can use it for other things besides HA, you can support additional features and commands that HA doesn’t know about, and it might be easier to maintain since it would have no dependencies on HA. The downsides of this approach is that it’s harder for many people to use (running a separate process) and it’s harder to use with hass.io since it’s a separate server process to configure and run. I used this approach for my insteon/mqtt bridge system and it worked great (at least for me) in that case - but insteon devices have a lot of other commands besides HA that are useful and need database management so that might not apply to an alarm panel.
Rather than making gwww’s new code MQTT natively itself, the usual method would be that if someone wants MQTT interface for it, a separate piece of code is created which imports / uses gwww’s code. Same for HASS (this is how my existing HASS code is set up - the Elk interface code is in a separate library which could in theory be used for other things, and the HASS code uses that library to interact with the Elk)
Form a couple of hours testing this code it’s solid. Running on the PI3 it’s behaving very well and a trigger of a sensor is reported instantly
I have also enabled my JS module speaking to the same endpoint concurrently and they both behave flawlessly.
What is the current of any thinking regarding a direction for building a component for Home Assistant or an MQTT wrapper. Either is greatly appericated, I would offer but I’m going to stay in learn mode and maybe use the learning to create a driver for my projector based on approach as a first try attempt at real python
MQTT is not something I’ve worked with, other than setting up a server and pointing already existing integrations at it. So I’ll leave that to someone else.
I’ll try to get my HASS code running on gwww’s Elk code in the next few days. Just need to find a few free productive hours to get it done. Once I’ve got it working with what gwww has implemented so far, I’ll look at adding code for Thermostats and anything else that might not be present yet to his code and submit a PR, unless he beats me to it
Hey, lots happened since I last had a chance to look. This is great!
I’d like to see the Hass plugins next. My interest is in getting my Elk system integrated with Hass.
There’s still some library work to do…
disconnect/reconnect logic
Thermostats
how to handle temperature zones “correctly”; there’s handling for the message but no polling in place. Should there be? Similar to zone voltage. No polling in place. It doesn’t seem like there needs to be. Could the polling happen from Hass?
a couple of Elk messages still need encoders/decoders (IC message for example)
then there’s some stuff that needs to be decided if it should be supported: keypad messages for example
I’m guessing more questions will pop up when this gets put into use.
Most of the coding is probably not too hard, although I can’t say much about thermostats as I don’t have the spec for that. Is it online somewhere?
Has anyone run the mkdoc program in the bin directory of the library? Input on the message to implement next would be helpful.
I’m interested in learning more about MQTT sometime but prefer to get some of the above stuff working.
One more bit to write is serial support. I think it should be easy to add. I’ve got no simple way to test it. Anyone using serial interface with their Elk?
By default the Elk will send updates when a temp zone (or any other temp sensor) changes. But you can also query them by one of the commands I think. At least for sure you can query thermostat and keypad temp sensors, I think also zone temp sensors. There’s one command for all of them, you specify which group (zone/thermostat/keypad) and unit number to request. There’s also a separate request specific to thermostats which sends back more data (kind of redundant that you can request thermostat multiple ways … )
I just want to give a vote for the keypad messages feature.
I was using HomeSeer in the past with the Elk plugin and made use of this feature extensively to display outdoor temperature and forecast, send user/code specific messages based on the code entered to disarm or various reminders (just disarmed the alarm, still have your winter boots and coat on, no better time to be reminded to put the trash on curb for pickup tomorrow morning).
I know some of these can be automated with the elk tasks and automation but you become limited quickly when you need some dynamic data (weather, calendar events, etc).