mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	WIP: Mode change done
This commit is contained in:
		
							
								
								
									
										203
									
								
								libsrc/leddevice/dev_net/LedDeviceAurora.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								libsrc/leddevice/dev_net/LedDeviceAurora.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
|  | ||||
| // Local-Hyperion includes | ||||
| #include "LedDeviceAurora.h" | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
| #include <netdb.h> | ||||
| #include <assert.h> | ||||
| // qt includes | ||||
| #include <QtCore/qmath.h> | ||||
| #include <QEventLoop> | ||||
| #include <QNetworkReply> | ||||
|  | ||||
| struct addrinfo vints, *serverinfo, *pt; | ||||
| //char udpbuffer[1024]; | ||||
| int sockfp; | ||||
| int update_num; | ||||
| LedDevice* LedDeviceAurora::construct(const QJsonObject &deviceConfig) | ||||
| { | ||||
| 	return new LedDeviceAurora(deviceConfig); | ||||
| } | ||||
|  | ||||
| LedDeviceAurora::LedDeviceAurora(const QJsonObject &deviceConfig) { | ||||
| 	init(deviceConfig); | ||||
| } | ||||
|  | ||||
| bool LedDeviceAurora::init(const QJsonObject &deviceConfig) { | ||||
| 	const QString hostname = deviceConfig["output"].toString(); | ||||
| 	const QString key  = deviceConfig["key"].toString(); | ||||
|  | ||||
| 	manager = new QNetworkAccessManager(); | ||||
| 	QString port; | ||||
| 	// Read Panel count and panel Ids | ||||
| 	QByteArray response = get(hostname, key, "panelLayout/layout"); | ||||
| 	QJsonParseError error; | ||||
| 	QJsonDocument doc = QJsonDocument::fromJson(response, &error); | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		throw std::runtime_error("No Layout found. Check hostname and auth key"); | ||||
| 	} | ||||
| 	//Debug | ||||
| 	QString strJson(doc.toJson(QJsonDocument::Compact)); | ||||
| 	std::cout << strJson.toUtf8().constData() << std::endl; | ||||
| 	 | ||||
| 	QJsonObject json = doc.object(); | ||||
|  | ||||
| 	//Debug | ||||
| 	//Json::FastWriter fastWriter; | ||||
| 	//std::cout << fastWriter.write(json); | ||||
|  | ||||
| 	panelCount = json["numPanels"].toInt(); | ||||
| 	std::cout << panelCount << std::endl; | ||||
| 	QJsonObject positionDataJson = doc.object()["positionData"].toObject(); | ||||
| 	QJsonArray positionData = json["positionData"].toArray(); | ||||
| 	// Loop over all children. | ||||
| 	foreach (const QJsonValue & value, positionData) { | ||||
| 		QJsonObject panelObj = value.toObject();	 | ||||
| 		int panelId = panelObj["panelId"].toInt(); | ||||
| 		panelIds.push_back(panelId); | ||||
| 	} | ||||
| 	 | ||||
| 	// Check if we found enough lights. | ||||
| 	if (panelIds.size() != panelCount) { | ||||
| 		throw std::runtime_error("Not enough lights found"); | ||||
| 	}else { | ||||
| 		std::cout <<  "All panel Ids found: "<< panelIds.size() << std::endl; | ||||
| 	} | ||||
| 	 | ||||
| 	// Set Aurora to UDP Mode | ||||
| 	QByteArray modeResponse = changeMode(hostname, key, "effects"); | ||||
| 	QJsonDocument configDoc = QJsonDocument::fromJson(modeResponse, &error); | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		throw std::runtime_error("Could not change mode"); | ||||
| 	} | ||||
| 	QJsonObject configJson = doc.object(); | ||||
|  | ||||
| 	// Get UDP port | ||||
| 	port = configJson["streamControlPort"].toString(); | ||||
|  | ||||
| 	std::cout << "hostname " << hostname.toStdString() << " port " << port.toStdString() << std::endl; | ||||
| 	/* | ||||
| 	int rv; | ||||
|  | ||||
| 	memset(&vints, 0, sizeof vints); | ||||
| 	vints.ai_family = AF_UNSPEC; | ||||
| 	vints.ai_socktype = SOCK_DGRAM; | ||||
|  | ||||
| 	if ((rv = getaddrinfo(hostname.c_str() , port.c_str(), &vints, &serverinfo)) != 0) { | ||||
| 		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); | ||||
| 		assert(rv==0); | ||||
| 	} | ||||
|  | ||||
| 	// loop through all the results and make a socket | ||||
| 	for(pt = serverinfo; pt != NULL; pt = pt->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 "; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| QString LedDeviceAurora::getUrl(QString host, QString token, QString route) { | ||||
| 	return QString("http://%1:16021/api/v1/%2/%3").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( "{\"write\" : {\"command\" : \"display\", \"animType\" : \"extControl\"}}"); //Enable UDP Mode | ||||
| 	return putJson(url, jsondata); | ||||
| } | ||||
|  | ||||
| LedDeviceAurora::~LedDeviceAurora() | ||||
| { | ||||
| 	delete manager; | ||||
| } | ||||
|  | ||||
| int LedDeviceAurora::write(const std::vector<ColorRgb> & 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<udpBufferSize) { | ||||
| 			udpbuffer[i++] = panelIds[panelCounter++ % panelCount]; | ||||
| 			udpbuffer[i++] = 1; // No of Frames | ||||
| 			udpbuffer[i++] = color.red; | ||||
| 			udpbuffer[i++] = color.green; | ||||
| 			udpbuffer[i++] = color.blue; | ||||
| 			udpbuffer[i++] = 0; // W not set manually | ||||
| 			udpbuffer[i++] = 1; // currently fixed at value 1 which corresponds to 100ms | ||||
| 		} | ||||
| 		if(panelCounter > 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; | ||||
| } | ||||
							
								
								
									
										67
									
								
								libsrc/leddevice/dev_net/LedDeviceAurora.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								libsrc/leddevice/dev_net/LedDeviceAurora.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| #pragma once | ||||
| // STL includes | ||||
| #include <string> | ||||
| #include <cmath> | ||||
| #include <fstream> | ||||
|  | ||||
| // Leddevice includes | ||||
| #include <leddevice/LedDevice.h> | ||||
| // Qt includes | ||||
| #include <QObject> | ||||
| #include <QString> | ||||
| #include <QNetworkAccessManager> | ||||
| #include <QTimer> | ||||
| /// | ||||
| /// 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 QJsonObject &deviceConfig); | ||||
|  | ||||
| 	/// | ||||
| 	/// Destructor of this test-device | ||||
| 	/// | ||||
| 	virtual ~LedDeviceAurora(); | ||||
|  | ||||
| 	/// Switch the leds off | ||||
| 	virtual int switchOff(); | ||||
| 	/// constructs leddevice | ||||
| 	static LedDevice* construct(const QJsonObject &deviceConfig); | ||||
| protected: | ||||
| 	/// | ||||
| 	/// Writes the RGB-Color values to the leds. | ||||
| 	/// | ||||
| 	/// @param[in] ledValues  The RGB-color per led | ||||
| 	/// | ||||
| 	/// @return Zero on success else negative | ||||
| 	/// | ||||
| 	virtual int write(const std::vector<ColorRgb> & ledValues); | ||||
|  | ||||
| 	bool init(const QJsonObject &deviceConfig); | ||||
|  | ||||
| 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<unsigned int> 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); | ||||
| }; | ||||
		Reference in New Issue
	
	Block a user