whaleygeek / pyenergenie

A python interface to the Energenie line of products
MIT License
82 stars 51 forks source link

Using the ENER314-RT as both receiver and transmitter simultaneously. #90

Closed ghost closed 5 years ago

ghost commented 6 years ago

I'm currently working on building my home automation platform using Home Assistant. Rather than hammering the Energenie API i bought a ENER314-RT which i'm using pyenergenie to interact with.

Currently I poll my door sensors for its latest status so that i'm able to build automations based on doors opening with only a short delay, today I attempted to run a transmit script to turn a socket on / off, which then stopped my polling script from working completely (not just delayed the reads).

I understand that the board can only do so much but is it possible to use it as a receiver and pause if a transmit request has been sent?

whaleygeek commented 6 years ago

Hi @Pow377 sounds like a great project.

You can only have one script talking to the radio at any one time, so you will have to merge transmit and receive functionality into a single combined script. That might be what you are doing already.

There is already some 'stacking' behaviour in the radio state machine, so if you put the radio into receive mode then request a transmit, it should immediately return into receive mode at the end. Also, if you are mixing OOK devices with FSK devices, you might have to do a bit of work under the bonnet to get it to switch modulation schemes when returning from transmit mode. Although, as OOK is transmit only and FSK is transmit and receive, this should just come out in the wash. i.e. if you leave it in FSK receive mode for the polling, then ask to transmit a message in any modulation, I think it should switch back to the previous receive mode at the end. It's only if you request standby mode that it will turn the radio off completely (e.g. power saving) after a transmit.

So, in summary, if you use this general sequence...

while True:
    radio.standby()
    wait a bit
    radio.receive()
    radio.transmit()

Then you get a low power (mostly off) duty cycle.

If you use this...

radio.receive()
while True:
    wait a bit
    radio.transmit()

You should get a mostly receive oriented with an occasional transmit.

(bits are missing in the above code, but you'll probably get the general idea).

I have it on the long term todo list to 'learn' the transmit times of reporting sockets, and then split time up into a series of timeslots, some allocated for receive and some for transmit, as that will make such a scheme more deterministic. But that's quite a bit of work to do it in a generic way that works for all scenarios.

I'm pretty sure that all receipt messages have a timestamp in them somewhere, so you could have a first crack at doing this scheduling in your application - learn which second in the minute that a specific plug reports it's status, and never schedule a transmit if it is close to that second in the current minute. If you have multiple devices, you'll need a list of 'expected receipt times' and basically build guard windows around those. Once you are out of a guard window for expected receipts, if you have a transmit message on a transmit queue somewhere, peel off the next transmit message from that tx queue (a Python list) and transmit it.

That's not far off what I plan to build into the standard library but you might be able to get close to that within your application.

The timing of the energenie devices might not be that accurate (they probably have a cheap low tolerance timebase in them), so you should make the 'learning the reporting rate' of each device a bit dynamic, perhaps by just remembering the last time it reported and using that in the next minute.

Something that is completely event driven (e.g. a door switch with no time guards) is much much harder as you never know when it will report and it could easily collide with other sensors.

There is a pathway in the code to allow two or more radios to be connected, and I always had a view that one day I would support a dual radio solution with one in permanent receive and one in scheduled transmit. You'd have to set them quite a distance apart to prevent one deafening the other, but it might work. Again, that's quite a lot of work.

Hope this helps a bit.

David

ghost commented 6 years ago

Thanks, I’ll take a look at this and have a play. Not sure if it’ll all work as a reliable method for home automation. Especially with the potential missed readings from a door sensor from a security perspective.

Ill see what i can come up with, Thanks again

gpbenton commented 6 years ago

I'm currently working on building my home automation platform using Home Assistant.

I have been using my MQTT project with Home Assistant and the ENER314-RT to achieve two way communications with 3 Energenie eTRVs. The TRVs use the FSK protocol though, so my project would need some adapting if you just want to use it to receive the OOK protocol that typical sensors use.

I use this project to receive data from 433 MHz OOK sensors (including energenie remotes), and send the codes to Home Assistant.