|
|
#include "FaceLightClient.h"
|
|
|
#include <iostream>
|
|
|
#include <string>
|
|
|
#include <vector>
|
|
|
#include <map>
|
|
|
#include <sstream>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
void printUsage(const char* programName) {
|
|
|
std::cout << "Usage: " << programName << " [OPTIONS]\n";
|
|
|
std::cout << "\nOptions:\n";
|
|
|
std::cout << " -m, --mode MODE Control mode: all|single|cycle|custom|pattern\n";
|
|
|
std::cout << " -c, --color COLOR Color: red|green|blue|yellow|white|black\n";
|
|
|
std::cout << " -i, --index INDEX LED index (0-11) for single mode\n";
|
|
|
std::cout << " -d, --delay DELAY Delay in milliseconds (default: 2000)\n";
|
|
|
std::cout << " -p, --pattern PATTERN Custom pattern: \"0:red,1:green,2:blue\"\n";
|
|
|
std::cout << " -t, --times TIMES Number of cycles for cycle mode (default: infinite)\n";
|
|
|
std::cout << " -h, --help Show this help message\n";
|
|
|
std::cout << "\nExamples:\n";
|
|
|
std::cout << " " << programName << " -m all -c red # All LEDs red\n";
|
|
|
std::cout << " " << programName << " -m single -i 0 -c blue # LED 0 blue\n";
|
|
|
std::cout << " " << programName << " -m cycle -d 1000 -t 5 # Color cycle 5 times\n";
|
|
|
std::cout << " " << programName << " -m pattern -p \"0:red,5:green\" # Custom pattern\n";
|
|
|
}
|
|
|
|
|
|
std::map<std::string, const uint8_t*> getColorMap(FaceLightClient& client) {
|
|
|
std::map<std::string, const uint8_t*> colors;
|
|
|
colors["red"] = client.red;
|
|
|
colors["green"] = client.green;
|
|
|
colors["blue"] = client.blue;
|
|
|
colors["yellow"] = client.yellow;
|
|
|
colors["white"] = client.white;
|
|
|
colors["black"] = client.black;
|
|
|
return colors;
|
|
|
}
|
|
|
|
|
|
bool parsePattern(const std::string& pattern, std::vector<std::pair<int, std::string>>& ledPattern) {
|
|
|
std::stringstream ss(pattern);
|
|
|
std::string token;
|
|
|
|
|
|
while (std::getline(ss, token, ',')) {
|
|
|
size_t colonPos = token.find(':');
|
|
|
if (colonPos == std::string::npos) {
|
|
|
std::cerr << "Error: Invalid pattern format. Use INDEX:COLOR\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
int index = std::stoi(token.substr(0, colonPos));
|
|
|
std::string color = token.substr(colonPos + 1);
|
|
|
|
|
|
if (index < 0 || index > 11) {
|
|
|
std::cerr << "Error: LED index must be 0-11\n";
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
ledPattern.push_back({index, color});
|
|
|
} catch (const std::exception& e) {
|
|
|
std::cerr << "Error: Invalid pattern format\n";
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
FaceLightClient client;
|
|
|
auto colors = getColorMap(client);
|
|
|
|
|
|
// 默认参数
|
|
|
std::string mode = "all";
|
|
|
std::string color = "red";
|
|
|
int ledIndex = 0;
|
|
|
int delay = 2000;
|
|
|
std::string pattern = "";
|
|
|
int cycles = -1; // -1 表示无限循环
|
|
|
|
|
|
// 解析命令行参数
|
|
|
for (int i = 1; i < argc; i++) {
|
|
|
std::string arg = argv[i];
|
|
|
|
|
|
if (arg == "-h" || arg == "--help") {
|
|
|
printUsage(argv[0]);
|
|
|
return 0;
|
|
|
} else if ((arg == "-m" || arg == "--mode") && i + 1 < argc) {
|
|
|
mode = argv[++i];
|
|
|
} else if ((arg == "-c" || arg == "--color") && i + 1 < argc) {
|
|
|
color = argv[++i];
|
|
|
} else if ((arg == "-i" || arg == "--index") && i + 1 < argc) {
|
|
|
ledIndex = std::atoi(argv[++i]);
|
|
|
} else if ((arg == "-d" || arg == "--delay") && i + 1 < argc) {
|
|
|
delay = std::atoi(argv[++i]);
|
|
|
} else if ((arg == "-p" || arg == "--pattern") && i + 1 < argc) {
|
|
|
pattern = argv[++i];
|
|
|
} else if ((arg == "-t" || arg == "--times") && i + 1 < argc) {
|
|
|
cycles = std::atoi(argv[++i]);
|
|
|
} else {
|
|
|
std::cerr << "Error: Unknown argument " << arg << std::endl;
|
|
|
printUsage(argv[0]);
|
|
|
return 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 验证参数
|
|
|
if (colors.find(color) == colors.end()) {
|
|
|
std::cerr << "Error: Invalid color. Available: red, green, blue, yellow, white, black\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
if (ledIndex < 0 || ledIndex > 11) {
|
|
|
std::cerr << "Error: LED index must be 0-11\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
if (delay < 0) {
|
|
|
std::cerr << "Error: Delay must be non-negative\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
std::cout << "FaceLight Controller Starting...\n";
|
|
|
std::cout << "Mode: " << mode << ", Color: " << color << ", Delay: " << delay << "ms\n";
|
|
|
|
|
|
// 执行控制逻辑
|
|
|
if (mode == "all") {
|
|
|
// 全部LED使用同一颜色
|
|
|
std::cout << "Setting all LEDs to " << color << std::endl;
|
|
|
client.setAllLed(colors[color]);
|
|
|
client.sendCmd();
|
|
|
|
|
|
} else if (mode == "single") {
|
|
|
// 单个LED控制
|
|
|
std::cout << "Setting LED " << ledIndex << " to " << color << std::endl;
|
|
|
client.setAllLed(client.black); // 先关闭所有LED
|
|
|
client.setLedColor(ledIndex, colors[color]);
|
|
|
client.sendCmd();
|
|
|
|
|
|
} else if (mode == "cycle") {
|
|
|
// 颜色循环
|
|
|
std::cout << "Starting color cycle..." << std::endl;
|
|
|
std::vector<std::string> cycleColors = {"red", "green", "blue", "yellow", "white"};
|
|
|
|
|
|
int count = 0;
|
|
|
while (cycles == -1 || count < cycles) {
|
|
|
for (const auto& cycleColor : cycleColors) {
|
|
|
std::cout << "Cycle " << (count + 1) << ": " << cycleColor << std::endl;
|
|
|
client.setAllLed(colors[cycleColor]);
|
|
|
client.sendCmd();
|
|
|
usleep(delay * 1000); // 转换为微秒
|
|
|
}
|
|
|
if (cycles != -1) count++;
|
|
|
}
|
|
|
|
|
|
} else if (mode == "pattern") {
|
|
|
// 自定义模式
|
|
|
if (pattern.empty()) {
|
|
|
std::cerr << "Error: Pattern mode requires -p option\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
std::vector<std::pair<int, std::string>> ledPattern;
|
|
|
if (!parsePattern(pattern, ledPattern)) {
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
std::cout << "Applying custom pattern..." << std::endl;
|
|
|
client.setAllLed(client.black); // 先关闭所有LED
|
|
|
|
|
|
for (const auto& led : ledPattern) {
|
|
|
int index = led.first;
|
|
|
const std::string& ledColor = led.second;
|
|
|
|
|
|
if (colors.find(ledColor) == colors.end()) {
|
|
|
std::cerr << "Error: Invalid color in pattern: " << ledColor << std::endl;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
std::cout << "Setting LED " << index << " to " << ledColor << std::endl;
|
|
|
client.setLedColor(index, colors[ledColor]);
|
|
|
}
|
|
|
client.sendCmd();
|
|
|
|
|
|
} else if (mode == "custom") {
|
|
|
// 原始自定义模式(RGB交替)
|
|
|
std::cout << "Applying RGB alternating pattern..." << std::endl;
|
|
|
for (int i = 0; i < 12; ++i) {
|
|
|
switch (i % 3) {
|
|
|
case 0:
|
|
|
client.setLedColor(i, client.red);
|
|
|
break;
|
|
|
case 1:
|
|
|
client.setLedColor(i, client.green);
|
|
|
break;
|
|
|
case 2:
|
|
|
client.setLedColor(i, client.blue);
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
client.sendCmd();
|
|
|
|
|
|
} else {
|
|
|
std::cerr << "Error: Invalid mode. Available: all, single, cycle, custom, pattern\n";
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
std::cout << "Command executed successfully!\n";
|
|
|
return 0;
|
|
|
}
|