whaleygeek / pyenergenie

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

Best method for an error time out #26

Closed ninjawil closed 8 years ago

ninjawil commented 8 years ago

Hi

I have taken your code and branched it to suit my application. It works very well and I want to thank you for your hard work.

I have made some changes just to the way I access your code, so I could send requests and commands when needed instead of a permanent loop. The way it's coded now means that the script will hang if no response is received from a request.

Just wanted to ask you what would be the best way to implement a time out if no response is received from the plug. I am thinking of using an interrupt to count down a timer but was wondering if this would affect any incoming responses and whether it would corrupt the message leading to further errors.

Any suggestions would be greatly appreciated.

Thank you

Will

whaleygeek commented 8 years ago

Hi Will,

You'll probably have to put most of the API code in a separate thread, and then signal to the thread when to transmit a message. It can then spin round looking for receives, and either signal via a shared variable, or call a callback, or add the received message to a queue, when a message comes in. Your main program (in the main thread) can then get on with other stuff, and send when it wants to, and receive when it is ready. You can then use a simple time.time() time horizon in the application to track when you sent a message, and whether you received a reply. If you did not receive a reply in an allowed timeout, you could resend the message or raise an error after a number of retries.

Here is a rough sketch of the basic idea:

send_msg = None receive_msg = None

in the thread body: while True: if send_msg != None: send(send_msg) send_msg = None check for receive if received message if receive_message != None: error, lost message (note, could add a queue here instead) else receive_message = msg

in the main program

start the thread (with thread body as above) while True: do various stuff at some arbitrary time when you want to send a message... while send_msg != None: wait a bit of time send_msg = message outstanding = True timer = time now + 5 seconds

if receive_msg != None:
    handle_received(receive_msg)
    outstanding = False
    receive_msg = None

if outstanding and time now > timer value
    did not get a response
    outstanding = False
    trigger resend of a message

There are many ways of solving this problem, but it is best that you choose one that you think is within the scope of your understanding of the python language.

Hope this helps.

whaleygeek commented 8 years ago

Sorry for the poor indentation in that example, but you can probably work it out.

Closing this issue as I believe I have provided an answer. I also have it on the TODO list to provide a range of different concurrency models for users, this being one of them.