Skip to content

Commit

Permalink
add V5 Receivers for Kulp/FPP, IDK good Variant Names, Hopefully Dan …
Browse files Browse the repository at this point in the history
…will update them to fit his product names, I just made a POC with the K16v2 I have
  • Loading branch information
computergeek1507 committed Dec 10, 2024
1 parent 370f0f9 commit 04dc9d1
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 10 deletions.
26 changes: 26 additions & 0 deletions controllers/kulp.xcontroller
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,32 @@
<fppSerialPort1>ttyS1</fppSerialPort1>
<fppSerialPort2>ttyS2</fppSerialPort2>
</Variant>
<Variant Name="v2 No Expansion" ID="K16A-B" Base="FPP:FPPStringCapeTTYs">

This comment has been minimized.

Copy link
@dkulp

dkulp Dec 10, 2024

Member

Honestly, I wasn't planning on creating separate variants at all. I was just going to add the falcon_v5 types and then in FPP.cpp, check the cape/strings/* file to see if the falconV5Listeners node is in the json and auto-drop to fpp_v2 on upload if not.

<MaxPixelPort>32</MaxPixelPort>
<MaxSerialPort>2</MaxSerialPort>
<fpp>1</fpp>
<fpp1>33,-1</fpp1>
<fppSerialPort1>ttyS1</fppSerialPort1>
<fppSerialPort2>ttyS2</fppSerialPort2>
<SmartRemoteTypes>
<Type>falcon_v1</Type>
<Type>fpp_v2</Type>
<Type>falcon_v5</Type>
</SmartRemoteTypes>
</Variant>
<Variant Name="v2 Expansion" ID="K16A-B" Base="FPP:FPPStringCapeTTYs">
<MaxPixelPort>48</MaxPixelPort>
<MaxSerialPort>2</MaxSerialPort>
<fpp>1</fpp>
<fpp1>33,16</fpp1>
<fppSerialPort1>ttyS1</fppSerialPort1>
<fppSerialPort2>ttyS2</fppSerialPort2>
<SmartRemoteTypes>
<Type>falcon_v1</Type>
<Type>fpp_v2</Type>
<Type>falcon_v5</Type>
</SmartRemoteTypes>
</Variant>
</Controller>
<Controller Name="K4-PB">
<Variant Name="" ID="K4-PB" Base="FPP:FPPStringCapeTTYs">
Expand Down
51 changes: 41 additions & 10 deletions xLights/controllers/FPP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2759,7 +2759,10 @@ bool FPP::UploadPixelOutputs(ModelManager* allmodels,
vsname += "F";
}
if (pvs->_smartRemote >= 1) {
if (pvs->_smartRemoteType.find("v2") != std::string::npos) {
auto const diff_type = DecodeReceiverType(pvs->_smartRemoteType);
if (diff_type == ReceiverType::FalconV5) {
stringData["outputs"][port->GetPort() - 1]["differentialType"] = 10;
} else if(diff_type == ReceiverType::v2) {
stringData["outputs"][port->GetPort() - 1]["differentialType"] = 4;
} else {
stringData["outputs"][port->GetPort() - 1]["differentialType"] = 1;
Expand Down Expand Up @@ -2792,7 +2795,7 @@ bool FPP::UploadPixelOutputs(ModelManager* allmodels,
if ((x & 0x3) == 0) {
//need to check the group of 4 to see if we need a smartRemote or not
int remoteType = 0;
bool remoteTypeV2 = false;
ReceiverType receiverType{ ReceiverType::Standard };
for (int z = 0; z < 4; z++) {
if ((x + z) < maxport) {
if (stringData["outputs"][x + z].HasMember("virtualStringsF")) {
Expand All @@ -2808,13 +2811,14 @@ bool FPP::UploadPixelOutputs(ModelManager* allmodels,
} else if (stringData["outputs"][x+z].HasMember("differentialType")) {
remoteType = std::max(remoteType, 1);
}
if (stringData["outputs"][x + z].HasMember("differentialType") &&
stringData["outputs"][x + z]["differentialType"].AsLong() > 3) {
remoteTypeV2 = true;
if (stringData["outputs"][x + z].HasMember("differentialType") ) {
receiverType = DecodeReceiverType(stringData["outputs"][x + z]["differentialType"].AsLong());
}
}
}
if (remoteTypeV2) {
if (ReceiverType::FalconV5 == receiverType) {
remoteType += 9;
} else if (ReceiverType::v2 == receiverType) {
remoteType += 3;
}
if (remoteType) {
Expand Down Expand Up @@ -3963,17 +3967,17 @@ std::list<FPP*> FPP::GetInstances(wxWindow* frame, OutputManager* outputManager)
// show network to be easier to do
for (auto& it : outputManager->GetControllers()) {
auto eth = dynamic_cast<ControllerEthernet*>(it);
if (eth != nullptr && eth->GetIP() != "" && eth->GetIP() != "MULTICAST") {
if (eth != nullptr && !eth->GetIP().empty() && eth->GetIP() != "MULTICAST") {
std::string resolvedIP = eth->GetResolvedIP(true);
if (resolvedIP == "") {
if (resolvedIP.empty()) {
startAddresses.push_back(::Lower(eth->GetIP()));
} else {
// only add the instances where we were actually able to resolve an IP address
if (eth->IsActive() && (ip_utils::IsIPValid(resolvedIP) || resolvedIP != eth->GetIP())) {
startAddresses.push_back(::Lower(resolvedIP));
}
}
if (eth->GetFPPProxy() != "") {
if (!eth->GetFPPProxy().empty()) {
startAddresses.push_back(::Lower(ip_utils::ResolveIP(eth->GetFPPProxy())));
}
}
Expand All @@ -3992,7 +3996,7 @@ std::list<FPP*> FPP::GetInstances(wxWindow* frame, OutputManager* outputManager)
for (const auto& a : startAddressesForced) {
for (const auto& fpp : instances) {
if (case_insensitive_match(a, fpp->hostName) || case_insensitive_match(a, fpp->ipAddress)) {
if (newForce != "") {
if (!newForce.empty()) {
newForce.append(",");
}
newForce.append(a);
Expand All @@ -4006,3 +4010,30 @@ std::list<FPP*> FPP::GetInstances(wxWindow* frame, OutputManager* outputManager)

return instances;
}


ReceiverType FPP::DecodeReceiverType(const std::string& type) {
if (type.find("v1") != std::string::npos) {
return ReceiverType::v1;
}
if (type.find("v2") != std::string::npos) {
return ReceiverType::v2;
}
if (type.find("v5") != std::string::npos) {
return ReceiverType::FalconV5;
}
return ReceiverType::Standard;
}

ReceiverType FPP::DecodeReceiverType(int type) {
if (9 < type) {
return ReceiverType::FalconV5;
}
if (3 < type) {
return ReceiverType::v2;
}
if (0 < type) {
return ReceiverType::v1;
}
return ReceiverType::Standard;
}
10 changes: 10 additions & 0 deletions xLights/controllers/FPP.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ enum class FPP_TYPE { FPP,
ESPIXELSTICK,
GENIUS };

enum class ReceiverType {
Standard = 0,
v1 = 1,
v2 = 2,
FalconV5 = 3
};

class FPP : public BaseController
{
public:
Expand Down Expand Up @@ -135,6 +142,9 @@ class FPP : public BaseController
static void TypeIDtoControllerType(int typeId, FPP* inst);
static std::list<FPP*> GetInstances(wxWindow* frame, OutputManager* outputManager);

static ReceiverType DecodeReceiverType(const std::string& type);
static ReceiverType DecodeReceiverType(int type);

#ifndef DISCOVERYONLY
wxJSONValue CreateModelMemoryMap(ModelManager* allmodels, int32_t startChan, int32_t endChannel);
static std::string CreateVirtualDisplayMap(ModelManager* allmodels, int previewWi, int previewHi);
Expand Down

0 comments on commit 04dc9d1

Please sign in to comment.