Skip to content

Commit

Permalink
[MQTT] Add option to publish output port information including curren…
Browse files Browse the repository at this point in the history
…t draw (#1827)

Add option to publish output port information (with current details) on a periodic bases via MQTT.

Closes #1661
  • Loading branch information
ghormann committed Mar 31, 2024
1 parent 36d02bc commit 40e657d
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 9 deletions.
40 changes: 40 additions & 0 deletions docs/MQTT.txt
Expand Up @@ -32,6 +32,7 @@ FPP will published the following sub_topics (using the full topic format) if MQT
*/playlist/media/artist - The artist listing in the audio / video file being played
*/playlist_details - If the MQTT Playlist Publish Frequency option (Advanced settings) is > 0 then a JSON file is published based on the duration (seconds) specified.
*/fppd_status - If the MQTT Status Publish Frequency option (Advanced settings) is > 0 then a JSON file is published based on the duration (seconds) specified.
*/port_status - If the MQTT Port Status Publish Frequency option (Advanced settings) is > 0 then a JSON file is published based on the duration (seconds) specified.

Message Example for fppd_status
---------------------------------------------
Expand Down Expand Up @@ -181,6 +182,45 @@ entries in a Playlist are allowed, only one will be displayed in real life.
]
}

Message Example for port_status
---------------------------------------------
When output sensors are present, this will report the status of each port and how many milliamps were
being pulled when the port was sampled.
[
{
"col": 1,
"enabled": true,
"ma": 435,
"name": "Port #1",
"row": 1,
"status": true
},
{
"col": 2,
"enabled": false,
"ma": 0,
"name": "Port #2",
"row": 1,
"status": true
},
{
"col": 3,
"enabled": false,
"ma": 0,
"name": "Port #3",
"row": 1,
"status": true
},
{
"col": 4,
"enabled": false,
"ma": 0,
"name": "Port #4",
"row": 1,
"status": true
}
]



FPP Subscribed subtopics
Expand Down
23 changes: 23 additions & 0 deletions src/Events.cpp
Expand Up @@ -23,6 +23,7 @@
#include <unistd.h>
#include <utility>

#include "OutputMonitor.h"
#include "Player.h"
#include "Warnings.h"
#include "common.h"
Expand Down Expand Up @@ -73,6 +74,22 @@ class PublishFPPDStatus : public EventNotifier {
}
};

class PublishPortStatus : public EventNotifier {
public:
PublishPortStatus(int freq) :
EventNotifier(freq) {}
~PublishPortStatus() {}

void notify() {
Json::Value json = Json::arrayValue;
OutputMonitor::INSTANCE.GetCurrentPortStatusJson(json);
std::stringstream buffer;
buffer << json << std::endl;
LogDebug(VB_CONTROL, "Notify FPPDStatus\n");
Events::Publish("port_status", buffer.str());
}
};

