Usage
You need to first define a DeviceManager class object (device manager class), then call its enumerate() function to enumerate devices and obtain a device object list.
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto streamDocks = manager.getStreamDocks();
After obtaining the device object list, you need to call the wakeupScreen() method to wake up the device before using other methods to operate the device.
auto it = streamDocks.begin();
auto device = it->second;
device->wakeupScreen();
// Set brightness
device->setKeyBrightness(100);
Examples
Basic Example
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include "DeviceManager/devicemanager.h"
#include "HotspotDevice/StreamDockN4/streamdockN4.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main()
{
// Get device manager instance
DeviceManager &manager = DeviceManager::instance();
// Enumerate currently connected devices
manager.enumerator();
auto &streamDocks = manager.getStreamDocks();
std::cout << "Found " << streamDocks.size() << " devices" << std::endl;
if (streamDocks.empty()) {
std::cout << "No StreamDock devices found" << std::endl;
return 0;
}
// Start device listening thread, handle hot-plug
manager.listen([](std::shared_ptr<StreamDock> device) {
std::cout << "New device connected: " << device->info()->serialNumber << std::endl;
device->wakeupScreen();
device->setKeyBrightness(100);
});
// Handle connected devices
for (const auto &devicePair : streamDocks) {
auto device = devicePair.second;
// Wake up screen
device->wakeupScreen();
// Set image encoder
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// Set background image
device->setBackgroundImgFile("./img/background.jpg");
device->refresh();
// Set key images
device->setKeyImgFile("./img/key1.jpg", 1);
device->setKeyImgFile("./img/key2.jpg", 2);
device->refresh();
// Start read loop
device->reader()->startReadLoop();
// Register key event callbacks
device->reader()->registerReadCallback(1, []() {
std::cout << "Key 1 pressed" << std::endl;
}, RegisterEvent::KeyPress);
device->reader()->registerReadCallback(2, []() {
std::cout << "Key 2 pressed" << std::endl;
}, RegisterEvent::KeyPress);
}
std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();
// Stop listening
manager.stopListen();
return 0;
}
Multi-Device Support Example
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "HotspotDevice/StreamDockN4/streamdockN4.h"
#include "HotspotDevice/StreamDockM18/streamdockM18.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
void handleN4Device(std::shared_ptr<StreamDock> device) {
std::cout << "Handling N4 device" << std::endl;
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// N4-specific feature: Set secondary screen
device->setBackgroundImgFile("./img/n4_background.jpg");
device->refresh();
// Register knob events
device->reader()->registerReadCallback(16, []() {
std::cout << "Knob 1 turned left" << std::endl;
}, RegisterEvent::KnobLeft);
device->reader()->registerReadCallback(17, []() {
std::cout << "Knob 1 turned right" << std::endl;
}, RegisterEvent::KnobRight);
// Register touch screen swipe events
device->reader()->registerReadCallback(28, []() {
std::cout << "Touch screen swiped left" << std::endl;
}, RegisterEvent::SwipeLeft);
}
void handleM18Device(std::shared_ptr<StreamDock> device) {
std::cout << "Handling M18 device" << std::endl;
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// M18-specific feature: Set LED color
device->rgber()->setLedColor(255, 0, 0); // Red
device->rgber()->setLedBrightness(50);
// Set background animation
device->gifer()->setBackgroundGifFile("./img/background.gif");
device->gifer()->startGifLoop();
}
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
// Handle different device types
for (const auto &devicePair : devices) {
auto device = devicePair.second;
device->reader()->startReadLoop();
switch (device->info()->originType) {
case DeviceOriginType::SDN4:
handleN4Device(device);
break;
case DeviceOriginType::SDM18:
handleM18Device(device);
break;
default:
std::cout << "Unknown device type" << std::endl;
break;
}
}
std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();
return 0;
}
GIF Animation Example
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
for (const auto &devicePair : devices) {
auto device = devicePair.second;
// Check if device supports GIF
if (!device->feature()->isDualDevice) {
std::cout << "Device does not support GIF functionality" << std::endl;
continue;
}
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// Set key GIF animations
device->gifer()->setKeyGifFile("./img/animation1.gif", 1);
device->gifer()->setKeyGifFile("./img/animation2.gif", 2);
device->gifer()->setKeyGifFile("./img/animation3.gif", 3);
// Set background GIF animation (if supported)
if (device->feature()->supportBackGroundGif) {
device->gifer()->setBackgroundGifFile("./img/background.gif");
}
// Start GIF loop
device->gifer()->startGifLoop();
std::cout << "GIF animation started" << std::endl;
}
std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();
return 0;
}
Error Handling Example
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main() {
try {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
if (devices.empty()) {
std::cout << "No devices found, please check:" << std::endl;
std::cout << "1. Whether the device is properly connected" << std::endl;
std::cout << "2. Whether you have sufficient permissions to access the device" << std::endl;
std::cout << "3. Whether udev rules are correctly configured" << std::endl;
return 1;
}
for (const auto &devicePair : devices) {
auto device = devicePair.second;
try {
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// Try to set image
device->setBackgroundImgFile("./img/background.jpg");
// Check for errors
std::wstring error = device->lastError();
if (!error.empty()) {
std::wcout << L"Device error: " << error << std::endl;
continue;
}
device->refresh();
std::cout << "Device initialization successful" << std::endl;
} catch (const std::exception &e) {
std::cout << "Device operation failed: " << e.what() << std::endl;
}
}
} catch (const std::exception &e) {
std::cout << "Program exception: " << e.what() << std::endl;
return 1;
}
std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();
return 0;
}
Device Hot-plug Listening
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
int main() {
DeviceManager &manager = DeviceManager::instance();
// Start device listening
manager.listen([](std::shared_ptr<StreamDock> device) {
std::cout << "Device connected: " << device->info()->serialNumber << std::endl;
std::cout << "Device type: " << static_cast<int>(device->info()->originType) << std::endl;
// Automatically initialize newly connected devices
device->wakeupScreen();
device->setKeyBrightness(80);
});
std::cout << "Device listening started, you can plug/unplug devices for testing" << std::endl;
std::cout << "Press Enter to exit..." << std::endl;
std::cin.get();
manager.stopListen();
return 0;
}
Multi-threading
#include <iostream>
#include <memory>
#include <thread>
#include <atomic>
#include "DeviceManager/devicemanager.h"
std::atomic<bool> running(true);
void deviceReadThread(std::shared_ptr<StreamDock> device) {
uint8_t response[64];
size_t length;
while (running) {
try {
device->reader()->read(response, &length, 100);
if (length > 0) {
std::cout << "Received data: ";
for (size_t i = 0; i < length; i++) {
printf("%02X ", response[i]);
}
std::cout << std::endl;
}
} catch (const std::exception &e) {
std::cout << "Read thread exception: " << e.what() << std::endl;
break;
}
}
}
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
if (devices.empty()) {
std::cout << "No devices found" << std::endl;
return 0;
}
// Create read thread for each device
std::vector<std::thread> readThreads;
for (const auto &devicePair : devices) {
auto device = devicePair.second;
device->wakeupScreen();
// Create read thread
readThreads.emplace_back(deviceReadThread, device);
}
std::cout << "Multi-threading started, press Enter to exit..." << std::endl;
std::cin.get();
running = false;
// Wait for all threads to finish
for (auto &thread : readThreads) {
if (thread.joinable()) {
thread.join();
}
}
return 0;
}
