Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Shared/Sensors/BaseSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <SensorManager.h>
#include "LoggingSupport.h"
#include "JsonVisitor.h"

enum class SensorType : uint8_t
{
Expand All @@ -17,4 +18,6 @@ class BaseSensor : public BaseSensorHandler, public JsonVisitor
virtual SensorType getSensorType() const = 0;

virtual const char* getSensorCommandId() const = 0;

virtual const char* getSensorName() const = 0;
};
5 changes: 5 additions & 0 deletions Shared/Sensors/Dht11SensorHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,9 @@ class Dht11SensorHandler : public BaseSensor, public BroadcastLoggerSupport
{
return SensorTemperature;
}

const char* getSensorName() const override
{
return "dht11";
}
};
7 changes: 6 additions & 1 deletion Shared/Sensors/WaterSensorHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class WaterSensorHandler : public BaseSensor, public BroadcastLoggerSupport

void formatStatusJson(char* buffer, size_t size) override
{
snprintf(buffer, size, "\"waterLevel\":%d,\"average\":%d",
snprintf(buffer, size, "\"level\":%d,\"average\":%d",
_latestWaterLevel, _waterPumpQueue.average());
}

Expand All @@ -101,4 +101,9 @@ class WaterSensorHandler : public BaseSensor, public BroadcastLoggerSupport
{
return SensorWaterLevel;
}

const char* getSensorName() const override
{
return "waterLevel";
}
};
4 changes: 4 additions & 0 deletions Shared/SystemDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

constexpr uint8_t DefaultValue = 0xFF;

constexpr uint8_t BufferSuccess = 0x00;
constexpr uint8_t BufferInvalid = 0x01;
constexpr uint8_t BufferOverflow = 0x02;

constexpr char SystemHeartbeatCommand[] = "F0";
constexpr char SystemInitialized[] = "F1";
constexpr char SystemFreeMemory[] = "F2";
Expand Down
28 changes: 22 additions & 6 deletions SmartFuseBox/INetworkCommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include <SerialCommandManager.h>
#include <Arduino.h>
#include "SystemDefinitions.h"
#include "JsonVisitor.h"
#include "NetworkJsonVisitor.h"



