Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the correct way to send unsolicited replies based on events ? #297

Open
auphofBSF opened this issue Jun 15, 2021 · 8 comments
Open

Comments

@auphofBSF
Copy link

auphofBSF commented Jun 15, 2021

My use case is to simulate a basic serial device over tcp that responds to commands but also sends unsolicited messages

The doc's strings and Readthedocs are great but I feel I am missing something

I am using a TCP Stream Based on Motor Example

I have successfully implemented Cmd's and get the correct responses

I would like to get an unsolicited_reply() from the StreamHandler when the following events happen

  1. a new connection is made to the simulation interface with Telnet Host:Port (no data yet sent from Client) -> Generates a Welcome message
  2. a periodic (Non Regular - random time interval) event happens in the simulated Device subclassing StateMachineDevice and sends an unsolicited_reply to the TCP client, ie simulating a state change through lewis-control device ....
  3. a periodic (regular - fixed time interval) variant of 2.
@mattclarke
Copy link
Member

@DominicOram Any ideas/tips for this?

@DominicOram
Copy link
Contributor

Does https://github.com/ess-dmsc/lewis/tree/message_on_init fix point 1? You should be able to add something like the following in your strream interface:

def initial_message(self):
    return b"Hello World"

I'll think about 2 and 3 later today...

@auphofBSF
Copy link
Author

Thank you @DominicOram initial_message works well.

With regard to 2&3 I have spent a few hours trying to see how find the current active StreamHandlers from the process method in StateMachineDevice, getting a deeper understanding of lewis but have not been successful yet, so look forward to your thoughts, Thank you again

@DominicOram
Copy link
Contributor

Yh, the issue is that unsolicited_reply is a bit of a hack. The StreamInterface side holds a reference to the device but not the other way round. This means when we've used unsolicited_reply in the past we've ended up putting what should really be device logic into the StreamInterface or we've set the unsolicited reply to just send periodically. I guess the second link solves 3 for you but still isn't elegant.

@auphofBSF
Copy link
Author

Selfishly only considering the adapters.stream,

Could device have a legitimate reference to StreamServer and device have method stream_event_message .

Then StreamServer in the process method forwards stream_event_message if it exists to all handler in _accepted_connections in a similar method to your initial_message suggestion

It is then logic in device to decide periodicity or specific condition for generating stream_event_message

StreamInterface by handler can either just forward message by default event_message method or do further processing by overwritting with a event_message method in the custom impementation of StreamInterface

@auphofBSF
Copy link
Author

auphofBSF commented Jun 16, 2021

I have explored this in https://github.com/auphofBSF/lewis/tree/wip_297_unsolicited_messages

In principle it works but generates deque errors and eventually crashes the connection. The across thread comms needs addressing

@auphofBSF
Copy link
Author

Ok I have fixed the deque and connection trashing issue, tidied up the solution proposed and could do with a review
https://github.com/auphofBSF/lewis/tree/wip_297_unsolicited_messages with example now in branch in 836f263

It is achieving what I required but I am sure it needs to be aligned with lewis styling and more deeper understanding
I think how the adapters are attached to devices in simulation could be improved.

I have created an example lewis -k lewis.examples simple_eventing_state_device that attempts to demonstrate some of the features that @DominicOram created with initial_message and what I have introduced in this fork.

With a bit more work, some docs, possibly a test or 2 and I think it can be converted to a PR, but before that I would like to get comment

@mattclarke
Copy link
Member

Can you create a draft PR please?
It makes it a bit easier for us to see what you have done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants