Often you want to leave to flespi all the hard work for real-time processing and detecting intervals from device messages - e.g. trips, parkings, fuel fillings or drains, stops, engine hours, geofence visits, etc. - and receive the event notification by calling a webhook to invoke your lambda only when such an event has ended.
This is easy to implement with flespi using a combination of calculator and webhook. In the sample below we will configure the solution to detect trips and notify your lambda only when the trip has been finished to perform some additional processing of this event calculation on your side.
- Create a calculator and assign to devices
- Create webhook and subscribe it to calculator events
- Alternatives to webhook
- What’s next
Create a calculator and assign to devices
Our calculator configuration is very straightforward. We will count a trip by a vehicle instant speed condition for at least 1 minute and allow stops inside a trip up to 2 minutes.
This is configured by the selector of type=”expression” with expression=”position.speed>0”, max_inactive=”120”, min_duration=”60” plus few extra tuning parameters:
max_inactive with 2 minutes configured is an important option as it will control the minimum delay from the moment the trip has stopped until we receive a notification about this.
You can define a lot of counters to calculate additional information within interval but the most important one to catch finished trips is type=“active” which will add into interval JSON its active state as a boolean:
Active interval state means the interval is still ON e.g. trip is not yet finished.
Now assign some devices to the calculator and check calculator logs if we have some trips detected. This is done via LOGS & MESSAGES calculator’s tab:
Here you see logs from the calculator that it initially splitted all device messages onto trip intervals and automatically updates the last active interval upon new messages received from the device. All these calculator’s events that you see in logs can be handled via MQTT and of course webhooks.
To check the contents of each interval JSON you can navigate to the intervals view for a specific device. This is done via DEVICES tab by clicking on a round cube icon on the device card:
There we have a special combined view of intervals and device messages. By clicking on the corresponding interval in the upper pane the lower pane will show and highlight devices messages associated with it. And in the right pane you can see JSON representation of the currently selected interval or message. Interval JSON is exactly what you will receive in your lambda:
You see that the most recent interval has an active=true parameter which means it is still ongoing. While all other intervals have active=false which we will utilize to catch only finished intervals.
Create webhook and subscribe it to calculator events
Before creating a webhook you have to select the correct MQTT topic of events that will be delivered to your lambda. To handle only finished intervals from calculator we will catch topic flespi/interval/gw/calcs/{calc-id}/devices/+/created,updated with payload filter ”active == false”:
Webhooks templating system allows you to use full featured expressions inside %% characters to access the message that triggered webhook and format URL, headers and BODY of request. To utilize this templating feature we suggest specifying your lambda server URL with ?topic=%topic% in query parameters and %payload% in the webhook body:
%payload% will resolve in a JSON representation of interval while %topic% will help you to understand from which device and calculator this event originated.
Now you can just open two logs windows - from the calculator and webhook in parallel and wait until the calculator will detect the end of the trip. Remember that we catch all interval JSON updates from the calculator but will trigger webhook to a lambda only when receiving an event with active=false parameter:
Here we tried webhook to a lambda, but the lambda server responded with 400 Bad Request so the system skipped further delivery attempts of this event. You use logs to check what was sent to a lambda inside HTTP request or to investigate the payload and topic of the MQTT message that triggered this webhook event:
Logs are valuable information when something is going out of plan. In webhook logs you can see everything related to this event or its delivery to your lambda and debug the issue.
Alternative and even more beautiful solution could be to use fixed URI and provide all the variable information in the Body section of webhook:
We used next expression for request body:
{"payload": %payload%, "device_id": %tonumber(topics[6])%, "reason": %tonumber(user_properties["reason_code"])%}
It will result in delivery to our lambda the reason of interval event, related device id and of course the interval JSON:
To change JSON representation of intervals that is sent to your lambda you usually add additional counters to count mileage, average speed, number and locations of all long stops, various eco-driving events and so on. You may explore different counters in the analytics basic overview.
If your lambda server will not be available or respond with 5xx HTTP code during the event delivery, the webhook will repeat it after a certain pause.
Alternatives to webhook
Main part in this article is calculator configuration because it is responsible for extracting intervals from device messages in the background. Webhook here is easy to use but not the only method for you to receive such interval events. You can also receive such events with:
- Direct subscriptions with MQTT client
- By using an extra chain of channel + stream to push these events into IoT clouds such as AWS IoT Core, Azure IoT Hub or Google Cloud
Direct subscriptions with MQTT will require you to filter incoming messages by payload. This is achieved with additional $filter/payload=xxxx/ specification prepended to a subscription topic where xxxx is urlencoded active==false filter to pass only intervals that have active with false value in their JSON payload. The final subscription topic in our case will be:
$filter/payload=active%3D%3Dfalse/flespi/interval/gw/calcs/1680656/devices/+/updated,created
Here you can see how standard subscription and filtered react when subscribed to both topics with MQTT Board:
Do not forget to put any number into the subscription identifier within its properties in order for MQTT Board to operate with non-standard subscriptions.
Same MQTT topic you may use when streaming intervals using channels with MQTT protocol in order to forward them into other systems.
What’s next
The best way to explore flespi capabilities with calculators and webhooks is to watch detailed videos from our conference:
As well as with event delivery options you are not limited with event reasons just to finished intervals. You can trigger a notification to your lambda for a big set of events - daily or monthly device mileage is calculated, a harsh breaking event occurred, when a channel has some parsing error, somebody logs into the flespi panel, invoice from flespi is created/paid and so on.
Events from devices can be aggregated with analytics while non-aggregated device events together with a lot of events from other systems inside flespi are handled with corresponding MQTT topics.
And finally if you want to aggregate events rather then device telemetry messages:
Create a channel with MQTT protocol
Subscribe it to the topic that corresponding to events you want to aggregate
Define ident for aggregating device (you may use even fixed ident string)
Create device of type MQTT generic and accumulate events as its messages
Create calculators to aggregate events
- Subscribe to events from these calculators
And that is - you will have a fake device filled with messages created from events. And you can apply to this device everything what you have in flespi including calculators for data aggregation.