diff --git a/src/OutputMonitor.cpp b/src/OutputMonitor.cpp index a5b354015..2c75c3d32 100644 --- a/src/OutputMonitor.cpp +++ b/src/OutputMonitor.cpp @@ -40,6 +40,7 @@ OutputMonitor OutputMonitor::INSTANCE; class CurrentMonitorBase { public: + CurrentMonitorBase() {} CurrentMonitorBase(const Json::Value& c) { currentMonitorScale = c["scale"].asFloat(); if (c.isMember("offset")) { @@ -111,22 +112,46 @@ class SensorCurrentMonitor : public CurrentMonitorBase { int channel = 0; }; +class ReceiverInfo { +public: + bool isOn = false; + bool hasTriggered = false; + bool enabled = false; + int pixelCount = -1; + int configuredCount = -1; + float current = 0.0f; + std::string warning; +}; + class PortPinInfo { public: PortPinInfo(const std::string& n, const Json::Value& c) : - name(n), config(c) {} + name(n), config(c) { + if (config.isMember("row")) { + row = config["row"].asInt(); + } + if (config.isMember("col")) { + col = config["col"].asInt(); + } + } ~PortPinInfo() { if (currentMonitor) { delete currentMonitor; } } + void setConfig(const Json::Value& c) { + config = c; + if (config.isMember("row")) { + row = config["row"].asInt(); + } + if (config.isMember("col")) { + col = config["col"].asInt(); + } + } + std::string name; Json::Value config; - - bool isOn = false; - bool hasTriggered = false; - bool enabled = true; uint32_t group = 0; const PinCapabilities* enablePin = nullptr; @@ -137,35 +162,54 @@ class PortPinInfo { const PinCapabilities* eFuseInterruptPin = nullptr; CurrentMonitorBase* currentMonitor = nullptr; - int pixelCount = -1; - int configuredCount = -1; - std::string warning; + bool isSmartReceiver = false; + ReceiverInfo receivers[6]; + + int row = -1; + int col = -1; void appendTo(Json::Value& result) { Json::Value v; v["name"] = name; - if (enablePin) { - int pv = enablePin->getValue(); - v["enabled"] = (pv && highToEnable) || (!pv && !highToEnable); - } - if (isOn && eFusePin) { - v["status"] = eFuseOKValue == eFusePin->getValue(); + + if (isSmartReceiver) { + v["smartReceivers"] = true; + for (int x = 0; x < 6; x++) { + if (receivers[x].enabled) { + std::string sri(1, (char)('A' + x)); + v[sri]["enabled"] = receivers[x].isOn; + v[sri]["ma"] = receivers[x].current; + v[sri]["status"] = (receivers[x].isOn && !receivers[x].hasTriggered) || !receivers[x].isOn; + if (receivers[x].pixelCount >= 0 && receivers[x].pixelCount < 0xFFFF) { + v[sri]["pixelCount"] = receivers[x].pixelCount; + } + } + } } else { - v["status"] = true; - } - if (currentMonitor) { - float f = currentMonitor->getValue(); - int c = std::round(f); - v["ma"] = c; - } - if (config.isMember("row")) { - v["row"] = config["row"]; + if (enablePin) { + int pv = enablePin->getValue(); + v["enabled"] = (pv && highToEnable) || (!pv && !highToEnable); + } + if (receivers[0].isOn && eFusePin) { + v["status"] = eFuseOKValue == eFusePin->getValue(); + } else { + v["status"] = true; + } + if (currentMonitor) { + float f = currentMonitor->getValue(); + int c = std::round(f); + v["ma"] = c; + } + if (receivers[0].pixelCount >= 0) { + v["pixelCount"] = receivers[0].pixelCount; + } } - if (config.isMember("col")) { - v["col"] = config["col"]; + + if (row != -1) { + v["row"] = row; } - if (pixelCount >= 0) { - v["pixelCount"] = pixelCount; + if (col != -1) { + v["col"] = col; } result.append(v); } @@ -305,21 +349,27 @@ void OutputMonitor::checkPixelCounts(const std::string& portList, const std::str } for (auto p : portPins) { if (ports.find(p->name) != ports.end()) { - int diff = std::abs(p->configuredCount - p->pixelCount); - std::string newWarn; - if (diff > sensitivty) { - newWarn = p->name + " configured for " + std::to_string(p->configuredCount) + " pixels but " + std::to_string(p->pixelCount) + " pixels detected."; - } - if (action == "Warn" && newWarn != p->warning) { - if (!p->warning.empty()) { - WarningHolder::RemoveWarning(p->warning); + for (int x = 0; x < 6; x++) { + int diff = std::abs(p->receivers[x].configuredCount - p->receivers[x].pixelCount); + std::string newWarn; + if (diff > sensitivty) { + newWarn = p->name; + if (p->isSmartReceiver) { + p += (char)('A' + x); + } + newWarn += " configured for " + std::to_string(p->receivers[x].configuredCount) + " pixels but " + std::to_string(p->receivers[x].pixelCount) + " pixels detected."; } - p->warning = newWarn; - if (!p->warning.empty()) { - WarningHolder::AddWarning(p->warning); + if (action == "Warn" && newWarn != p->receivers[x].warning) { + if (!p->receivers[x].warning.empty()) { + WarningHolder::RemoveWarning(p->receivers[x].warning); + } + p->receivers[x].warning = newWarn; + if (!p->receivers[x].warning.empty()) { + WarningHolder::AddWarning(p->receivers[x].warning); + } + } else if (action == "Log") { + LogInfo(VB_CHANNELOUT, "%s\n", newWarn.c_str()); } - } else if (action == "Log") { - LogInfo(VB_CHANNELOUT, "%s\n", newWarn.c_str()); } } } @@ -333,9 +383,11 @@ void OutputMonitor::EnableOutputs() { PinCapabilities::SetMultiPinValue(pullHighOutputPins, 1); PinCapabilities::SetMultiPinValue(pullLowOutputPins, 0); for (auto p : portPins) { - if (p->enabled) { - p->isOn = true; - p->hasTriggered = false; + for (auto& r : p->receivers) { + if (r.enabled) { + r.isOn = true; + r.hasTriggered = false; + } } } for (auto p : portPins) { @@ -352,7 +404,12 @@ void OutputMonitor::DisableOutputs() { } std::unique_lock lock(gpioLock); for (auto p : portPins) { - p->isOn = false; + for (auto& r : p->receivers) { + r.isOn = false; + if (p->isSmartReceiver) { + r.current = 0; + } + } } PinCapabilities::SetMultiPinValue(pullHighOutputPins, 0); PinCapabilities::SetMultiPinValue(pullLowOutputPins, 1); @@ -362,28 +419,46 @@ void OutputMonitor::DisableOutputs() { void OutputMonitor::SetOutput(const std::string& port, bool on) { std::unique_lock lock(gpioLock); + int pn = 0; for (auto p : portPins) { if (p->name == port && p->enablePin) { - p->hasTriggered = false; - p->isOn = on; + p->receivers[0].hasTriggered = false; + p->receivers[0].isOn = on; int value = p->highToEnable ? on : !on; WarningHolder::RemoveWarning("eFUSE Triggered for " + p->name); p->enablePin->setValue(value); return; + } else if (p->isSmartReceiver) { + for (int x = 0; x < 6; x++) { + if (port == std::string(p->name) + std::string(1, 'A' + x)) { + bool isOn = p->receivers[x].isOn && !p->receivers[x].hasTriggered; + if (on != isOn) { + srCallback(pn, x, "ToggleOutput"); + } + } + } } + pn++; } } -void OutputMonitor::AddPortConfiguration(const std::string& name, const Json::Value& pinConfig, bool enabled) { +void OutputMonitor::AddPortConfiguration(int port, const Json::Value& pinConfig, bool enabled) { + std::string name = "Port " + std::to_string(port + 1); + if (port < portPins.size() && portPins[port]->name == name) { + portPins[port]->setConfig(pinConfig); + return; + } + PortPinInfo* pi = new PortPinInfo(name, pinConfig); bool hasInfo = false; + pi->receivers[0].enabled = true; if (pinConfig.isMember("enablePin")) { std::string ep = pinConfig.get("enablePin", "").asString(); if (ep != "") { pi->enablePin = AddOutputPin(name, ep); pi->highToEnable = (ep[0] != '!'); if (!enabled) { - pi->enabled = false; + pi->receivers[0].enabled = false; if (pi->highToEnable) { pullHighOutputPins.pop_back(); } else { @@ -436,11 +511,11 @@ void OutputMonitor::AddPortConfiguration(const std::string& name, const Json::Va // make sure the port is turned off a->enablePin->setValue(a->highToEnable ? 0 : 1); } - if (a->isOn && !a->hasTriggered) { + if (a->receivers[0].isOn && !a->receivers[0].hasTriggered) { // Output SHOULD be on, but the fuse triggered. That's a warning. LogWarn(VB_CHANNELOUT, "eFUSE Triggered for " + a->name + "\n"); WarningHolder::AddWarning("eFUSE Triggered for " + a->name); - a->hasTriggered = true; + a->receivers[0].hasTriggered = true; } } } @@ -474,14 +549,14 @@ void OutputMonitor::AddPortConfiguration(const std::string& name, const Json::Va if (pi->eFuseInterruptPin == nullptr) { GPIOManager::INSTANCE.AddGPIOCallback(pi->eFusePin, [this, pi](int v) { std::unique_lock lock(gpioLock); - //printf("eFuse for %s trigger: %d %d\n", pi->name.c_str(), v, pi->eFusePin->getValue()); + // printf("eFuse for %s trigger: %d %d\n", pi->name.c_str(), v, pi->eFusePin->getValue()); v = pi->eFusePin->getValue(); if (v != pi->eFuseOKValue) { if (pi->enablePin) { // make sure the port is turned off pi->enablePin->setValue(pi->highToEnable ? 0 : 1); } - if (pi->isOn) { + if (pi->receivers[0].isOn) { LogWarn(VB_CHANNELOUT, "eFUSE Triggered for " + pi->name + "\n"); // Output SHOULD be on, but the fuse triggered. That's a warning. WarningHolder::AddWarning("eFUSE Triggered for " + pi->name); @@ -506,9 +581,47 @@ void OutputMonitor::AddPortConfiguration(const std::string& name, const Json::Va pi->currentMonitor = new SensorCurrentMonitor(pinConfig["currentSensor"]); } } - if (hasInfo) { portPins.push_back(pi); + } else if (pinConfig.isMember("falconV5Listener")) { + int mr = -1; + bool hasSR = false; + for (auto a : portPins) { + mr = std::max(mr, a->row); + hasSR |= a->isSmartReceiver; + } + + int col = portPins.empty() ? 1 : portPins.back()->col; + + pi->isSmartReceiver = true; + pi->group = -1; + pi->receivers[0].enabled = false; + portPins.push_back(pi); + + if (!hasSR || col == 8) { + col = 1; + mr += hasSR ? 8 : 1; + } else { + col = 5; + } + + if (pi->row == -1) { + pi->col = col; + pi->row = mr; + } + int mc = pi->col; + mr = pi->row; + for (int x = 1; x < 4; x++) { + std::string name = "Port " + std::to_string(port + 1 + x); + pi = new PortPinInfo(name, pinConfig); + if (pi->row == -1) { + pi->row = mr; + pi->col = mc + x; + } + pi->isSmartReceiver = true; + pi->group = -1; + portPins.push_back(pi); + } } else { delete pi; } @@ -559,7 +672,7 @@ void OutputMonitor::lockToGroup(int i) { Sensors::INSTANCE.lockToGroup(i); } bool OutputMonitor::isPortInGroup(int group, int port) { - return ((port < portPins.size()) && (group == portPins[port]->group)); + return ((port < portPins.size()) && portPins[port] && (group == portPins[port]->group)); } std::vector OutputMonitor::GetPortCurrentValues() { @@ -570,20 +683,20 @@ std::vector OutputMonitor::GetPortCurrentValues() { if (a->currentMonitor && ((curGroup == -1) || (curGroup == a->group))) { ret.push_back(a->currentMonitor->getValue()); } else { - ret.push_back(0); + ret.push_back(a->receivers[0].current); } } return ret; } void OutputMonitor::SetPixelCount(int port, int pc, int cc) { - if (port < portPins.size() && ((curGroup == -1) || (curGroup == portPins[port]->group))) { - portPins[port]->pixelCount = pc; - portPins[port]->configuredCount = cc; + if (port < portPins.size() && portPins[port] && ((curGroup == -1) || (curGroup == portPins[port]->group))) { + portPins[port]->receivers[0].pixelCount = pc; + portPins[port]->receivers[0].configuredCount = cc; } } int OutputMonitor::GetPixelCount(int port) { - if (port < portPins.size()) { - return portPins[port]->pixelCount; + if (port < portPins.size() && portPins[port]) { + return portPins[port]->receivers[0].pixelCount; } return 0; } @@ -597,6 +710,17 @@ void OutputMonitor::GetCurrentPortStatusJson(Json::Value& result) { } } +void OutputMonitor::setSmartReceiverInfo(int port, int index, bool enabled, bool tripped, int current, int pixelCount) { + // printf(" %d %c: Current: %d PC: %d EN: %d TR: %d\n", port + 1, (char)('A' + index), current, pixelCount, enabled, tripped); + if (port < portPins.size()) { + portPins[port]->receivers[index].enabled = true; + portPins[port]->receivers[index].isOn = enabled; + portPins[port]->receivers[index].hasTriggered = tripped; + portPins[port]->receivers[index].pixelCount = pixelCount; + portPins[port]->receivers[index].current = current; + } +} + HTTP_RESPONSE_CONST std::shared_ptr OutputMonitor::render_GET(const httpserver::http_request& req) { int plen = req.get_path_pieces().size(); if (plen > 1 && req.get_path_pieces()[1] == "ports") { @@ -604,7 +728,15 @@ HTTP_RESPONSE_CONST std::shared_ptr OutputMonitor::re Json::Value result; result.append("--ALL--"); for (auto a : portPins) { - result.append(a->name); + if (a->isSmartReceiver) { + for (int x = 0; x < 6; x++) { + if (a->receivers[x].enabled) { + result.append(a->name + std::string(1, 'A' + x)); + } + } + } else { + result.append(a->name); + } } std::string resultStr = SaveJsonToString(result); return std::shared_ptr(new httpserver::string_response(resultStr, 200, "application/json")); diff --git a/src/OutputMonitor.h b/src/OutputMonitor.h index 4f3ed7a0a..d193fa087 100644 --- a/src/OutputMonitor.h +++ b/src/OutputMonitor.h @@ -30,7 +30,7 @@ class OutputMonitor : public httpserver::http_resource { void Initialize(std::map>& callbacks); void Cleanup(); - void AddPortConfiguration(const std::string& name, const Json::Value& config, bool enabled = true); + void AddPortConfiguration(int port, const Json::Value& config, bool enabled = true); const PinCapabilities* AddOutputPin(const std::string& name, const std::string& pin); void EnableOutputs(); @@ -54,6 +54,11 @@ class OutputMonitor : public httpserver::http_resource { void checkPixelCounts(const std::string& portList, const std::string& action, int sensitivy); + void setSmartReceiverInfo(int port, int index, bool enabled, bool tripped, int current, int pixelCount); + void setSmartReceiverEventCallback(std::function&& f) { + srCallback = f; + } + private: OutputMonitor(); ~OutputMonitor(); @@ -66,4 +71,6 @@ class OutputMonitor : public httpserver::http_resource { std::mutex gpioLock; int numGroups = 1; int curGroup = -1; + + std::function srCallback; }; diff --git a/src/channeloutput/PixelString.cpp b/src/channeloutput/PixelString.cpp index 16b570a4d..3dfc727a2 100644 --- a/src/channeloutput/PixelString.cpp +++ b/src/channeloutput/PixelString.cpp @@ -246,7 +246,7 @@ int PixelString::Init(Json::Value config, Json::Value* pinConfig) { AddVirtualString(VirtualString()); } if (pinConfig) { - OutputMonitor::INSTANCE.AddPortConfiguration("Port #" + std::to_string(m_portNumber + 1), *pinConfig, m_outputChannels > 0); + OutputMonitor::INSTANCE.AddPortConfiguration(m_portNumber, *pinConfig, m_outputChannels > 0); } m_outputMap.resize(m_outputChannels); diff --git a/src/non-gpl/BBShiftString/BBShiftString.cpp b/src/non-gpl/BBShiftString/BBShiftString.cpp index d4ac00b32..c330dc891 100644 --- a/src/non-gpl/BBShiftString/BBShiftString.cpp +++ b/src/non-gpl/BBShiftString/BBShiftString.cpp @@ -605,6 +605,9 @@ void BBShiftStringOutput::prepData(FrameData& d, unsigned char* channelData) { PixelStringTester* tester = nullptr; if (m_testType && m_testCycle >= 0) { + if (m_testType == 999 && falconV5Support && m_testCycle == 0) { + falconV5Support->sendCountPixelPackets(); + } tester = PixelStringTester::getPixelStringTester(m_testType); tester->prepareTestData(m_testCycle, m_testPercent); } diff --git a/src/non-gpl/FalconV5Support/FalconV5Support.cpp b/src/non-gpl/FalconV5Support/FalconV5Support.cpp index 1508455b1..9ed9f635d 100644 --- a/src/non-gpl/FalconV5Support/FalconV5Support.cpp +++ b/src/non-gpl/FalconV5Support/FalconV5Support.cpp @@ -15,6 +15,7 @@ #include #include "FalconV5Support.h" +#include "OutputMonitor.h" #include "Warnings.h" #include "common.h" #include "channeloutput/PixelString.h" @@ -101,8 +102,13 @@ class PRUControl { }; FalconV5Support::FalconV5Support() { + OutputMonitor::INSTANCE.setSmartReceiverEventCallback([this](int port, int index, const std::string& cmd) { + togglePort = port; + toggleIndex = index; + }); } FalconV5Support::~FalconV5Support() { + OutputMonitor::INSTANCE.setSmartReceiverEventCallback(nullptr); for (auto rc : receiverChains) { delete rc; } @@ -320,6 +326,13 @@ bool FalconV5Support::ReceiverChain::generateQueryPacket(uint8_t* packet, int re config["receiver"] = receiver; return encodeFalconV5Packet(config, packet); } +bool FalconV5Support::ReceiverChain::generateToggleEFusePacket(uint8_t* packet, int receiver, int port) const { + Json::Value config; + config["type"] = "toggleFuse"; + config["receiver"] = receiver; + config["port"] = port; + return encodeFalconV5Packet(config, packet); +} bool FalconV5Support::ReceiverChain::generateNumberPackets(uint8_t* packet, uint8_t* packet2) const { Json::Value config; @@ -343,10 +356,17 @@ bool FalconV5Support::ReceiverChain::generateQueryPacket(uint8_t* packet) { } return generateQueryPacket(packet, curReceiverQuery++); } +bool FalconV5Support::ReceiverChain::generatePixelCountPacket(uint8_t* packet) const { + Json::Value config; + config["type"] = "pixelCount"; + return encodeFalconV5Packet(config, packet); +} void FalconV5Support::ReceiverChain::handleQueryResponse(Json::Value& json) { int index = json["index"].asInt(); int port = json["port"].asInt(); + int dial = json["dial"].asInt(); + int numPorts = json["numPorts"].asInt(); if (ports[index].size() < numPorts) { ports[index].resize(numPorts); @@ -356,6 +376,13 @@ void FalconV5Support::ReceiverChain::handleQueryResponse(Json::Value& json) { ports[index][x].pixelCount = json["ports"][x]["pixelCount"].asInt() == 0xFFFF ? 0 : json["pixelCount"].asInt(); ports[index][x].fuseBlown = json["ports"][x]["fuseBlown"].asBool(); ports[index][x].fuseOn = json["ports"][x]["fuseOn"].asBool(); + + OutputMonitor::INSTANCE.setSmartReceiverInfo(port + x % 4, x / 4, + ports[index][x].fuseOn, + ports[index][x].fuseBlown, + ports[index][x].current, + json["ports"][x]["pixelCount"].asInt()); + if (ports[index][x].fuseBlown) { char idx = 'A' + index; std::string w = "eFUSE Triggered for port " + std::to_string(port + x + 1) + idx; @@ -383,6 +410,7 @@ bool FalconV5Support::generateDynamicPacket(std::vector> int newMux = curMux + 1; if (newMux >= maxCount.size()) { newMux = 0; + triggerPixelCount = false; } if (newMux != curMux) { setCurrentMux(newMux); @@ -401,8 +429,23 @@ bool FalconV5Support::generateDynamicPacket(std::vector> g.second.push_back(rc); rc = g.second.front(); } - rc->generateQueryPacket(&packets[rc->getPixelStrings().front()->m_portNumber][0]); + int rcP = rc->getPixelStrings().front()->m_portNumber; + if (rcP <= togglePort && (rcP + 4) > togglePort) { + rc->generateToggleEFusePacket(&packets[rc->getPixelStrings().front()->m_portNumber][0], toggleIndex, togglePort % 4); + togglePort = -1; + } else if (triggerPixelCount) { + rc->generatePixelCountPacket(&packets[rc->getPixelStrings().front()->m_portNumber][0]); + listen = false; + } else { + rc->generateQueryPacket(&packets[rc->getPixelStrings().front()->m_portNumber][0]); + listen = true; + } } - listen = true; return true; } + +void FalconV5Support::sendCountPixelPackets() { + setCurrentMux(0); + curCount = 0; + triggerPixelCount = true; +} diff --git a/src/non-gpl/FalconV5Support/FalconV5Support.h b/src/non-gpl/FalconV5Support/FalconV5Support.h index a3f665be4..e10d0a534 100644 --- a/src/non-gpl/FalconV5Support/FalconV5Support.h +++ b/src/non-gpl/FalconV5Support/FalconV5Support.h @@ -41,6 +41,7 @@ class FalconV5Support { bool generateNumberPackets(uint8_t* packet, uint8_t* packet2) const; bool generateQueryPacket(uint8_t* packet, int receiver) const; bool generateResetFusesPacket(uint8_t* packet) const; + bool generateToggleEFusePacket(uint8_t* packet, int receiver, int port) const; const std::array& getPixelStrings() const { return strings; }; uint32_t getReceiverCount() const { return numReceivers; } @@ -49,6 +50,7 @@ class FalconV5Support { void resetQueryCount() { curReceiverQuery = 0; } bool generateQueryPacket(uint8_t* packet); void handleQueryResponse(Json::Value& json); + bool generatePixelCountPacket(uint8_t* packet) const; private: std::array strings; @@ -71,6 +73,8 @@ class FalconV5Support { bool generateDynamicPacket(std::vector>& packets, bool& listen); + void sendCountPixelPackets(); + private: std::list receiverChains; std::list listeners; @@ -81,4 +85,8 @@ class FalconV5Support { std::vector maxCount; bool curMux = 0; int curCount = 0; + bool triggerPixelCount = false; + + int togglePort = -1; + int toggleIndex = -1; }; \ No newline at end of file diff --git a/www/currentmonitor.php b/www/currentmonitor.php index 8f2890687..37728fe4d 100644 --- a/www/currentmonitor.php +++ b/www/currentmonitor.php @@ -19,27 +19,80 @@ function OnDisableClicked(name) { function CountPixels() { $.get("api/fppd/ports/pixelCount"); } + +function FormatSmartReceiver(name, k, port, row, col) { + if (port == null) { + return ""; + } + var html = ""; + if (name != "") { + html += "" + name + "
"; + } + html += "" + k + ":
"; + html += "
"; + + if (port["enabled"]) { + html += "Enabled:
"; + } else if (port["status"]) { + html += "Enabled:
"; + } else { + html += "Enabled:
"; + } + if (port["status"]) { + html += "Status:
"; + } else { + html += "Status:
"; + } + if (typeof port.pixelCount !== 'undefined') { + html += "Pixels: " + port["pixelCount"] + "
"; + } + html += port["ma"] + " ma"; + + html += "
"; + $("#fppPorts tr:nth-child(" + row + ") td:nth-child(" + col + ")").html(html); + $("#fppPorts tr:nth-child(" + row + ")").show(); +} function StartMonitoring() { $.get('api/fppd/ports', function(data) { data.forEach(function(port) { - var html = "" + port["name"] + "
"; - if (port["enabled"]) { - html += "Enabled:
"; - } else if (port["status"]) { - html += "Enabled:
"; - } else { - html += "Enabled:
"; + var count = $('#fppPorts tr').length; + var rn = port["row"]; + if (port["smartReceivers"]) { + rn += 6; } - if (port["status"]) { - html += "Status:
"; - } else { - html += "Status:
"; + while (rn >= count) { + $('#fppPorts').append(""); + count++; } - if (typeof port.pixelCount !== 'undefined') { - html += "Pixels: " + port["pixelCount"] + "
"; + if (!port["smartReceivers"]) { + $("#fppPorts tr:nth-child(" + port["row"] + ")").show(); + var html = "" + port["name"] + "
"; + if (port["enabled"]) { + html += "Enabled:
"; + } else if (port["status"]) { + html += "Enabled:
"; + } else { + html += "Enabled:
"; + } + if (port["status"]) { + html += "Status:
"; + } else { + html += "Status:
"; + } + if (typeof port.pixelCount !== 'undefined') { + html += "Pixels: " + port["pixelCount"] + "
"; + } + html += port["ma"] + " ma"; + $("#fppPorts tr:nth-child(" + port["row"] + ") td:nth-child(" + port["col"] + ")").html(html); + } else { + rn = port["row"]; + FormatSmartReceiver(port["name"], "A", port["A"], rn, port["col"]); + FormatSmartReceiver(port["name"], "B", port["B"], rn + 1, port["col"]); + FormatSmartReceiver(port["name"], "C", port["C"], rn + 2, port["col"]); + FormatSmartReceiver(port["name"], "D", port["D"], rn + 3, port["col"]); + FormatSmartReceiver(port["name"], "E", port["E"], rn + 4, port["col"]); + FormatSmartReceiver(port["name"], "F", port["F"], rn + 5, port["col"]); } - html += port["ma"] + " ma"; - $("#fppPorts tr:nth-child(" + port["row"] + ") td:nth-child(" + port["col"] + ")").html(html); }); }); } @@ -68,11 +121,6 @@ function SetupPage() { - - - - -