Send MQTT Messages at specific time

0

Hello, I have a smart home system with a smartphone app and actors that communicates via MQTT. I want to be able to set in the app that an actor turns on for a certain time. For example, I want to be able to set the actor to turn on for the next 10 minutes, but also to turn on every day at 10 o'clock for 5 minutes.

My first idea was to use lambda functions, which then send the switch-off command after a delay. But this did not work.

How can I implement something like this with AWS?

Timon
asked a year ago577 views
2 Answers
1

One option might be to use EventBridge scheduler to create different schedules. On each schedule you will send the appropriate message using a Lambda function or calling the IoT SDK directly from the scheduler.

profile pictureAWS
EXPERT
Uri
answered a year ago
  • Hi,

    thanks for youre answer. But how can I set the EventBridge from a lambda function? At the moment, I only see that I can create a static schedule that will fire my lambda function. But I want the App User to define its own schedule.

  • Just use the EventBridge SDK from within the Lambda function. Depending on your language, we have different SDKs. For example, if you use Python, you need to use boto3, and specifically, the create_schedule API call.

1

Hi @Timon,

This is an interesting design challenge. There are probably multiple ways to use AWS services in combination to meet this need. I will share some thoughts in case they are helpful.

First, you could implement the scheduling on the device or in the cloud:

If on the device, it would work even when the device does not have a network connection. Also, the timing could probably be more precise (for example, if you need < 1 second precision). And if you have very large scale and devices that all act at the same time you may avoid some scalability challenges (ex: 5M devices all doing something at exactly the same time). You could implement this such that the app and cloud manage the device's activity schedule, but the net result is always synchronized to the device, where the device uses the equivalent of a local cron to take actions at specific times. Upon network re-connect, the device should always request its latest scheduled activity list from the cloud. The feasibility of this depends on your device hardware and software - even highly embedded systems have timers but if you're working with an 8-bit microcontroller unit then perhaps it is not feasible. The app/cloud would just manage the device schedule similar to any stored device settings, perhaps in Amazon DynamoDB, and probably use the device's shadow to store the net activity schedule and sync it to the device.

If in the cloud, then as @Uri suggests Amazon EventBridge seems attractive. The net effect of the app/cloud managing the device's activity schedule would be input to the EventBridge Scheduler. An EventBridge scheduled task could trigger a Lambda, which then posts a message to an appropriate MQTT topic for the device. Anytime a device activity schedule is changed, the net effect needs to be updated in the EventBridge Scheduler using the EventBridge API. The act of updating the EventBridge Scheduler could be implemented in Lambdas resulting from device activity schedule changes, and a different Lambda would react to the EventBridge task to propagate the event to an MQTT topic.

An alternative cloud implementation may use a software package (perhaps similar to cron) to trigger the events as scheduled. But then you get into running containers or EC2 instances, auto-scaling them, patching them, etc. This is why I think a use of Amazon EventBridge is attractive to pursue.

I will also note that if you have so many device events that they are triggering very frequently (ex: every second, every few seconds, or at least many times per minute) you may find a polling design is a better fit. In its simplest form, run a Lambda every X seconds (depending on the precision required, such as every 5 seconds) and have it query for the events that are 'due'. In its simplest form, query a database like Amazon DynamoDB or an RDS. Choose event storage and indexing to optimize for this frequent activity. The triggered Lambda runs all the events 'due' within its frequency. Since it only needs the nearest-term events, it would not have to query the entire database of scheduled activities if the act of editing the device schedules always updated the next events somewhere easy to find (a smaller dedicated table, or similar).

Lastly, a combination of the above is possible. Instead of polling, you do use an event scheduling service such as Amazon EventBridge. However, you do not necessarily have to configure all future events into EventBridge - technically you only need the one next event time configured. When the Lambda triggers, it takes the necessary action(s) for the 'due' event(s) (i.e., propagates them to the necessary device MQTT topics). But then before exiting, it queries for the next soonest event (or set of events that are scheduled at exactly the same time) and sets the next EventBridge scheduled event for that time. Then when the Lambda subsequently triggers, it repeats the exercise. You do also need to update the one "next Lambda trigger" event in EventBridge if any device schedule changes such that the soonest event time changes. This option might be attractive if the frequency of events is common/continuous but not enough to justify polling overhead.

Hopefully some of this information helps you design your product's user-scheduled-device-activities feature. I think you will find some combination of Amazon EventBridge, AWS Lambda, and glue services (ex: Amazon SNS, Amazon SQS) to fit your needs.

Regards,

Ryan

profile pictureAWS
Ryan_M
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions