fossasia / susi_linux

Hardware for SUSI AI https://susi.ai
Apache License 2.0
1.61k stars 148 forks source link

Planned Actions #521

Closed Orbiter closed 4 years ago

Orbiter commented 5 years ago

As a user I want to get timed actions: these are actions which are activated by a given time. Using timed actions it is possible to make not only "a timer" possible, but it is also possible to activate any kind of actions for a given time.

A broad range of use cases are possible:

Describe the solution you'd like

We need a scheduler which hosts SUSI actions which have time attributes attached. Such an action is not performed at the time when it arrives from the susi_server, instead it is performed if it is due in the scheduler. The due-date is arrived if the local date is greater than the date as given in the "plan" object.

To align the time of the server and the time of the client, the query_date as given in the susi response is used. This time is represented in the ISO8601 format and is time-zone independent.

The "plan" attributes are:

        "plan_delay": 60000,
        "plan_date": "2019-07-19T10:52:26.757Z"

Here the delay value is only used for debugging purpose, it is useful if the timed action was used for a timer; then the delay should represent the timer value in milliseconds.

A full susi response with timed actions would look like:


  "query": "set alarm in one minute",
  "query_date": "2019-06-24T13:36:25.490Z",
  "answer_date": "2019-06-24T13:36:25.752Z",
  "answers": [
    {
      "actions": [
      {
        "type": "answer",
        "expression": "Playing Metallica - Nothing Else Matters [Official Music Video]",
        "plan_delay": 60000,
        "plan_date": "2019-07-19T10:52:26.757Z"
      },
      {
        "type": "video_play",
        "identifier_type": "youtube",
        "identifier": "tAGnKpE4NCI",
        "plan_delay": 60000,
        "plan_date": "2019-07-19T10:52:26.757Z"
      },
      {
        "language": "en",
        "type": "answer",
        "expression": "alarm set in one minute to play music"
      }
    ]
  }
 ]
}

Here we have 3 Actions!

Important

It is NOT sufficient to use the local time of the client and just add up the delay time in milliseconds to compute a local due-time. We want that client can activate actions based on exact times as defined by the skill. This should be as exact as possible to make it feasible that this can be used for machine-to-machine interaction once several machines are using SUSI and communicate using timed events. Therefore

testing

Please use the following link: https://api.susi.ai/susi/chat.json?timezoneOffset=-120&q=set+alarm+in+one+minute

sansyrox commented 5 years ago

@Orbiter @norbusan , we can create a systemd.timer and .service on the fly to activate the service for every action that the user calls and disable the service on completion?

norbusan commented 5 years ago

@stealthanthrax For that we would need a way to inject actions into susi_linux main loop.but I think it would be better to have a scheduler in the python code that wakes up every sec and checks for events to be executed.

hongquan commented 5 years ago

Agree. Because of the vast variation of need for action/schedule, it should be implemented in our Python code. We need to create a candidate process to perform the action/job. Then from our main project, we send the task to that process, include the time we want it to be done.

We can use https://github.com/rq/rq-scheduler#periodic--repeated-jobs for this.

norbusan commented 5 years ago

@hongquan yes, I agree completely that we should do this in our own code.

Concerning your suggestion of rq-scheduler, this requires redis package. Isn't that a bit too heavy? I haven't really tried it out, though. Do you have experience with that?

hongquan commented 5 years ago

@norbusan No worries. Redis is one of the lightest software: https://packages.ubuntu.com/disco/redis-server

sansyrox commented 5 years ago

This makes much more sense.

have a scheduler in the python code that wakes up every sec and checks for events to be executed

sansyrox commented 5 years ago

@hongquan , we can also use something like rabbitmq and celery for task scheduling

hongquan commented 5 years ago

@stealthanthrax Those names are more wel-known, but they are too fat and slow, especially on an ARM computer like Raspberry Pi.

norbusan commented 5 years ago

What about https://github.com/dbader/schedule/ which is also on pypi, very lightweight...

hongquan commented 5 years ago

schedule looks OK.

alok760 commented 4 years ago

What about https://github.com/dbader/schedule/ which is also on pypi, very lightweight...

looks promising. I'll start working on this

hongquan commented 4 years ago

Please note that, because schedule works alone (without a message queue like Redis), it can only do one task at once and will miss any command you send to it, when it is busy.

In the case of other solutions (RQ, Celery), your command is put to a queue in Redis/RabbitMQ, and the worker can still get the command later, after it finishes its job.

norbusan commented 4 years ago

@hongquan @alok760 that is a good point, though it shouldn't be busy too long, and only kick of an action in the main loop, but not waiting for completion. That way this window is really small, and other smart speakers will have similar issues.

Still, it is good to keep in mind, thanks!!