diff --git a/libsrc/leddevice/CMakeLists.txt b/libsrc/leddevice/CMakeLists.txt index 7d3ea06..d4f5bf2 100755 --- a/libsrc/leddevice/CMakeLists.txt +++ b/libsrc/leddevice/CMakeLists.txt @@ -38,6 +38,7 @@ SET(Leddevice_HEADERS ${CURRENT_SOURCE_DIR}/LedDeviceFile.h ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h ${CURRENT_SOURCE_DIR}/LedDeviceUdp.h + ${CURRENT_SOURCE_DIR}/LedDeviceAurora.h ${CURRENT_SOURCE_DIR}/LedDeviceUdpRaw.h ${CURRENT_SOURCE_DIR}/LedUdpDevice.h ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h @@ -64,6 +65,7 @@ SET(Leddevice_SOURCES ${CURRENT_SOURCE_DIR}/LedDeviceFile.cpp ${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp ${CURRENT_SOURCE_DIR}/LedDeviceUdp.cpp + ${CURRENT_SOURCE_DIR}/LedDeviceAurora.cpp ${CURRENT_SOURCE_DIR}/LedDeviceUdpRaw.cpp ${CURRENT_SOURCE_DIR}/LedUdpDevice.cpp ${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp diff --git a/libsrc/leddevice/LedDeviceAurora.cpp b/libsrc/leddevice/LedDeviceAurora.cpp new file mode 100644 index 0000000..f3b1191 --- /dev/null +++ b/libsrc/leddevice/LedDeviceAurora.cpp @@ -0,0 +1,187 @@ + +// Local-Hyperion includes +#include "LedDeviceAurora.h" +#include +#include +// jsoncpp includes +#include +// qt includes +#include +#include + +#define ROOT_ROUTE "" +#define EFFECTS_ROUTE "effects" +#define URL_FORMAT "http://%1:16021/api/v1/%2/%3" +#define EXT_MODE_STRING "{\"write\" : {\"command\" : \"display\", \"animType\" : \"extControl\"}}" +#define PANELLAYOUT_KEY "panelLayout" +#define PANELCOUNT_KEY "numPanels" +#define PANELID_KEY "panelId" +#define POSITIONDATA_KEY "positionData" +#define UDPPORT_KEY "streamControlPort" +#define RHYTHM_KEY "rhythm" +#define RHYTHM_CONNECTED_KEY "rhythmConnected" + +struct addrinfo vints, *serverinfo, *pt; +//char udpbuffer[1024]; +int sockfp; +int update_num; + +LedDeviceAurora::LedDeviceAurora(const std::string& output, const std::string& key) { + manager = new QNetworkAccessManager(); + std::string hostname = output; + std::string port; + Json::Reader reader; + Json::FastWriter writer; + // Read Panel count and panel Ids + QByteArray response = get(QString::fromStdString(hostname), QString::fromStdString(key), ROOT_ROUTE); + Json::Value json; + if (!reader.parse(QString(response).toStdString(), json)) { + throw std::runtime_error("No Layout found"); + } + //Debug + // Json::FastWriter fastWriter; + // std::cout << fastWriter.write(json); + + Json::Value rhythmJson = json[RHYTHM_KEY]; + json = json[PANELLAYOUT_KEY]; + panelCount = json[PANELCOUNT_KEY].asUInt(); + Json::Value positionDataJson = json[POSITIONDATA_KEY]; + // Loop over all children. + for (Json::ValueIterator it = positionDataJson.begin(); it != positionDataJson.end() && panelIds.size() < panelCount; it++) { + Json::Value panel = *it; + int panelId = panel[PANELID_KEY].asUInt(); + panelIds.push_back(panelId); + } + + // Check if we found enough lights. + if ((panelIds.size() != panelCount) || (panelIds.size() != panelCount-1 && rhythmJson[RHYTHM_CONNECTED_KEY].asBool())) { + throw std::runtime_error("Not enough pannels found"); + }else { + std::cout << "All panel Ids found: "<< panelIds.size()<ai_next) { + if ((sockfp = socket(pt->ai_family, pt->ai_socktype, + pt->ai_protocol)) == -1) { + perror("talker: socket"); + continue; + } + + break; + } + + if (pt == NULL) { + fprintf(stderr, "talker: failed to create socket\n"); + assert(pt!=NULL); + } + //std::cout << "Started successfully "; +} + +QString LedDeviceAurora::getUrl(QString host, QString token, QString route) { + return QString(URL_FORMAT).arg(host).arg(token).arg(route); +} + +QByteArray LedDeviceAurora::get(QString host, QString token, QString route) { + QString url = getUrl(host, token, route); + // Perfrom request + QNetworkRequest request(url); + QNetworkReply* reply = manager->get(request); + // Connect requestFinished signal to quit slot of the loop. + QEventLoop loop; + loop.connect(reply, SIGNAL(finished()), SLOT(quit())); + // Go into the loop until the request is finished. + loop.exec(); + // Read all data of the response. + QByteArray response = reply->readAll(); + // Free space. + reply->deleteLater(); + // Return response + return response; +} + +QByteArray LedDeviceAurora::putJson(QString url, QString json) { + // Perfrom request + QNetworkRequest request(url); + QNetworkReply* reply = manager->put(request, json.toUtf8()); + // Connect requestFinished signal to quit slot of the loop. + QEventLoop loop; + loop.connect(reply, SIGNAL(finished()), SLOT(quit())); + // Go into the loop until the request is finished. + loop.exec(); + // Read all data of the response. + QByteArray response = reply->readAll(); + // Free space. + reply->deleteLater(); + // Return response + return response; +} + +QByteArray LedDeviceAurora::changeMode(QString host, QString token, QString route) { + QString url = getUrl(host, token, route); + QString jsondata(EXT_MODE_STRING); //Enable UDP Mode + return putJson(url, jsondata); +} + +LedDeviceAurora::~LedDeviceAurora() +{ + delete manager; +} + +int LedDeviceAurora::write(const std::vector & ledValues) +{ + uint udpBufferSize = panelCount * 7 + 1; + char udpbuffer[udpBufferSize]; + update_num++; + update_num &= 0xf; + + int i=0; + int panelCounter = 0; + udpbuffer[i++] = panelCount; + for (const ColorRgb& color : ledValues) + { + if (i panelCount) { + break; + } + //printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red)); + } + sendto(sockfp, udpbuffer, i, 0, pt->ai_addr, pt->ai_addrlen); + + return 0; +} + +int LedDeviceAurora::switchOff() +{ + return 0; +} diff --git a/libsrc/leddevice/LedDeviceAurora.h b/libsrc/leddevice/LedDeviceAurora.h new file mode 100644 index 0000000..d1ed7e9 --- /dev/null +++ b/libsrc/leddevice/LedDeviceAurora.h @@ -0,0 +1,59 @@ +#pragma once + +// Leddevice includes +#include +// Qt includes +#include +#include +#include +#include +/// +/// Implementation of the LedDevice that write the led-colors to an +/// ASCII-textfile('/home/pi/LedDevice.out') +/// +class LedDeviceAurora : public LedDevice +{ +public: + /// + /// Constructs the test-device, which opens an output stream to the file + /// + LedDeviceAurora(const std::string& output, const std::string& key); + + /// + /// Destructor of this test-device + /// + virtual ~LedDeviceAurora(); + + /// + /// Writes the given led-color values to the output stream + /// + /// @param ledValues The color-value per led + /// + /// @return Zero on success else negative + /// + virtual int write(const std::vector & ledValues); + + /// Switch the leds off + virtual int switchOff(); + +private: + /// The outputstream + // std::ofstream _ofs; + // QNetworkAccessManager object for sending requests. + QNetworkAccessManager* manager; + + // the number of leds (needed when switching off) + + size_t panelCount; + /// Array of the pannel ids. + std::vector panelIds; + QByteArray get(QString host, QString token, QString route); + QByteArray putJson(QString url, QString json); + QByteArray changeMode(QString host, QString token, QString route); + /// + /// @param route + /// + /// @return the full URL of the request. + /// + QString getUrl(QString host, QString token, QString route); +}; diff --git a/libsrc/leddevice/LedDeviceFactory.cpp b/libsrc/leddevice/LedDeviceFactory.cpp index 4f958ad..be01a35 100755 --- a/libsrc/leddevice/LedDeviceFactory.cpp +++ b/libsrc/leddevice/LedDeviceFactory.cpp @@ -40,6 +40,7 @@ #include "LedDeviceAtmo.h" #include "LedDeviceAdalightApa102.h" #include "LedDeviceAtmoOrb.h" +#include "LedDeviceAurora.h" #ifdef ENABLE_WS2812BPWM #include "LedDeviceWS2812b.h" @@ -319,6 +320,13 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig) const unsigned maxPacket = deviceConfig["maxpacket"].asInt(); device = new LedDeviceUdp(output, rate, protocol, maxPacket); } + else if (type == "aurora") + { + const std::string output = deviceConfig["output"].asString(); + const std::string key = deviceConfig["key"].asString(); + LedDeviceAurora* deviceAurora = new LedDeviceAurora(output, key); + device = deviceAurora; + } else if (type == "udpraw") { const std::string output = deviceConfig["output"].asString(); diff --git a/libsrc/leddevice/LedDeviceUdp.cpp b/libsrc/leddevice/LedDeviceUdp.cpp old mode 100644 new mode 100755 diff --git a/libsrc/leddevice/LedDeviceUdp.h b/libsrc/leddevice/LedDeviceUdp.h old mode 100644 new mode 100755