Expand All @@ -11,7 +11,7 @@
*
* Handlers implement this to expose REST-style endpoints for HTTP/WebSocket access.
*/
class INetworkCommandHandler : public JsonVisitor
class INetworkCommandHandler : public NetworkJsonVisitor
{
public:
/**
Expand Down Expand Up @@ -39,17 +39,33 @@ class INetworkCommandHandler : public JsonVisitor

virtual ~INetworkCommandHandler() = default;

void formatJsonResponse(char* buffer, size_t size, bool success, const char* message = nullptr)
uint8_t formatJsonResponse(char* buffer, size_t size, bool success, const char* message = nullptr)
{
if (!buffer || size == 0)
{
return BufferInvalid;
}

int written;
if (message)
{
snprintf(buffer, size, "{\"success\":%s,\"message\":\"%s\"}",
written = snprintf(buffer, size, "\"success\":%s,\"message\":\"%s\"",
success ? "true" : "false", message);
}
else
{
snprintf(buffer, size, "{\"success\":%s}", success ? "true" : "false");
written = snprintf(buffer, size, "\"success\":%s", success ? "true" : "false");
}

// Check if buffer was too small
if (written < 0 || written >= static_cast<int>(size))
{
// Buffer overflow occurred - truncate gracefully
buffer[size - 1] = '\0'; // Ensure null termination

return BufferOverflow;
}
}

return BufferSuccess;
}
};
10 changes: 10 additions & 0 deletions SmartFuseBox/NetworkJsonVisitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <WiFiClient.h>

class NetworkJsonVisitor
{
public:
virtual void formatWifiStatusJson(WiFiClient* client) = 0;
virtual ~NetworkJsonVisitor() = default;
};
9 changes: 9 additions & 0 deletions SmartFuseBox/RelayNetworkHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,12 @@ void RelayNetworkHandler::formatStatusJson(char* buffer, size_t size)

snprintf(buffer + written, size - written, "]");
}

void RelayNetworkHandler::formatWifiStatusJson(WiFiClient* client)
{
char buffer[MaximumJsonResponseBufferSize];
buffer[0] = '\0';

formatStatusJson(buffer, sizeof(buffer));
client->print(buffer);
}
4 changes: 3 additions & 1 deletion SmartFuseBox/RelayNetworkHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class RelayNetworkHandler : public INetworkCommandHandler

const char* getRoute() const override { return "/api/relay"; }

void formatStatusJson(char* buffer, size_t size) override;
void formatWifiStatusJson(WiFiClient* client) override;

void formatStatusJson(char* buffer, size_t size);

CommandResult handleRequest(const String& method,
const String& command,
Expand Down
95 changes: 70 additions & 25 deletions SmartFuseBox/SensorNetworkHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


#include "SensorNetworkHandler.h"
#include "SystemDefinitions.h"

Expand Down Expand Up @@ -31,29 +29,76 @@ CommandResult SensorNetworkHandler::handleRequest(const String& method,

void SensorNetworkHandler::formatStatusJson(char* buffer, size_t size)
{
int written = snprintf(buffer, size, "\"sensor\":[");

for (uint8_t i = 0; i < _sensorController->sensorCount(); i++)
{
BaseSensor* sensor = _sensorController->sensorGet(i);

if (sensor == nullptr)
continue;

char sensorBuffer[MaximumJsonResponseBufferSize];
sensorBuffer[0] = '\0';

sensor->formatStatusJson(sensorBuffer, sizeof(sensorBuffer));

// Add comma separator if not the first element
if (i > 0 && written < (int)size)
{
written += snprintf(buffer + written, size - written, ",");
}
if (!buffer || size == 0)
{
return;
}

int written = snprintf(buffer, size, "\"sensors\":{");
if (written < 0 || written >= static_cast<int>(size))
{
buffer[size - 1] = '\0';
return; // Buffer too small for even the opening
}

bool firstSensor = true;
for (uint8_t i = 0; i < _sensorController->sensorCount(); i++)
{
BaseSensor* sensor = _sensorController->sensorGet(i);

if (sensor == nullptr)
continue;

char sensorBuffer[MaximumJsonResponseBufferSize];
sensorBuffer[0] = '\0';

sensor->formatStatusJson(sensorBuffer, sizeof(sensorBuffer));

if (sensorBuffer[0] == '\0')
continue;

// Add comma separator if not the first element
if (!firstSensor)
{
int n = snprintf(buffer + written, size - written, ",");
if (n < 0 || written + n >= static_cast<int>(size))
{
buffer[size - 1] = '\0';
return; // Out of space
}
written += n;
}

// Write sensor entry (removed duplicate and fixed format)
int n = snprintf(buffer + written, size - written,
"\"%s\":{\"id\":%d,\"type\":%d,%s}",
sensor->getSensorName(),
static_cast<uint8_t>(sensor->getSensorId()),
static_cast<uint8_t>(sensor->getSensorType()),
sensorBuffer);

if (n < 0 || written + n >= static_cast<int>(size))
{
buffer[size - 1] = '\0';
return; // Out of space
}
written += n;
firstSensor = false;
}

// Close JSON object
int n = snprintf(buffer + written, size - written, "}");
if (n < 0 || written + n >= static_cast<int>(size))
{
buffer[size - 1] = '\0';
}
}

written += snprintf(buffer + written, size - written,
"%s", sensorBuffer);
}
void SensorNetworkHandler::formatWifiStatusJson(WiFiClient* client)
{
char buffer[MaximumJsonResponseBufferSize];
buffer[0] = '\0';

snprintf(buffer + written, size - written, "]");
formatStatusJson(buffer, sizeof(buffer));
client->print(buffer);
}
4 changes: 3 additions & 1 deletion SmartFuseBox/SensorNetworkHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class SensorNetworkHandler : public INetworkCommandHandler

const char* getRoute() const override { return "/api/sensor"; }

void formatStatusJson(char* buffer, size_t size) override;
void formatWifiStatusJson(WiFiClient* client) override;

void formatStatusJson(char* buffer, size_t size);

CommandResult handleRequest(const String& method,
const String& command,
Expand Down
4 changes: 1 addition & 3 deletions SmartFuseBox/SmartFuseBox.ino
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,12 @@ void configureWifiSupport(Config* config)


// json status visitors for wifi
JsonVisitor* jsonVisitors[] = {
NetworkJsonVisitor* jsonVisitors[] = {
&relayNetworkHandler,
&soundNetworkHandler,
&warningNetworkHandler,
&systemNetworkHandler,
&sensorNetworkHandler,
&waterSensorHandler,
&dht11SensorHandler
};
uint8_t jsonVisitorCount = sizeof(jsonVisitors) / sizeof(jsonVisitors[0]);
wifiController.registerJsonVisitors(jsonVisitors, jsonVisitorCount);
Expand Down
1 change: 1 addition & 0 deletions SmartFuseBox/SmartFuseBox.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
<DeploymentContent>true</DeploymentContent>
</ClCompile>
<ClInclude Include="BaseSensor.h" />
<ClInclude Include="NetworkJsonVisitor.h" />
<ClInclude Include="SystemDefinitions.h" />
<ClInclude Include="DateTimeManager.h" />
<ClInclude Include="INetworkCommandHandler.h" />
Expand Down
25 changes: 20 additions & 5 deletions SmartFuseBox/SmartFuseBox.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@
<ClCompile Include="ConfigManager.cpp">
<Filter>Source Files\SharedCode</Filter>
</ClCompile>
<ClCompile Include="SensorController.h">
<Filter>Header Files</Filter>
</ClCompile>
<ClCompile Include="SensorNetworkHandler.cpp">
<Filter>Source Files\NetworkCommandHandlers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="__vm\.SmartFuseBox.vsarduino.h">
Expand Down Expand Up @@ -168,9 +174,6 @@
<ClInclude Include="SharedBaseCommandHandler.h">
<Filter>Header Files\SharedCode\SerialCommandHandlers</Filter>
</ClInclude>
<ClInclude Include="SharedConstants.h">
<Filter>Header Files\SharedCode</Filter>
</ClInclude>
<ClInclude Include="WarningType.h">
<Filter>Header Files\SharedCode</Filter>
</ClInclude>
Expand Down Expand Up @@ -249,11 +252,23 @@
<ClInclude Include="DateTimeManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SystemNetworkHandler.h">
<ClInclude Include="JsonVisitor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="JsonVisitor.h">
<ClInclude Include="BaseSensor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SystemDefinitions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SensorNetworkHandler.h">
<Filter>Header Files\NetworkCommandHandlers</Filter>
</ClInclude>
<ClInclude Include="NetworkJsonVisitor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SystemNetworkHandler.h">
<Filter>Header Files\NetworkCommandHandlers</Filter>
</ClInclude>
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions SmartFuseBox/SoundNetworkHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,12 @@ void SoundNetworkHandler::formatStatusJson(char* buffer, size_t size)
snprintf(buffer, size, "\"sound\":{\"active\": %d,\"type\": %d}",
_soundController->isPlaying(), static_cast<int>(_soundController->getCurrentSoundType()));
}

void SoundNetworkHandler::formatWifiStatusJson(WiFiClient* client)
{
char buffer[MaximumJsonResponseBufferSize];
buffer[0] = '\0';

formatStatusJson(buffer, sizeof(buffer));
client->print(buffer);
}
4 changes: 3 additions & 1 deletion SmartFuseBox/SoundNetworkHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class SoundNetworkHandler : public INetworkCommandHandler

const char* getRoute() const override { return "/api/sound"; }

void formatStatusJson(char* buffer, size_t size) override;
void formatWifiStatusJson(WiFiClient* client) override;

void formatStatusJson(char* buffer, size_t size);

CommandResult handleRequest(const String& method,
const String& cmd,
Expand Down
9 changes: 9 additions & 0 deletions SmartFuseBox/SystemNetworkHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,12 @@ void SystemNetworkHandler::formatStatusJson(char* buffer, size_t size)
rssi,
DateTimeManager::formatDateTime().c_str());
}

void SystemNetworkHandler::formatWifiStatusJson(WiFiClient* client)
{
char buffer[MaximumJsonResponseBufferSize];
buffer[0] = '\0';

formatStatusJson(buffer, sizeof(buffer));
client->print(buffer);
}
4 changes: 3 additions & 1 deletion SmartFuseBox/SystemNetworkHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class SystemNetworkHandler : public INetworkCommandHandler

const char* getRoute() const override { return "/api/system"; }

void formatStatusJson(char* buffer, size_t size) override;
void formatWifiStatusJson(WiFiClient* client) override;

void formatStatusJson(char* buffer, size_t size);

CommandResult handleRequest(const String& method,
const String& cmd,
Expand Down
Loading