class EventWarningListener : public WarningListener {
public:
EventWarningListener() {}
Expand Down Expand Up @@ -108,6 +125,8 @@ void Events::Ready() {

int playlistFrequency = getSettingInt("MQTTFrequency");
int statusFrequency = getSettingInt("MQTTStatusFrequency");
int portFrequency = getSettingInt("MQTTPortStatusFrequency");

if (playlistFrequency > 0) {
eventNotifiers.push_back(new PublishPlaylistStatus(playlistFrequency));
}
Expand All @@ -116,6 +135,10 @@ void Events::Ready() {
eventNotifiers.push_back(new PublishFPPDStatus(statusFrequency));
}

if (portFrequency > 0) {
eventNotifiers.push_back(new PublishPortStatus(portFrequency));
}

if (EVENT_PUBLISH_THREAD == nullptr && eventNotifiers.size() > 0) {
EVENT_PUBLISH_THREAD = new std::thread();
// create background Publish Thread
Expand Down
20 changes: 13 additions & 7 deletions src/OutputMonitor.cpp
Expand Up @@ -201,7 +201,7 @@ class FPPEnablePortCommand : public Command {
static FPPEnablePortCommand INSTANCE;
FPPEnablePortCommand() :
Command("Set Port Status") {
args.push_back(CommandArg("Port", "string", "Port").setContentListUrl("api/fppd/ports/list"));
args.push_back(CommandArg("Port", "string", "Port").setContentListUrl("api/fppd/ports/list"));
args.push_back(CommandArg("on", "bool", "On"));
}
virtual std::unique_ptr<Command::Result> run(const std::vector<std::string>& args) override {
Expand Down Expand Up @@ -360,7 +360,7 @@ void OutputMonitor::DisableOutputs() {
CommandManager::INSTANCE.TriggerPreset("OUTPUTS_DISABLED");
}

void OutputMonitor::SetOutput(const std::string &port, bool on) {
void OutputMonitor::SetOutput(const std::string& port, bool on) {
std::unique_lock<std::mutex> lock(gpioLock);
for (auto p : portPins) {
if (p->name == port && p->enablePin) {
Expand All @@ -374,7 +374,6 @@ void OutputMonitor::SetOutput(const std::string &port, bool on) {
}
}


void OutputMonitor::AddPortConfiguration(const std::string& name, const Json::Value& pinConfig, bool enabled) {
PortPinInfo* pi = new PortPinInfo(name, pinConfig);
bool hasInfo = false;
Expand Down Expand Up @@ -589,6 +588,15 @@ int OutputMonitor::GetPixelCount(int port) {
return 0;
}

void OutputMonitor::GetCurrentPortStatusJson(Json::Value& result) {
if (!portPins.empty()) {
Sensors::INSTANCE.updateSensorSources();
for (auto a : portPins) {
a->appendTo(result);
}
}
}

HTTP_RESPONSE_CONST std::shared_ptr<httpserver::http_response> OutputMonitor::render_GET(const httpserver::http_request& req) {
int plen = req.get_path_pieces().size();
if (plen > 1 && req.get_path_pieces()[1] == "ports") {
Expand Down Expand Up @@ -617,10 +625,8 @@ HTTP_RESPONSE_CONST std::shared_ptr<httpserver::http_response> OutputMonitor::re
CommandManager::INSTANCE.run("Test Stop", args);
}
Sensors::INSTANCE.updateSensorSources();
Json::Value result;
for (auto a : portPins) {
a->appendTo(result);
}
Json::Value result = Json::arrayValue;
GetCurrentPortStatusJson(result);
std::string resultStr = SaveJsonToString(result);
return std::shared_ptr<httpserver::http_response>(new httpserver::string_response(resultStr, 200, "application/json"));
}
Expand Down
4 changes: 3 additions & 1 deletion src/OutputMonitor.h
Expand Up @@ -36,11 +36,13 @@ class OutputMonitor : public httpserver::http_resource {
void EnableOutputs();
void DisableOutputs();

void SetOutput(const std::string &port, bool on);
void SetOutput(const std::string& port, bool on);

void AutoEnableOutputs();
void AutoDisableOutputs();

void GetCurrentPortStatusJson(Json::Value& result);

virtual HTTP_RESPONSE_CONST std::shared_ptr<httpserver::http_response> render_GET(const httpserver::http_request& req) override;

int getGroupCount() const { return numGroups; }
Expand Down
15 changes: 14 additions & 1 deletion www/settings.json
Expand Up @@ -128,6 +128,7 @@
"MQTTPassword",
"MQTTCaFile",
"MQTTFrequency",
"MQTTPortStatusFrequency",
"MQTTStatusFrequency",
"MQTTSubscribe"
]
Expand Down Expand Up @@ -1560,6 +1561,18 @@
"max": 65535,
"step": 1
},
"MQTTPortStatusFrequency": {
"name": "MQTTPortStatusFrequency",
"description": "Publish Port Status Frequency",
"gatherStats": true,
"tip": "Optional frequency to publish Port Monitoring status Json to MQTT Broker. Zero indicates that the status will not be published",
"restart": 2,
"default": 0,
"type": "number",
"min": 0,
"max": 3600,
"step": 1
},
"MQTTPrefix": {
"name": "MQTTPrefix",
"description": "Topic Prefix",
Expand All @@ -1580,7 +1593,7 @@
},
"MQTTStatusFrequency": {
"name": "MQTTStatusFrequency",
"description": "Publish Status Frequency",
"description": "Publish FPPD Status Frequency",
"gatherStats": true,
"tip": "Optional frequency to publish FPP status Json to MQTT Broker. Zero indicates that the status will not be published",
"restart": 2,
Expand Down

0 comments on commit 40e657d

Please sign in to comment.