Hyperion.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. #pragma once
  2. // stl includes
  3. #include <list>
  4. // QT includes
  5. #include <QString>
  6. #include <QStringList>
  7. #include <QSize>
  8. #include <QJsonObject>
  9. #include <QJsonValue>
  10. #include <QJsonArray>
  11. #include <QMap>
  12. // hyperion-utils includes
  13. #include <utils/Image.h>
  14. #include <utils/ColorRgb.h>
  15. #include <utils/Components.h>
  16. #include <utils/VideoMode.h>
  17. // Hyperion includes
  18. #include <hyperion/LedString.h>
  19. #include <hyperion/PriorityMuxer.h>
  20. #include <hyperion/ColorAdjustment.h>
  21. #include <hyperion/ComponentRegister.h>
  22. #if defined(ENABLE_EFFECTENGINE)
  23. // Effect engine includes
  24. #include <effectengine/EffectDefinition.h>
  25. #include <effectengine/Effect.h>
  26. #include <effectengine/ActiveEffectDefinition.h>
  27. #include <effectengine/EffectSchema.h>
  28. #endif
  29. #include <leddevice/LedDevice.h>
  30. // settings utils
  31. #include <utils/settings.h>
  32. // Forward class declaration
  33. class HyperionDaemon;
  34. class ImageProcessor;
  35. #if defined(ENABLE_FORWARDER)
  36. class MessageForwarder;
  37. #endif
  38. class LinearColorSmoothing;
  39. #if defined(ENABLE_EFFECTENGINE)
  40. class EffectEngine;
  41. #endif
  42. class MultiColorAdjustment;
  43. class ColorAdjustment;
  44. class SettingsManager;
  45. class BGEffectHandler;
  46. class CaptureCont;
  47. #if defined(ENABLE_BOBLIGHT_SERVER)
  48. class BoblightServer;
  49. #endif
  50. class LedDeviceWrapper;
  51. class Logger;
  52. ///
  53. /// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
  54. /// the priority muxer.
  55. ///
  56. class Hyperion : public QObject
  57. {
  58. Q_OBJECT
  59. public:
  60. /// Type definition of the info structure used by the priority muxer
  61. using InputInfo = PriorityMuxer::InputInfo;
  62. ///
  63. /// Destructor; cleans up resources
  64. ///
  65. ~Hyperion() override;
  66. ///
  67. /// free all alocated objects, should be called only from constructor or before restarting hyperion
  68. ///
  69. void freeObjects();
  70. ImageProcessor* getImageProcessor() const { return _imageProcessor; }
  71. ///
  72. /// @brief Get instance index of this instance
  73. /// @return The index of this instance
  74. ///
  75. quint8 getInstanceIndex() const { return _instIndex; }
  76. ///
  77. /// @brief Return the size of led grid
  78. ///
  79. QSize getLedGridSize() const { return _ledGridSize; }
  80. /// gets the methode how image is maped to leds
  81. int getLedMappingType() const;
  82. /// forward smoothing config
  83. unsigned addSmoothingConfig(int settlingTime_ms, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
  84. unsigned updateSmoothingConfig(unsigned id, int settlingTime_ms=200, double ledUpdateFrequency_hz=25.0, unsigned updateDelay=0);
  85. VideoMode getCurrentVideoMode() const;
  86. ///
  87. /// @brief Get the current active led device
  88. /// @return The device name
  89. ///
  90. QString getActiveDeviceType() const;
  91. bool getReadOnlyMode() {return _readOnlyMode; }
  92. public slots:
  93. ///
  94. /// Updates the priority muxer with the current time and (re)writes the led color with applied
  95. /// transforms.
  96. ///
  97. void update();
  98. ///
  99. /// Returns the number of attached leds
  100. ///
  101. int getLedCount() const;
  102. ///
  103. /// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
  104. /// A repeated call to update the base data of a known priority won't overwrite their current timeout
  105. /// @param[in] priority The priority of the channel
  106. /// @param[in] component The component of the channel
  107. /// @param[in] origin Who set the channel (CustomString@IP)
  108. /// @param[in] owner Specific owner string, might be empty
  109. /// @param[in] smooth_cfg The smooth id to use
  110. ///
  111. void registerInput(int priority, hyperion::Components component, const QString& origin = "System", const QString& owner = "", unsigned smooth_cfg = 0);
  112. ///
  113. /// @brief Update the current color of a priority (prev registered with registerInput())
  114. /// DO NOT use this together with setInputImage() at the same time!
  115. /// @param priority The priority to update
  116. /// @param ledColors The colors
  117. /// @param timeout_ms The new timeout (defaults to -1 endless)
  118. /// @param clearEffect Should be true when NOT called from an effect
  119. /// @return True on success, false when priority is not found
  120. ///
  121. bool setInput(int priority, const std::vector<ColorRgb>& ledColors, int timeout_ms = PriorityMuxer::ENDLESS, bool clearEffect = true);
  122. ///
  123. /// @brief Update the current image of a priority (prev registered with registerInput())
  124. /// DO NOT use this together with setInput() at the same time!
  125. /// @param priority The priority to update
  126. /// @param image The new image
  127. /// @param timeout_ms The new timeout (defaults to -1 endless)
  128. /// @param clearEffect Should be true when NOT called from an effect
  129. /// @return True on success, false when priority is not found
  130. ///
  131. bool setInputImage(int priority, const Image<ColorRgb>& image, int64_t timeout_ms = PriorityMuxer::ENDLESS, bool clearEffect = true);
  132. ///
  133. /// Writes a single color to all the leds for the given time and priority
  134. /// Registers comp color or provided type against muxer
  135. /// Should be never used to update leds continuous
  136. ///
  137. /// @param[in] priority The priority of the written color
  138. /// @param[in] ledColors The color to write to the leds
  139. /// @param[in] timeout_ms The time the leds are set to the given color [ms]
  140. /// @param[in] origin The setter
  141. /// @param clearEffect Should be true when NOT called from an effect
  142. ///
  143. void setColor(int priority, const std::vector<ColorRgb> &ledColors, int timeout_ms = PriorityMuxer::ENDLESS, const QString& origin = "System" ,bool clearEffects = true);
  144. ///
  145. /// @brief Set the given priority to inactive
  146. /// @param priority The priority
  147. /// @return True on success false if not found
  148. ///
  149. bool setInputInactive(quint8 priority);
  150. ///
  151. /// Returns the list with unique adjustment identifiers
  152. /// @return The list with adjustment identifiers
  153. ///
  154. QStringList getAdjustmentIds() const;
  155. ///
  156. /// Returns the ColorAdjustment with the given identifier
  157. /// @return The adjustment with the given identifier (or nullptr if the identifier does not exist)
  158. ///
  159. ColorAdjustment * getAdjustment(const QString& id) const;
  160. /// Tell Hyperion that the corrections have changed and the leds need to be updated
  161. void adjustmentsUpdated();
  162. ///
  163. /// Clears the given priority channel. This will switch the led-colors to the colors of the next
  164. /// lower priority channel (or off if no more channels are set)
  165. ///
  166. /// @param[in] priority The priority channel. -1 clears all priorities
  167. /// @param[in] forceClearAll Force the clear
  168. /// @return True on success else false (not found)
  169. ///
  170. bool clear(int priority, bool forceClearAll=false);
  171. #if defined(ENABLE_EFFECTENGINE)
  172. /// #############
  173. /// EFFECTENGINE
  174. ///
  175. /// @brief Get a pointer to the effect engine
  176. /// @return EffectEngine instance pointer
  177. ///
  178. EffectEngine* getEffectEngineInstance() const { return _effectEngine; }
  179. ///
  180. /// @brief Save an effect
  181. /// @param obj The effect args
  182. /// @return Empty on success else error message
  183. ///
  184. QString saveEffect(const QJsonObject& obj);
  185. ///
  186. /// @brief Delete an effect by name.
  187. /// @param effectName The effect name to delete
  188. /// @return Empty on success else error message
  189. ///
  190. QString deleteEffect(const QString& effectName);
  191. /// Run the specified effect on the given priority channel and optionally specify a timeout
  192. /// @param effectName Name of the effec to run
  193. /// @param priority The priority channel of the effect
  194. /// @param timeout The timeout of the effect (after the timout, the effect will be cleared)
  195. int setEffect(const QString & effectName, int priority, int timeout = PriorityMuxer::ENDLESS, const QString & origin="System");
  196. /// Run the specified effect on the given priority channel and optionally specify a timeout
  197. /// @param effectName Name of the effec to run
  198. /// @param args arguments of the effect script
  199. /// @param priority The priority channel of the effect
  200. /// @param timeout The timeout of the effect (after the timout, the effect will be cleared)
  201. int setEffect(const QString &effectName
  202. , const QJsonObject &args
  203. , int priority
  204. , int timeout = PriorityMuxer::ENDLESS
  205. , const QString &pythonScript = ""
  206. , const QString &origin="System"
  207. , const QString &imageData = ""
  208. );
  209. /// Get the list of available effects
  210. /// @return The list of available effects
  211. std::list<EffectDefinition> getEffects() const;
  212. /// Get the list of active effects
  213. /// @return The list of active effects
  214. std::list<ActiveEffectDefinition> getActiveEffects() const;
  215. /// Get the list of available effect schema files
  216. /// @return The list of available effect schema files
  217. std::list<EffectSchema> getEffectSchemas() const;
  218. #endif
  219. /// #############
  220. /// PRIORITYMUXER
  221. ///
  222. /// @brief Get a pointer to the priorityMuxer instance
  223. /// @return PriorityMuxer instance pointer
  224. ///
  225. PriorityMuxer* getMuxerInstance() { return _muxer; }
  226. ///
  227. /// @brief enable/disable automatic/priorized source selection
  228. /// @param state The new state
  229. ///
  230. void setSourceAutoSelect(bool state);
  231. ///
  232. /// @brief set current input source to visible
  233. /// @param priority the priority channel which should be vidible
  234. /// @return true if success, false on error
  235. ///
  236. bool setVisiblePriority(int priority);
  237. /// gets current state of automatic/priorized source selection
  238. /// @return the state
  239. bool sourceAutoSelectEnabled() const;
  240. ///
  241. /// Returns the current priority
  242. ///
  243. /// @return The current priority
  244. ///
  245. int getCurrentPriority() const;
  246. ///
  247. /// Returns true if current priority is given priority
  248. ///
  249. /// @return bool
  250. ///
  251. bool isCurrentPriority(int priority) const;
  252. ///
  253. /// Returns a list of all registered priorities
  254. ///
  255. /// @return The list with priorities
  256. ///
  257. QList<int> getActivePriorities() const;
  258. ///
  259. /// Returns the information of a specific priorrity channel
  260. ///
  261. /// @param[in] priority The priority channel
  262. ///
  263. /// @return The information of the given, a not found priority will return lowest priority as fallback
  264. ///
  265. PriorityMuxer::InputInfo getPriorityInfo(int priority) const;
  266. /// #############
  267. /// SETTINGSMANAGER
  268. ///
  269. /// @brief Get a setting by settings::type from SettingsManager
  270. /// @param type The settingsType from enum
  271. /// @return Data Document
  272. ///
  273. QJsonDocument getSetting(settings::type type) const;
  274. /// gets the current json config object from SettingsManager
  275. /// @return json config
  276. QJsonObject getQJsonConfig() const;
  277. ///
  278. /// @brief Save a complete json config
  279. /// @param config The entire config object
  280. /// @param correct If true will correct json against schema before save
  281. /// @return True on success else false
  282. ///
  283. bool saveSettings(const QJsonObject& config, bool correct = false);
  284. ///
  285. /// @brief Restore a complete json config
  286. /// @param config The entire config object
  287. /// @param correct If true will correct json against schema before save
  288. /// @return True on success else false
  289. ///
  290. bool restoreSettings(const QJsonObject& config, bool correct = false);
  291. /// ############
  292. /// COMPONENTREGISTER
  293. ///
  294. /// @brief Get the component Register
  295. /// return Component register pointer
  296. ///
  297. ComponentRegister* getComponentRegister() { return _componentRegister; }
  298. ///
  299. /// @brief Called from components to update their current state. DO NOT CALL FROM USERS
  300. /// @param[in] component The component from enum
  301. /// @param[in] state The state of the component [true | false]
  302. ///
  303. void setNewComponentState(hyperion::Components component, bool state);
  304. ///
  305. /// @brief Get a list of all contrable components and their current state
  306. /// @return list of components
  307. ///
  308. std::map<hyperion::Components, bool> getAllComponents() const;
  309. ///
  310. /// @brief Test if a component is enabled
  311. /// @param The component to test
  312. /// @return Component state
  313. ///
  314. int isComponentEnabled(hyperion::Components comp) const;
  315. /// sets the methode how image is maped to leds at ImageProcessor
  316. void setLedMappingType(int mappingType);
  317. ///
  318. /// Set the video mode (2D/3D)
  319. /// @param[in] mode The new video mode
  320. ///
  321. void setVideoMode(VideoMode mode);
  322. ///
  323. /// @brief Init after thread start
  324. ///
  325. void start();
  326. ///
  327. /// @brief Stop the execution of this thread, helper to properly track eventing
  328. ///
  329. void stop();
  330. int getLatchTime() const;
  331. ///
  332. /// @brief Set hyperion in suspend mode or resume from suspend/idle.
  333. /// All instances and components will be disabled/enabled.
  334. /// @param isSupend True, components will be deactivated, else put into their previous state before suspend
  335. ///
  336. void setSuspend(bool isSupend);
  337. ///
  338. /// @brief Set hyperion in idle /working mode.
  339. /// In idle, all instances and components will be disabled besides the output processing (LED-Devices, smoothing).
  340. /// @param isIdle True, selected components will be deactivated, else put into their previous state before idle
  341. ///
  342. void setIdle(bool isIdle);
  343. signals:
  344. /// Signal which is emitted when a priority channel is actively cleared
  345. /// This signal will not be emitted when a priority channel time out
  346. void channelCleared(int priority);
  347. /// Signal which is emitted when all priority channels are actively cleared
  348. /// This signal will not be emitted when a priority channel time out
  349. void allChannelsCleared();
  350. ///
  351. /// @brief Emits whenever a user request a component state change, it's up the component to listen
  352. /// and update the component state at the componentRegister
  353. /// @param component The component from enum
  354. /// @param enabled The new state of the component
  355. ///
  356. void compStateChangeRequest(hyperion::Components component, bool enabled);
  357. ///
  358. /// @brief Emits when all (besides excluded) components are subject to state changes
  359. /// @param isActive The new state for all components
  360. /// @param execlude List of excluded components
  361. void compStateChangeRequestAll(bool isActive, const ComponentList& excludeList = {});
  362. /// Signal which is emitted, when system is to be suspended/resumed
  363. void suspendRequest(bool isSuspend);
  364. /// Signal which is emitted, when system should go into idle/working mode
  365. void idleRequest(bool isIdle);
  366. ///
  367. /// @brief Emits whenever the imageToLedsMapping has changed
  368. /// @param mappingType The new mapping type
  369. ///
  370. void imageToLedsMappingChanged(int mappingType);
  371. ///
  372. /// @brief Emits whenever the visible priority delivers a image which is applied in update()
  373. /// priorities with ledColors won't emit this signal
  374. /// @param image The current image
  375. ///
  376. void currentImage(const Image<ColorRgb> & image);
  377. /// Signal which is emitted, when a new json message should be forwarded
  378. void forwardJsonMessage(QJsonObject);
  379. /// Signal which is emitted, when a new system proto image should be forwarded
  380. void forwardSystemProtoMessage(const QString&, const Image<ColorRgb>&);
  381. /// Signal which is emitted, when a new V4l proto image should be forwarded
  382. void forwardV4lProtoMessage(const QString&, const Image<ColorRgb>&);
  383. /// Signal which is emitted, when a new Audio proto image should be forwarded
  384. void forwardAudioProtoMessage(const QString&, const Image<ColorRgb>&);
  385. #if defined(ENABLE_FLATBUF_SERVER) || defined(ENABLE_PROTOBUF_SERVER)
  386. /// Signal which is emitted, when a new Flat-/Proto- Buffer image should be forwarded
  387. void forwardBufferMessage(const QString&, const Image<ColorRgb>&);
  388. #endif
  389. ///
  390. /// @brief Is emitted from clients who request a videoMode change
  391. ///
  392. void videoMode(VideoMode mode);
  393. ///
  394. /// @brief A new videoMode was requested (called from Daemon!)
  395. ///
  396. void newVideoMode(VideoMode mode);
  397. ///
  398. /// @brief Emits whenever a config part changed. SIGNAL PIPE helper for SettingsManager -> HyperionDaemon
  399. /// @param type The settings type from enum
  400. /// @param data The data as QJsonDocument
  401. ///
  402. void settingsChanged(settings::type type, const QJsonDocument& data);
  403. ///
  404. /// @brief Emits whenever the adjustments have been updated
  405. ///
  406. void adjustmentChanged();
  407. #if defined(ENABLE_EFFECTENGINE)
  408. ///
  409. /// @brief Signal pipe from EffectEngine to external, emits when effect list has been updated
  410. ///
  411. void effectListUpdated();
  412. #endif
  413. ///
  414. /// @brief Emits whenever new data should be pushed to the LedDeviceWrapper which forwards it to the threaded LedDevice
  415. ///
  416. void ledDeviceData(const std::vector<ColorRgb>& ledValues);
  417. ///
  418. /// @brief Emits whenever new untransformed ledColos data is available, reflects the current visible device
  419. ///
  420. void rawLedColors(const std::vector<ColorRgb>& ledValues);
  421. ///
  422. /// @brief Emits before thread quit is requested
  423. ///
  424. void finished();
  425. ///
  426. /// @brief Emits after thread has been started
  427. ///
  428. void started();
  429. private slots:
  430. ///
  431. /// @brief Handle whenever the visible component changed
  432. /// @param comp The new component
  433. ///
  434. void handleVisibleComponentChanged(hyperion::Components comp);
  435. ///
  436. /// @brief Apply settings updates for LEDS and COLOR
  437. /// @param type The type from enum
  438. /// @param config The configuration
  439. ///
  440. void handleSettingsUpdate(settings::type type, const QJsonDocument& config);
  441. ///
  442. /// @brief Apply new videoMode from Daemon to _currVideoMode
  443. ///
  444. void handleNewVideoMode(VideoMode mode) { _currVideoMode = mode; }
  445. ///
  446. /// @brief Handle the scenario when no/an input source is available
  447. /// @param priority Current priority
  448. ///
  449. void handleSourceAvailability(int priority);
  450. private:
  451. friend class HyperionDaemon;
  452. friend class HyperionIManager;
  453. ///
  454. /// @brief Constructs the Hyperion instance, just accessible for HyperionIManager
  455. /// @param instance The instance index
  456. ///
  457. Hyperion(quint8 instance, bool readonlyMode = false);
  458. /// instance index
  459. const quint8 _instIndex;
  460. /// Settings manager of this instance
  461. SettingsManager* _settingsManager;
  462. /// Register that holds component states
  463. ComponentRegister* _componentRegister;
  464. /// The specifiation of the led frame construction and picture integration
  465. LedString _ledString;
  466. /// Image Processor
  467. ImageProcessor* _imageProcessor;
  468. std::vector<ColorOrder> _ledStringColorOrder;
  469. /// The priority muxer
  470. PriorityMuxer* _muxer;
  471. /// The adjustment from raw colors to led colors
  472. MultiColorAdjustment * _raw2ledAdjustment;
  473. /// The actual LedDeviceWrapper
  474. LedDeviceWrapper* _ledDeviceWrapper;
  475. /// The smoothing LedDevice
  476. LinearColorSmoothing * _deviceSmooth;
  477. #if defined(ENABLE_EFFECTENGINE)
  478. /// Effect engine
  479. EffectEngine * _effectEngine;
  480. #endif
  481. #if defined(ENABLE_FORWARDER)
  482. // Message forwarder
  483. MessageForwarder * _messageForwarder;
  484. #endif
  485. /// Logger instance
  486. Logger * _log;
  487. /// count of hardware leds
  488. int _hwLedCount;
  489. QSize _ledGridSize;
  490. /// Background effect instance, kept active to react on setting changes
  491. BGEffectHandler* _BGEffectHandler;
  492. /// Capture control for Daemon native capture
  493. CaptureCont* _captureCont;
  494. /// buffer for leds (with adjustment)
  495. std::vector<ColorRgb> _ledBuffer;
  496. VideoMode _currVideoMode = VideoMode::VIDEO_2D;
  497. #if defined(ENABLE_BOBLIGHT_SERVER)
  498. /// Boblight instance
  499. BoblightServer* _boblightServer;
  500. #endif
  501. bool _readOnlyMode;
  502. };