Added Melody Struct & Ajusted MQTT Subs and Deserialization

A new Melody Struct was added containing the melody's main attributes.
The MQTT Topic Subscriptions were updated to a more proper format.
Also added DEV_ID that corresponds to the device's ID or Serial Number.
Chnaged the Deserialization function to actually adjust the MelodyStruct's attributes.
Added basic play/stop functionality.
This commit is contained in:
2025-01-12 19:46:24 +02:00
parent 30e708f048
commit 540d8a14fe
9 changed files with 149 additions and 56 deletions

View File

@@ -1,26 +0,0 @@
#pragma once
void reconstr (String payload) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("deserializeJson() failed: ");
Serial.println(error.c_str());
return;
}
// EXAMPLE PAYLOAD. CHANGE THIS TO THE APPROPRIATE ONE.
int a = doc["a"];
bool b = doc["b"];
float c = doc["c"];
Serial.println("The payload received contains: ");
Serial.print("a: ");
Serial.print(a);
Serial.print(" b: ");
Serial.print(b);
Serial.print(" c: ");
Serial.println(c);
}

View File

@@ -5,8 +5,7 @@ const int MQTT_PORT = 1883;
AsyncMqttClient mqttClient;
String GetPayloadContent(char* data, size_t len)
{
String GetPayloadContent(char* data, size_t len) {
String content = "";
for(size_t i = 0; i < len; i++)
{
@@ -15,28 +14,51 @@ String GetPayloadContent(char* data, size_t len)
return content;
}
void SuscribeMqtt()
{
uint16_t packetIdSub = mqttClient.subscribe("user123456/channel", 0);
Serial.print("Subscribing at QoS 2, packetId: ");
Serial.println(packetIdSub);
void SuscribeMqtt() {
String topicPlayback = String("vesper/") + DEV_ID + "/control/playback";
String topicAddMelody = String("vesper/") + DEV_ID + "/control/add_melody";
uint16_t control_id = mqttClient.subscribe(topicPlayback.c_str(), 2);
Serial.print("Subscribing to playback topic, QoS 2, packetId: ");
Serial.println(control_id);
// doesn't work yet:
uint16_t add_melody_id = mqttClient.subscribe(topicAddMelody.c_str(), 2);
Serial.print("Subscribing to add_melody topic, QoS 2, packetId: ");
Serial.println(add_melody_id);
}
String payload;
void PublishMqtt(unsigned long data)
{
void PublishMqtt(unsigned long data) {
String topicData = String("vesper/") + DEV_ID + "/data";
String payload = String(data);
mqttClient.publish("hello/world", 0, true, (char*)payload.c_str());
mqttClient.publish(topicData.c_str(), 0, true, (char*)payload.c_str());
}
void OnMqttReceived(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
{
//Serial.print("Received on ");
//Serial.print(topic);
//Serial.print(": ");
String content = GetPayloadContent(payload, len);
reconstr(content);
//Serial.print(content);
//Serial.println();
String topicPlayback = String("vesper/") + DEV_ID + "/control/playback";
String topicAddMelody = String("vesper/") + DEV_ID + "/control/add_melody"; // doesn't work yet.
String payloadContent = String(payload).substring(0, len);
if (String(topic) == topicPlayback) {
// Handle the playback command
handleJSON(payload);
}
else if (String(topic) == topicAddMelody) {
// Handle adding melody
Serial.println("Adding melody...");
// You can call a function here to handle adding the melody
}
else {
// Handle unknown topics
Serial.println("Unknown topic received.");
}
}

BIN
data/data.bin Normal file

Binary file not shown.

BIN
data/melody1.bin Normal file

Binary file not shown.

1
data/melody1.txt Normal file
View File

@@ -0,0 +1 @@
[0000000000000001,0000000000000000,0000000000000010,0000000000000000,0000000000000001,0100000000010010,0000000000000001,0000000000001010,0000000000000000,0000000000000001]

71
functions.hpp Normal file
View File

@@ -0,0 +1,71 @@
#pragma once
extern volatile bool playing;
void playback(JsonDocument doc){
if (doc["playback"].as<bool>()){
playing = true;
Serial.println("START Playback!");
}
else if (doc["playback"].as<bool>()){
playing = false;
Serial.println("STOP Playback!");
}
}
void selectMelody(JsonDocument doc){
melody.name = doc["name"].as<const char*>(); // Convert to std::string
melody.id = doc["id"].as<uint16_t>();
melody.duration = doc["duration"].as<uint32_t>();
melody.infinite_play = doc["infinite"].as<bool>();
melody.interval_duration = doc["inter_dur"].as<uint16_t>();
melody.speed = doc["speed"].as<uint8_t>();
Serial.printf("Name: %s, ID: %d, Duration: %lu, Inf: %s, Inter: %d, Speed: %d\n",
melody.name.c_str(),
melody.id,
melody.duration,
melody.infinite_play ? "true" : "false",
melody.interval_duration,
melody.speed);
}
void handleJSON(String payload) {
JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("deserializeJson() failed: ");
Serial.println(error.c_str());
return;
}
selectMelody(doc);
playback(doc);
}
/*
possible topics:
vesper/client-id/control
/play
/stop
vesper/client-id/select_melody
vesper/client-id/update_melody
vesper/client-id/add_melody
*/

1
melody_handling.hpp Normal file
View File

@@ -0,0 +1 @@
// MELODY PLAYBACK WILL BE HANDLED HERE

View File

@@ -1,31 +1,55 @@
#
#include <WiFi.h>
#include <AsyncMqttClient.h>
#include <ArduinoJson.h>
#include <FS.h>
#include <SPIFFS.h>
#include <string>
#define DEV_ID "id-96638646"
struct melody_attributes {
std::string name; // Contains the name of each Melody saved
uint16_t id; // The (internal) ID of the selected melody
uint32_t duration; // Indicates the total Duration in Minutes
bool infinite_play; // Infinite Loop Indicator (If True the melody will loop forever or until stoped, with pauses of "interval duration in between loops")
uint16_t interval_duration; // Indicates the Duration of the Interval between finished loops, IF "inf" is true
uint8_t speed; // Indicates the Speed in 9 Steps. 1-9 (Steps can be adjusted in the bellEngine function)
};
melody_attributes melody;
volatile bool playing = false;
#include "functions.hpp"
#include "config.h" // Sustituir con datos de vuestra red
#include "JSON_functions.hpp"
#include "MQTT.hpp"
#include "ESP32_Utils.hpp"
#include "ESP32_Utils_MQTT_Async.hpp"
#include "melody_handling.hpp"
void setup()
{
// Initialize Serial Communication (for debuggin)
Serial.begin(115200);
delay(50);
delay(500);
// Initialize SPIFFS
if (!SPIFFS.begin(true)) { // 'true' means format SPIFFS if initialization fails
Serial.println("Failed to mount SPIFFS");
return;
}
Serial.println("SPIFFS mounted successfully");
delay(50);
// Initialize WiFi and MQTT
WiFi.onEvent(WiFiEvent);
InitMqtt();
ConnectWiFi_STA();
delay(1000);
}
void loop()
{
// EXAMPLE PUBLISH. CHANGE THIS, IF NEEDED.
//delay(1000);
//PublishMqtt(millis());
}