Myriota Flex SDK 2.6.0
Loading...
Searching...
No Matches
Schedule Message Example

This example demonstrates how to safely schedule custom messages for satellite transmission and actively monitor the status of the internal message queue.

How it Works

  • Periodic Scheduling: The SendMessage job automatically runs to schedule a defined number of messages per day (configured via MESSAGES_PER_DAY).
  • Custom Payload: It constructs a packed message struct containing a sequence number and a timestamp. You can easily expand this struct to include your own application's sensor data.
  • Safe Queuing (Capacity Checks): Before attempting to schedule a message, the application checks FLEX_MessageSlotsFree() and FLEX_MessageBytesFree(). If the queue is full, it gracefully skips the current schedule to prevent overwriting older, unsent messages.
  • Message ID: The FLEX_MessageSchedule function pushes the payload to the queue. If successful, it returns the newly created message's unique ID (>= 0). A negative return value indicates a failure to schedule.
  • Queue Monitoring: After every scheduling attempt, the application prints a formatted table displaying the overall queue capacity and the exact FLEX_MessageTransmitStatus of every message currently in the system (e.g., PENDING, ONGOING, COMPLETE, or EXPIRED).

Satellite Transmission

Messages are held in the queue and will be transmitted automatically when a satellite is overhead. You can check satellite access times for your location using the Device Manager

#include <stdio.h>
#include "flex.h"
#define APPLICATION_NAME "Schedule Message Example"
// Note: Modify this according to the application requirements.
#define MESSAGES_PER_DAY 4
typedef struct {
uint16_t sequence_number;
uint32_t time;
// ADD YOUR PARAMETERS HERE
} __attribute__((packed)) message;
static const char* StatusString(const FLEX_MessageTransmitStatus status) {
switch (status) {
return "PENDING";
return "ONGOING";
return "COMPLETE";
return "EXPIRED";
}
return "UNKNOWN";
}
static void PrintMessageQueueInfo(void) {
const int queue_size = FLEX_MessageSlotsMax();
FLEX_MessageStatus message_status[queue_size];
const int messages = FLEX_MessageQueueStatus(message_status, queue_size);
printf("\n==== Message Queue Info ====\n");
printf("Slots Free: %d / %d\n", FLEX_MessageSlotsFree(), queue_size);
printf("Bytes Free: %d\n\n", (int)FLEX_MessageBytesFree());
if (messages < 0) {
printf("Error: Failed to retrieve queue status (%d)\n\n", messages);
return;
}
if (messages == 0) {
printf("Message queue is empty!\n\n");
return;
}
printf(" %-10s | %-15s \n", "Message ID", "Transmit Status");
printf("-----------------------------\n");
for (int i = 0; i < messages; i++) {
printf(" %-10u | %-15s \n", message_status[i].id, StatusString(message_status[i].status));
}
printf("=============================\n\n");
}
static time_t SendMessage(void) {
static uint16_t sequence_number = 0;
message message;
message.sequence_number = sequence_number++;
message.time = FLEX_TimeGet();
// POPULATE YOUR DATA HERE
if (FLEX_MessageSlotsFree() == 0) {
printf("WARNING: no free message slots available! skipping message\n");
goto next_schedule;
}
if (FLEX_MessageBytesFree() < sizeof(message)) {
printf("WARNING: not enough free bytes for a %d-byte message! skipping message\n",
sizeof(message));
goto next_schedule;
}
// Schedule messages for satellite transmission
const int message_id = FLEX_MessageSchedule((void*)&message, sizeof(message));
if (message_id < 0) {
printf("ERROR: Failed to schedule message\n");
} else {
printf("Scheduled message (ID %d) : %u %lu\n", message_id, message.sequence_number,
message.time);
}
next_schedule:
PrintMessageQueueInfo();
return (FLEX_TimeGet() + 24 * 3600 / MESSAGES_PER_DAY);
}
void FLEX_AppInit() {
printf("%s\n", APPLICATION_NAME);
FLEX_JobSchedule(SendMessage, FLEX_ASAP());
}