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:
@@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
60
MQTT.hpp
60
MQTT.hpp
@@ -1,12 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
const IPAddress MQTT_HOST(10, 98, 20, 10);
|
const IPAddress MQTT_HOST(10,98,20,10);
|
||||||
const int MQTT_PORT = 1883;
|
const int MQTT_PORT = 1883;
|
||||||
|
|
||||||
AsyncMqttClient mqttClient;
|
AsyncMqttClient mqttClient;
|
||||||
|
|
||||||
String GetPayloadContent(char* data, size_t len)
|
String GetPayloadContent(char* data, size_t len) {
|
||||||
{
|
|
||||||
String content = "";
|
String content = "";
|
||||||
for(size_t i = 0; i < len; i++)
|
for(size_t i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
@@ -15,28 +14,51 @@ String GetPayloadContent(char* data, size_t len)
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SuscribeMqtt()
|
void SuscribeMqtt() {
|
||||||
{
|
|
||||||
uint16_t packetIdSub = mqttClient.subscribe("user123456/channel", 0);
|
String topicPlayback = String("vesper/") + DEV_ID + "/control/playback";
|
||||||
Serial.print("Subscribing at QoS 2, packetId: ");
|
String topicAddMelody = String("vesper/") + DEV_ID + "/control/add_melody";
|
||||||
Serial.println(packetIdSub);
|
|
||||||
|
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);
|
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)
|
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);
|
String topicPlayback = String("vesper/") + DEV_ID + "/control/playback";
|
||||||
reconstr(content);
|
String topicAddMelody = String("vesper/") + DEV_ID + "/control/add_melody"; // doesn't work yet.
|
||||||
//Serial.print(content);
|
|
||||||
//Serial.println();
|
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
BIN
data/data.bin
Normal file
Binary file not shown.
BIN
data/melody1.bin
Normal file
BIN
data/melody1.bin
Normal file
Binary file not shown.
1
data/melody1.txt
Normal file
1
data/melody1.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[0000000000000001,0000000000000000,0000000000000010,0000000000000000,0000000000000001,0100000000010010,0000000000000001,0000000000001010,0000000000000000,0000000000000001]
|
||||||
71
functions.hpp
Normal file
71
functions.hpp
Normal 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
1
melody_handling.hpp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
// MELODY PLAYBACK WILL BE HANDLED HERE
|
||||||
40
vesper.ino
40
vesper.ino
@@ -1,31 +1,55 @@
|
|||||||
#
|
|
||||||
|
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <AsyncMqttClient.h>
|
#include <AsyncMqttClient.h>
|
||||||
#include <ArduinoJson.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 "config.h" // Sustituir con datos de vuestra red
|
||||||
#include "JSON_functions.hpp"
|
|
||||||
#include "MQTT.hpp"
|
#include "MQTT.hpp"
|
||||||
#include "ESP32_Utils.hpp"
|
#include "ESP32_Utils.hpp"
|
||||||
#include "ESP32_Utils_MQTT_Async.hpp"
|
#include "ESP32_Utils_MQTT_Async.hpp"
|
||||||
|
#include "melody_handling.hpp"
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
|
// Initialize Serial Communication (for debuggin)
|
||||||
Serial.begin(115200);
|
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);
|
WiFi.onEvent(WiFiEvent);
|
||||||
InitMqtt();
|
InitMqtt();
|
||||||
|
|
||||||
ConnectWiFi_STA();
|
ConnectWiFi_STA();
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
// EXAMPLE PUBLISH. CHANGE THIS, IF NEEDED.
|
|
||||||
//delay(1000);
|
|
||||||
//PublishMqtt(millis());
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user