From 02fef83bb8bc9df1f2b41437515ee4f8db68e3bd Mon Sep 17 00:00:00 2001 From: Rick164 Date: Sat, 2 Apr 2016 00:07:28 +0200 Subject: [PATCH] AtmoOrb smoothing additions * Updated smoothing options for AtmoOrb, can now choose between Orb external or Hyperion's internal smoothing. With skipSmoothingDif you can set the maximum allowed color difference before overriding / clearing Orb smoothing during faster color change like for instance color <-> black. * Updated inline documentation. * Fixed command type typo in AtmoOrb device. * Corrected variable spelling in AtmoOrb device. * Make smoothing also match equal values for AtmoOrb smoothing differential Former-commit-id: 3eede43c2f76fa324f0144aeac0526b8125ad149 --- libsrc/leddevice/LedDeviceAtmoOrb.cpp | 40 +++++++++++++++++---------- libsrc/leddevice/LedDeviceAtmoOrb.h | 23 ++++++++------- libsrc/leddevice/LedDeviceFactory.cpp | 31 +++++++++++---------- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/libsrc/leddevice/LedDeviceAtmoOrb.cpp b/libsrc/leddevice/LedDeviceAtmoOrb.cpp index 4ef3486d..02ea1b62 100644 --- a/libsrc/leddevice/LedDeviceAtmoOrb.cpp +++ b/libsrc/leddevice/LedDeviceAtmoOrb.cpp @@ -15,9 +15,9 @@ AtmoOrbLight::AtmoOrbLight(unsigned int id) { // Not implemented } -LedDeviceAtmoOrb::LedDeviceAtmoOrb(const std::string &output, bool switchOffOnBlack, - int transitiontime, int port, int numLeds, std::vector orbIds) : - multicastGroup(output.c_str()), switchOffOnBlack(switchOffOnBlack), transitiontime(transitiontime), +LedDeviceAtmoOrb::LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing, + int transitiontime, int skipSmoothingDiff, int port, int numLeds, std::vector orbIds) : + multicastGroup(output.c_str()), useOrbSmoothing(useOrbSmoothing), transitiontime(transitiontime), skipSmoothingDiff(skipSmoothingDiff), multiCastGroupPort(port), numLeds(numLeds), orbIds(orbIds) { manager = new QNetworkAccessManager(); groupAddress = QHostAddress(multicastGroup); @@ -35,30 +35,40 @@ int LedDeviceAtmoOrb::write(const std::vector &ledValues) { return 0; } + // Command options: + // + // 1 = force off + // 2 = use lamp smoothing and validate by Orb ID + // 4 = validate by Orb ID + + // When setting useOrbSmoothing = true it's recommended to disable Hyperion's own smoothing as it will conflict (double smoothing) + int commandType = 4; + if(useOrbSmoothing) + { + commandType = 2; + } + // Iterate through colors and set Orb color // Start off with idx 1 as 0 is reserved for controlling all orbs at once unsigned int idx = 1; for (const ColorRgb &color : ledValues) { - // Options parameter: - // - // 1 = force off - // 2 = use lamp smoothing and validate by Orb ID - // 4 = validate by Orb ID - // - if (switchOffOnBlack && color.red == 0 && color.green == 0 && color.blue == 0) { - // Force to black + // If color difference is higher than skipSmoothingDiff than we skip Orb smoothing (if enabled) and send it right away + if ((skipSmoothingDiff != 0 && useOrbSmoothing) && (abs(color.red - lastRed) >= skipSmoothingDiff || abs(color.blue - lastBlue) >= skipSmoothingDiff || + abs(color.green - lastGreen) >= skipSmoothingDiff)) + { + // Skip Orb smoothing when using (command type 4) for (unsigned int i = 0; i < orbIds.size(); i++) { if (orbIds[i] == idx) { - setColor(idx, color, 1); + setColor(idx, color, 4); } } } else { - // Default send color + // Send color for (unsigned int i = 0; i < orbIds.size(); i++) { if (orbIds[i] == idx) { - setColor(idx, color, 4); + setColor(idx, color, commandType); } } } @@ -80,7 +90,7 @@ void LedDeviceAtmoOrb::setColor(unsigned int orbId, const ColorRgb &color, int c bytes[2] = 0xEE; // Command type - bytes[3] = 2; + bytes[3] = commandType; // Orb ID bytes[4] = orbId; diff --git a/libsrc/leddevice/LedDeviceAtmoOrb.h b/libsrc/leddevice/LedDeviceAtmoOrb.h index d425b06a..fb3733aa 100644 --- a/libsrc/leddevice/LedDeviceAtmoOrb.h +++ b/libsrc/leddevice/LedDeviceAtmoOrb.h @@ -48,21 +48,21 @@ public: /// /// @param output is the multicast address of Orbs /// - /// @param switchOffOnBlack turn off Orbs on black (default: false) - /// /// @param transitiontime is optional and not used at the moment /// + /// @param useOrbSmoothing use Orbs own (external) smoothing algorithm (default: false) + /// + /// @param skipSmoothingDiff minimal color (0-255) difference to override smoothing so that if current and previously received colors are higher than set dif we override smoothing + /// /// @param port is the multicast port. /// /// @param numLeds is the total amount of leds per Orb /// /// @param array containing orb ids /// - LedDeviceAtmoOrb(const std::string &output, bool switchOffOnBlack = - false, int transitiontime = 0, int port = 49692, int numLeds = 24, - std::vector orbIds = std::vector < unsigned int - - >()); + LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing = + false, int transitiontime = 0, int skipSmoothingDiff = 0, int port = 49692, int numLeds = 24, + std::vector orbIds = std::vector < unsigned int>()); /// /// Destructor of this device @@ -87,12 +87,15 @@ private: /// String containing multicast group IP address QString multicastGroup; - /// Switch off when detecting black - bool switchOffOnBlack; + /// use Orbs own (external) smoothing algorithm + bool useOrbSmoothing; /// Transition time between colors (not implemented) int transitiontime; + // Maximum allowed color difference, will skip Orb (external) smoothing once reached + int skipSmoothingDiff; + /// Multicast port to send data to int multiCastGroupPort; @@ -126,4 +129,4 @@ private: /// @param bytes the byte array containing command to send over multicast /// void sendCommand(const QByteArray &bytes); -}; +}; \ No newline at end of file diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index db53cd58..43e715a5 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -246,35 +246,36 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) } device = new LedDevicePhilipsHue(output, username, switchOffOnBlack, transitiontime, lightIds); } - else if (type == "atmoorb") - { + else if (type == "atmoorb") + { const std::string output = deviceConfig["output"].asString(); - const bool switchOffOnBlack = deviceConfig.get("switchOffOnBlack", true).asBool(); + const bool useOrbSmoothing = deviceConfig.get("useOrbSmoothing", false).asBool(); const int transitiontime = deviceConfig.get("transitiontime", 1).asInt(); + const int skipSmoothingDiff = deviceConfig.get("skipSmoothingDiff", 0).asInt(); const int port = deviceConfig.get("port", 1).asInt(); const int numLeds = deviceConfig.get("numLeds", 1).asInt(); - const std::string orbId = deviceConfig["orbIds"].asString(); + const std::string orbId = deviceConfig["orbIds"].asString(); std::vector orbIds; // If we find multiple Orb ids separate them and add to list const std::string separator (","); if (orbId.find(separator) != std::string::npos) { - std::stringstream ss(orbId); - std::vector output; - unsigned int i; - while (ss >> i) { - orbIds.push_back(i); - if (ss.peek() == ',' || ss.peek() == ' ') - ss.ignore(); - } + std::stringstream ss(orbId); + std::vector output; + unsigned int i; + while (ss >> i) { + orbIds.push_back(i); + if (ss.peek() == ',' || ss.peek() == ' ') + ss.ignore(); + } } else { - orbIds.push_back(atoi(orbId.c_str())); + orbIds.push_back(atoi(orbId.c_str())); } - device = new LedDeviceAtmoOrb(output, switchOffOnBlack, transitiontime, port, numLeds, orbIds); - } + device = new LedDeviceAtmoOrb(output, useOrbSmoothing, transitiontime, skipSmoothingDiff, port, numLeds, orbIds); + } else if (type == "file") { const std::string output = deviceConfig.get("output", "/dev/null").asString();