You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

210 lines
7.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}