diff --git a/projects/llm_framework/main_ax650_ec_proxy/Kconfig b/projects/llm_framework/main_ax650_ec_proxy/Kconfig new file mode 100644 index 0000000..e69de29 diff --git a/projects/llm_framework/main_ax650_ec_proxy/SConstruct b/projects/llm_framework/main_ax650_ec_proxy/SConstruct new file mode 100644 index 0000000..1a908a3 --- /dev/null +++ b/projects/llm_framework/main_ax650_ec_proxy/SConstruct @@ -0,0 +1,58 @@ +import os + +Import('env') +with open(env['PROJECT_TOOL_S']) as f: + exec(f.read()) + +if "CONFIG_AX_650C_MSP_ENABLED" not in os.environ: + Return('env') + +SRCS = [] +INCLUDE = [] +PRIVATE_INCLUDE = [] +REQUIREMENTS = ['pthread', 'utilities', 'eventpp', 'StackFlow', 'modbus_component', 'fmt'] +STATIC_LIB = [] +DYNAMIC_LIB = [] +DEFINITIONS = [] +DEFINITIONS_PRIVATE = [] +LDFLAGS = [] +LINK_SEARCH_PATH = [] +STATIC_FILES = [] + +LINK_SEARCH_PATH += [ADir('../static_lib')] + +LDFLAGS+=['-Wl,-rpath=/opt/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib', '-Wl,-rpath=/usr/local/m5stack/lib/gcc-10.3', '-Wl,-rpath=/opt/lib', '-Wl,-rpath=/opt/usr/lib', '-Wl,-rpath=./'] + +STATIC_FILES += [] + + +SRCS = [AFile('src/ec_proxy_main.cpp')] +env['COMPONENTS'].append({'target':'ax650_ec_proxy-1.0', + 'SRCS':SRCS, + 'INCLUDE':INCLUDE, + 'PRIVATE_INCLUDE':PRIVATE_INCLUDE, + 'REQUIREMENTS':REQUIREMENTS, + 'STATIC_LIB':STATIC_LIB, + 'DYNAMIC_LIB':DYNAMIC_LIB, + 'DEFINITIONS':DEFINITIONS, + 'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE, + 'LDFLAGS':LDFLAGS, + 'LINK_SEARCH_PATH':LINK_SEARCH_PATH, + 'STATIC_FILES':STATIC_FILES, + 'REGISTER':'project' + }) +SRCS = [AFile('src/ec_cli_main.cpp')] +env['COMPONENTS'].append({'target':'ax650_ec_cli-1.0', + 'SRCS':SRCS, + 'INCLUDE':INCLUDE, + 'PRIVATE_INCLUDE':PRIVATE_INCLUDE, + 'REQUIREMENTS':REQUIREMENTS, + 'STATIC_LIB':STATIC_LIB, + 'DYNAMIC_LIB':DYNAMIC_LIB, + 'DEFINITIONS':DEFINITIONS, + 'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE, + 'LDFLAGS':LDFLAGS, + 'LINK_SEARCH_PATH':LINK_SEARCH_PATH, + 'STATIC_FILES':STATIC_FILES, + 'REGISTER':'project' + }) diff --git a/projects/llm_framework/main_ax650_ec_proxy/src/cmdline.hpp b/projects/llm_framework/main_ax650_ec_proxy/src/cmdline.hpp new file mode 100644 index 0000000..ea8b59e --- /dev/null +++ b/projects/llm_framework/main_ax650_ec_proxy/src/cmdline.hpp @@ -0,0 +1,732 @@ +/* + Copyright (c) 2009, Hideyuki Tanaka + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace cmdline { + +namespace detail { + +template +class lexical_cast_t { + public: + static Target cast(const Source &arg) { + Target ret; + std::stringstream ss; + if (!(ss << arg && ss >> ret && ss.eof())) throw std::bad_cast(); + + return ret; + } +}; + +template +class lexical_cast_t { + public: + static Target cast(const Source &arg) { return arg; } +}; + +template +class lexical_cast_t { + public: + static std::string cast(const Source &arg) { + std::ostringstream ss; + ss << arg; + return ss.str(); + } +}; + +template +class lexical_cast_t { + public: + static Target cast(const std::string &arg) { + Target ret; + std::istringstream ss(arg); + if (!(ss >> ret && ss.eof())) throw std::bad_cast(); + return ret; + } +}; + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +template +Target lexical_cast(const Source &arg) { + return lexical_cast_t::value>::cast(arg); +} + +static inline std::string demangle(const std::string &name) { + int status = 0; + char *p = abi::__cxa_demangle(name.c_str(), 0, 0, &status); + std::string ret(p); + free(p); + return ret; +} + +template +std::string readable_typename() { + return demangle(typeid(T).name()); +} + +template +std::string default_value(T def) { + return detail::lexical_cast(def); +} + +template <> +inline std::string readable_typename() { + return "string"; +} + +} // namespace detail + +//----- + +class cmdline_error : public std::exception { + public: + cmdline_error(const std::string &msg) : msg(msg) {} + ~cmdline_error() throw() {} + const char *what() const throw() { return msg.c_str(); } + + private: + std::string msg; +}; + +template +struct default_reader { + T operator()(const std::string &str) { return detail::lexical_cast(str); } +}; + +template +struct range_reader { + range_reader(const T &low, const T &high) : low(low), high(high) {} + T operator()(const std::string &s) const { + T ret = default_reader()(s); + if (!(ret >= low && ret <= high)) + throw cmdline::cmdline_error("range_error"); + return ret; + } + + private: + T low, high; +}; + +template +range_reader range(const T &low, const T &high) { + return range_reader(low, high); +} + +template +struct oneof_reader { + T operator()(const std::string &s) { + T ret = default_reader()(s); + if (std::find(alt.begin(), alt.end(), ret) == alt.end()) + throw cmdline_error(""); + return ret; + } + void add(const T &v) { alt.push_back(v); } + + private: + std::vector alt; +}; + +template +oneof_reader oneof(T a1) { + oneof_reader ret; + ret.add(a1); + return ret; +} + +template +oneof_reader oneof(T a1, T a2) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + ret.add(a6); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + ret.add(a6); + ret.add(a7); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + ret.add(a6); + ret.add(a7); + ret.add(a8); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + ret.add(a6); + ret.add(a7); + ret.add(a8); + ret.add(a9); + return ret; +} + +template +oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, + T a10) { + oneof_reader ret; + ret.add(a1); + ret.add(a2); + ret.add(a3); + ret.add(a4); + ret.add(a5); + ret.add(a6); + ret.add(a7); + ret.add(a8); + ret.add(a9); + ret.add(a10); + return ret; +} + +//----- + +class parser { + public: + parser() {} + ~parser() { + for (std::map::iterator p = options.begin(); + p != options.end(); p++) + delete p->second; + } + + void add(const std::string &name, char short_name = 0, + const std::string &desc = "") { + if (options.count(name)) + throw cmdline_error("multiple definition: " + name); + options[name] = new option_without_value(name, short_name, desc); + ordered.push_back(options[name]); + } + + template + void add(const std::string &name, char short_name = 0, + const std::string &desc = "", bool need = true, const T def = T()) { + add(name, short_name, desc, need, def, default_reader()); + } + + template + void add(const std::string &name, char short_name = 0, + const std::string &desc = "", bool need = true, const T def = T(), + F reader = F()) { + if (options.count(name)) + throw cmdline_error("multiple definition: " + name); + options[name] = new option_with_value_with_reader( + name, short_name, need, def, desc, reader); + ordered.push_back(options[name]); + } + + void footer(const std::string &f) { ftr = f; } + + void set_program_name(const std::string &name) { prog_name = name; } + + bool exist(const std::string &name) const { + if (options.count(name) == 0) + throw cmdline_error("there is no flag: --" + name); + return options.find(name)->second->has_set(); + } + + template + const T &get(const std::string &name) const { + if (options.count(name) == 0) + throw cmdline_error("there is no flag: --" + name); + const option_with_value *p = + dynamic_cast *>(options.find(name)->second); + if (p == NULL) throw cmdline_error("type mismatch flag '" + name + "'"); + return p->get(); + } + + const std::vector &rest() const { return others; } + + bool parse(const std::string &arg) { + std::vector args; + + std::string buf; + bool in_quote = false; + for (std::string::size_type i = 0; i < arg.length(); i++) { + if (arg[i] == '\"') { + in_quote = !in_quote; + continue; + } + + if (arg[i] == ' ' && !in_quote) { + args.push_back(buf); + buf = ""; + continue; + } + + if (arg[i] == '\\') { + i++; + if (i >= arg.length()) { + errors.push_back("unexpected occurrence of '\\' at end of string"); + return false; + } + } + + buf += arg[i]; + } + + if (in_quote) { + errors.push_back("quote is not closed"); + return false; + } + + if (buf.length() > 0) args.push_back(buf); + + for (size_t i = 0; i < args.size(); i++) + std::cout << "\"" << args[i] << "\"" << std::endl; + + return parse(args); + } + + bool parse(const std::vector &args) { + int argc = static_cast(args.size()); + std::vector argv(argc); + + for (int i = 0; i < argc; i++) argv[i] = args[i].c_str(); + + return parse(argc, &argv[0]); + } + + bool parse(int argc, const char *const argv[]) { + errors.clear(); + others.clear(); + + if (argc < 1) { + errors.push_back("argument number must be longer than 0"); + return false; + } + if (prog_name == "") prog_name = argv[0]; + + std::map lookup; + for (std::map::iterator p = options.begin(); + p != options.end(); p++) { + if (p->first.length() == 0) continue; + char initial = p->second->short_name(); + if (initial) { + if (lookup.count(initial) > 0) { + lookup[initial] = ""; + errors.push_back(std::string("short option '") + initial + + "' is ambiguous"); + return false; + } else + lookup[initial] = p->first; + } + } + + for (int i = 1; i < argc; i++) { + if (strncmp(argv[i], "--", 2) == 0) { + const char *p = strchr(argv[i] + 2, '='); + if (p) { + std::string name(argv[i] + 2, p); + std::string val(p + 1); + set_option(name, val); + } else { + std::string name(argv[i] + 2); + if (options.count(name) == 0) { + errors.push_back("undefined option: --" + name); + continue; + } + if (options[name]->has_value()) { + if (i + 1 >= argc) { + errors.push_back("option needs value: --" + name); + continue; + } else { + i++; + set_option(name, argv[i]); + } + } else { + set_option(name); + } + } + } else if (strncmp(argv[i], "-", 1) == 0) { + if (!argv[i][1]) continue; + char last = argv[i][1]; + for (int j = 2; argv[i][j]; j++) { + last = argv[i][j]; + if (lookup.count(argv[i][j - 1]) == 0) { + errors.push_back(std::string("undefined short option: -") + + argv[i][j - 1]); + continue; + } + if (lookup[argv[i][j - 1]] == "") { + errors.push_back(std::string("ambiguous short option: -") + + argv[i][j - 1]); + continue; + } + set_option(lookup[argv[i][j - 1]]); + } + + if (lookup.count(last) == 0) { + errors.push_back(std::string("undefined short option: -") + last); + continue; + } + if (lookup[last] == "") { + errors.push_back(std::string("ambiguous short option: -") + last); + continue; + } + + if (i + 1 < argc && options[lookup[last]]->has_value()) { + set_option(lookup[last], argv[i + 1]); + i++; + } else { + set_option(lookup[last]); + } + } else { + others.push_back(argv[i]); + } + } + + for (std::map::iterator p = options.begin(); + p != options.end(); p++) + if (!p->second->valid()) + errors.push_back("need option: --" + std::string(p->first)); + + return errors.size() == 0; + } + + void parse_check(const std::string &arg) { + if (!options.count("help")) add("help", '?', "print this message"); + check(0, parse(arg)); + } + + void parse_check(const std::vector &args) { + if (!options.count("help")) add("help", '?', "print this message"); + check(args.size(), parse(args)); + } + + void parse_check(int argc, char *argv[]) { + if (!options.count("help")) add("help", '?', "print this message"); + check(argc, parse(argc, argv)); + } + + std::string error() const { return errors.size() > 0 ? errors[0] : ""; } + + std::string error_full() const { + std::ostringstream oss; + for (size_t i = 0; i < errors.size(); i++) oss << errors[i] << std::endl; + return oss.str(); + } + + std::string usage() const { + std::ostringstream oss; + oss << "usage: " << prog_name << " "; + for (size_t i = 0; i < ordered.size(); i++) { + if (ordered[i]->must()) oss << ordered[i]->short_description() << " "; + } + + oss << "[options] ... " << ftr << std::endl; + oss << "options:" << std::endl; + + size_t max_width = 0; + for (size_t i = 0; i < ordered.size(); i++) { + max_width = std::max(max_width, ordered[i]->name().length()); + } + for (size_t i = 0; i < ordered.size(); i++) { + if (ordered[i]->short_name()) { + oss << " -" << ordered[i]->short_name() << ", "; + } else { + oss << " "; + } + + oss << "--" << ordered[i]->name(); + for (size_t j = ordered[i]->name().length(); j < max_width + 4; j++) + oss << ' '; + oss << ordered[i]->description() << std::endl; + } + return oss.str(); + } + + private: + void check(int argc, bool ok) { + if ((argc == 1 && !ok) || exist("help")) { + std::cerr << usage(); + exit(0); + } + + if (!ok) { + std::cerr << error() << std::endl << usage(); + exit(1); + } + } + + void set_option(const std::string &name) { + if (options.count(name) == 0) { + errors.push_back("undefined option: --" + name); + return; + } + if (!options[name]->set()) { + errors.push_back("option needs value: --" + name); + return; + } + } + + void set_option(const std::string &name, const std::string &value) { + if (options.count(name) == 0) { + errors.push_back("undefined option: --" + name); + return; + } + if (!options[name]->set(value)) { + errors.push_back("option value is invalid: --" + name + "=" + value); + return; + } + } + + class option_base { + public: + virtual ~option_base() {} + + virtual bool has_value() const = 0; + virtual bool set() = 0; + virtual bool set(const std::string &value) = 0; + virtual bool has_set() const = 0; + virtual bool valid() const = 0; + virtual bool must() const = 0; + + virtual const std::string &name() const = 0; + virtual char short_name() const = 0; + virtual const std::string &description() const = 0; + virtual std::string short_description() const = 0; + }; + + class option_without_value : public option_base { + public: + option_without_value(const std::string &name, char short_name, + const std::string &desc) + : nam(name), snam(short_name), desc(desc), has(false) {} + ~option_without_value() {} + + bool has_value() const { return false; } + + bool set() { + has = true; + return true; + } + + bool set(const std::string &) { return false; } + + bool has_set() const { return has; } + + bool valid() const { return true; } + + bool must() const { return false; } + + const std::string &name() const { return nam; } + + char short_name() const { return snam; } + + const std::string &description() const { return desc; } + + std::string short_description() const { return "--" + nam; } + + private: + std::string nam; + char snam; + std::string desc; + bool has; + }; + + template + class option_with_value : public option_base { + public: + option_with_value(const std::string &name, char short_name, bool need, + const T &def, const std::string &desc) + : nam(name), + snam(short_name), + need(need), + has(false), + def(def), + actual(def) { + this->desc = full_description(desc); + } + ~option_with_value() {} + + const T &get() const { return actual; } + + bool has_value() const { return true; } + + bool set() { return false; } + + bool set(const std::string &value) { + try { + actual = read(value); + has = true; + } catch (const std::exception &e) { + return false; + } + return true; + } + + bool has_set() const { return has; } + + bool valid() const { + if (need && !has) return false; + return true; + } + + bool must() const { return need; } + + const std::string &name() const { return nam; } + + char short_name() const { return snam; } + + const std::string &description() const { return desc; } + + std::string short_description() const { + return "--" + nam + "=" + detail::readable_typename(); + } + + protected: + std::string full_description(const std::string &desc) { + return desc + " (" + detail::readable_typename() + + (need ? "" : " [=" + detail::default_value(def) + "]") + ")"; + } + + virtual T read(const std::string &s) = 0; + + std::string nam; + char snam; + bool need; + std::string desc; + + bool has; + T def; + T actual; + }; + + template + class option_with_value_with_reader : public option_with_value { + public: + option_with_value_with_reader(const std::string &name, char short_name, + bool need, const T def, + const std::string &desc, F reader) + : option_with_value(name, short_name, need, def, desc), + reader(reader) {} + + private: + T read(const std::string &s) { return reader(s); } + + F reader; + }; + + std::map options; + std::vector ordered; + std::string ftr; + + std::string prog_name; + std::vector others; + + std::vector errors; +}; + +} // namespace cmdline diff --git a/projects/llm_framework/main_ax650_ec_proxy/src/ec_cli_main.cpp b/projects/llm_framework/main_ax650_ec_proxy/src/ec_cli_main.cpp new file mode 100644 index 0000000..1e47073 --- /dev/null +++ b/projects/llm_framework/main_ax650_ec_proxy/src/ec_cli_main.cpp @@ -0,0 +1,317 @@ +#include +#include +#include "pzmq.hpp" +#include "cmdline.hpp" +#include <../../static_lib/include/fmt/core.h> +#include <../../static_lib/include/fmt/format.h> +#include +#include +#include +#include "json.hpp" +int condition = 1; +const char *rpc_socket_path; +const char *pub_socket_path; + +void info_fun(cmdline::parser &a, std::string set_fun, std::string get_fun) +{ + if (a.exist("data") || a.exist("DataRaw")) { + if (set_fun.length() == 0) return; + std::string DataRaw = a.get("DataRaw"); + if (DataRaw.empty()) { + DataRaw = fmt::format("{{ \"data\": {} }}", a.get("data")); + } + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action(set_fun, DataRaw, + [set_fun](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call " << set_fun << " faile!" << std::endl; + } + }); + } else { + if (get_fun.length() == 0) { + std::cout << "please set data: -d or -D" << std::endl; + return; + } + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action(get_fun, "{}", + [get_fun](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call " << get_fun << " faile! " << std::endl; + } + }); + } +} + +void get_info_fun(cmdline::parser &a, std::string fun) +{ + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action(fun, "{\"data\":\"None\"}", + [fun](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call " << fun << " faile!" << std::endl; + } + }); +} + +void set_info_fun(cmdline::parser &a, std::string fun) +{ + if (a.exist("data") || a.exist("DataRaw")) { + std::string DataRaw = a.get("DataRaw"); + if (DataRaw.empty()) { + DataRaw = fmt::format("{{ \"data\": {} }}", a.get("data")); + } + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action(fun, DataRaw, + [fun](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call " << fun << "faile!" << std::endl; + } + }); + } +} + +void fan_speed_fun(cmdline::parser &a) +{ + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action("fan_get_speed", "{}", + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call fan_get_speed faile!" << std::endl; + } + }); +} + +void fan_pwm_fun(cmdline::parser &a) +{ + if (a.exist("data") || a.exist("DataRaw")) { + std::string DataRaw = a.get("DataRaw"); + if (DataRaw.empty()) { + DataRaw = fmt::format("{{ \"data\": {} }}", a.get("data")); + } + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action("fan_set_pwm", DataRaw, + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call fan_set_pwm faile!" << std::endl; + } + }); + } else { + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action("fan_get_pwm", "{}", + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call fan_get_pwm faile!" << std::endl; + } + }); + } +} + +void rgb_fun(cmdline::parser &a) +{ + if (a.exist("data") || a.exist("DataRaw")) { + std::string DataRaw = a.get("DataRaw"); + if (DataRaw.empty()) { + DataRaw = fmt::format("{{ \"data\": {} }}", a.get("data")); + } + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action("rgb_set_mode", DataRaw, + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call rgb_set_mode faile!" << std::endl; + } + }); + } else { + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action("rgb_get_mode", "{}", + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << data->string() << std::endl; + } else { + std::cout << "call rgb_get_mode faile!" << std::endl; + } + }); + } +} + +void exec_fun(cmdline::parser &a) +{ + if (a.exist("list")) { + StackFlows::pzmq Context(rpc_socket_path); + std::cout << "list" << std::endl; + Context.call_rpc_action("list_action", "None", + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + try { + nlohmann::json _data = nlohmann::json::parse(data->string()); + std::cout << _data.dump(4) << std::endl; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + } + } else { + std::cout << "call list_action faile!" << std::endl; + } + }); + return; + } + + const std::string fun = a.get("fun"); + const std::string data = a.get("data"); + if (fun.length() == 0) { + std::cout << "fun is empty! cli exec -f -d " << std::endl; + return; + } + + StackFlows::pzmq Context(rpc_socket_path); + Context.call_rpc_action(fun, data, [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + if (data->size() > 0) { + std::cout << "" << data->string() << std::endl; + } else { + std::cout << "call ax650_ec_prox faile!" << std::endl; + } + }); +} + +void echo_fun(cmdline::parser &a) +{ + if (a.exist("button")) { + StackFlows::pzmq Context(pub_socket_path, ZMQ_SUB, + [](StackFlows::pzmq *_pzmq, const std::shared_ptr &data) { + std::cout << data->string() << std::endl; + }); + while (condition) { + usleep(100 * 1000); + } + exit(0); + } +} + +void signalHandler(int signum) +{ + condition = 0; + std::exit(0); // 这会调用全局对象的析构函数 +} + +struct call_fun { + std::string fun; + char flage; + std::string dec; + std::function fun_call; +}; + +int main(int argc, char *argv[]) +{ + if (argc < 2) { + error_print_exit: + std::cout << R"help( +用法:git [--version] [--help] + <命令> [<参数>] + +这些是各种场合常见的 cli 命令: + +直接操作 ec (参见:cli help device) + device 直接执行一个操作,使用指令传递参数 + +自定义操作 ec (参见:git help exec) + exec 执行一个原始函数调用 + +订阅 prox 的通道数据(参见:git help echo) + echo 显示 prox 的通道数据 + +命令 'cli help -a' 和 'cli help -g' 显示可用的子命令和一些概念帮助。 +查看 'cli help <命令>' 或 'cli help <概念>' 以获取给定子命令或概念的 +帮助。 +)help" << std::endl; + return 0; + } + signal(SIGTERM, signalHandler); + signal(SIGINT, signalHandler); + rpc_socket_path = getenv("AX650C_EC_PROXY_RPC_SOCKET"); + if (rpc_socket_path == NULL) { + rpc_socket_path = "ipc:///tmp/rpc.ec_prox"; + } + pub_socket_path = getenv("AX650C_EC_PROXY_PUB_SOCKET"); + if (pub_socket_path == NULL) { + pub_socket_path = "ipc:///tmp/llm/ec_prox.event.socket"; + } + if (std::string(argv[1]) == "device") { + cmdline::parser a; + // clang-format off + std::list cmd_list = { + {"rgb", 'r', "rgb_mode", std::bind(&info_fun, std::placeholders::_1, "rgb_set_mode", "rgb_get_mode")}, + {"rgb_size", 0, "rgb_size", std::bind(&info_fun, std::placeholders::_1, "rgb_set_size", "rgb_get_size")}, + {"rgb_get_color", 0, "rgb_get_color", std::bind(&info_fun, std::placeholders::_1, "rgb_get_color", "")}, + {"rgb_set_color", 0, "rgb set color ,example: cli --rgb_set_color -d '{\"rgb_index\":0,\"rgb_color\":255}'", std::bind(&info_fun, std::placeholders::_1, "rgb_set_color", "")}, + {"fan", 'f', "fan_pwm", std::bind(&info_fun, std::placeholders::_1, "fan_set_pwm", "fan_get_pwm")}, + {"fanspeed", 'F', "fan_speed", std::bind(&info_fun, std::placeholders::_1, "", "fan_get_speed")}, + {"board", 'B', "board_get_power_info", std::bind(&info_fun, std::placeholders::_1, "", "board_get_power_info")}, + {"ip", 'i', "ip fun", std::bind(&info_fun, std::placeholders::_1, "ip_set", "ip_get")}, + {"lcd", 'l', "lcd fun", std::bind(&info_fun, std::placeholders::_1, "lcd_set_mode", "lcd_get_mode")}, + {"lcd_ram", 0, "lcd_ram", std::bind(&info_fun, std::placeholders::_1, "lcd_set_ram", "")}, + {"lcd_echo", 'E', "lcd_echo", std::bind(&info_fun, std::placeholders::_1, "lcd_echo", "")}, + {"vddcpu", 'c', "vddcpu fun", std::bind(&info_fun, std::placeholders::_1, "vddcpu_set", "vddcpu_get")}, + {"modbus_speed", 0, "modbus_speed", std::bind(&info_fun, std::placeholders::_1, "modbus_set_speed", "modbus_get_speed")}, + {"ext_power", 'p', "ext_power fun", std::bind(&info_fun, std::placeholders::_1, "ext_power", "")}, + {"board_power", 'b', "board_power fun", std::bind(&info_fun, std::placeholders::_1, "board_power", "")}, + {"pcie0", 0, "pcie0_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "pcie0_set_switch", "")}, + {"pcie1", 0, "pcie1_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "pcie1_set_switch", "")}, + {"gl3510_reset", 0, "gl3510_reset fun", std::bind(&info_fun, std::placeholders::_1, "gl3510_reset", "")}, + {"usbds1_big", 0, "usbds1_set_big_power fun", std::bind(&info_fun, std::placeholders::_1, "usbds1_set_big_power", "")}, + {"usbds2_big", 0, "usbds2_set_big_power fun", std::bind(&info_fun, std::placeholders::_1, "usbds2_set_big_power", "")}, + {"usbds1", 0, "usbds1_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "usbds1_set_switch", "")}, + {"usbds2", 0, "usbds2_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "usbds2_set_switch", "")}, + {"usbds3", 0, "usbds3_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "usbds3_set_switch", "")}, + {"grove_uart", 0, "grove_uart_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "grove_uart_set_switch", "")}, + {"grove_iic", 0, "grove_iic_set_switch fun", std::bind(&info_fun, std::placeholders::_1, "grove_iic_set_switch", "")}, + {"flash_switch", 0, "flash_save_switch fun", std::bind(&info_fun, std::placeholders::_1, "flash_save_switch", "")}, + {"flash_value", 0, "flash_save_value_config fun", std::bind(&info_fun, std::placeholders::_1, "flash_save_value_config", "")}, + {"poweroff", 0, "poweroff fun", std::bind(&info_fun, std::placeholders::_1, "poweroff", "")}, + + }; + // clang-format on + for (auto &cmd : cmd_list) { + a.add(cmd.fun, cmd.flage, cmd.dec); + } + a.add("data", 'd', "call param", false); + a.add("DataRaw", 'D', "call param raw", false); + a.parse_check(argc, argv); + for (auto &cmd : cmd_list) { + if (a.exist(cmd.fun)) { + cmd.fun_call(a); + } + } + } else if (std::string(argv[1]) == "exec") { + cmdline::parser a; + a.add("list", 'l', "list call function"); + a.add("fun", 'f', "call ax650c_ec_proxy function", false); + a.add("data", 'd', "call ax650c_ec_proxy function input data", false); + a.parse_check(argc, argv); + exec_fun(a); + } else if (std::string(argv[1]) == "echo") { + cmdline::parser a; + a.add("button", 'b', "button event"); + a.parse_check(argc, argv); + echo_fun(a); + std::cout << a.usage() << std::endl; + return 0; + } else { + goto error_print_exit; + } + + return 0; +} diff --git a/projects/llm_framework/main_ax650_ec_proxy/src/ec_proxy_main.cpp b/projects/llm_framework/main_ax650_ec_proxy/src/ec_proxy_main.cpp new file mode 100644 index 0000000..38c40fd --- /dev/null +++ b/projects/llm_framework/main_ax650_ec_proxy/src/ec_proxy_main.cpp @@ -0,0 +1,963 @@ +/* + * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD + * + * SPDX-License-Identifier: MIT + */ +#include "StackFlow.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include "cmdline.hpp" +#include <../../static_lib/include/fmt/core.h> +#include <../../static_lib/include/fmt/format.h> +#include "../../../../SDK/components/utilities/include/sample_log.h" + +int main_exit_flage = 0; +static void __sigint(int iSigNo) +{ + SLOGW("llm_ec_prox will be exit!"); + main_exit_flage = 1; +} + +#define CONFIG_AUTO_SET(obj, key) \ + if (config_body.contains(#key)) \ + mode_config_.key = config_body[#key]; \ + else if (obj.contains(#key)) \ + mode_config_.key = obj[#key]; + +using namespace StackFlows; + +class llm_ec_prox : public StackFlow { +private: + enum { EVENT_LOAD_CONFIG = EVENT_EXPORT + 1, EVENT_QUEUE_PLAY }; + std::string ec_prox_event_channel = "ipc:///tmp/llm/ec_prox.event.socket"; + modbus_t *modbus_ctx; + std::mutex modbus_mtx_; + typedef struct { + int reg_index; // 16位寄存器索引 + int byte_offset; // 在寄存器中字节偏移(0-低字节,1-高字节) + } RegPosition; + std::unique_ptr pub_ctx_; + std::string StackFlow_pack_temp = + R"format({{ "created":{},"data":{},"object":{},"request_id":{},"work_id":"ax650_ec_proxy" }})format"; + std::string StackFlow_pack_all_temp = + R"format({{ "created":{},"data":{},"error":{{"code":{},"message":{}}},"object":{},"request_id":{},"work_id":"ax650_ec_proxy" }})format"; + std::string return_success_result(std::string data, std::string object = "\"\"", std::string request_id = "\"\"") + { + return fmt::format(StackFlow_pack_temp, std::time(nullptr), data, object, request_id); + } + + static llm_ec_prox *self; + + void loop() + { + uint8_t butt = 0; + while (!main_exit_flage) { + { + std::unique_lock lock(this->modbus_mtx_); + uint8_t tab_rp_bits[2]; + int rc = modbus_read_input_bits(modbus_ctx, 4, 1, tab_rp_bits); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + if (tab_rp_bits[0] != butt) { + if (tab_rp_bits[0]) { + pub_ctx_->send_data(return_success_result("1")); + } else { + pub_ctx_->send_data(return_success_result("0")); + } + butt = tab_rp_bits[0]; + } + } + // std::cout << "butt:" << (int)butt << std::endl; + } + usleep(20 * 1000); + } + } + + std::string board_get_power_info(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + // mbpoll -m rtu -b 115200 -P none -a 1 -r 1 -t 3 -c 13 -l 10 /dev/ttyS3 + uint16_t tab_reg[12]; + int rc = modbus_read_input_registers(modbus_ctx, 0, 12, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format( + R"format({{ "pcie0_mv": {} , "pcie0_ma": {} , "pcie1_mv": {} , "pcie1_ma": {} , "usb1_mv": {} , "usb1_ma": {} , "usb2_mv": {} , "usb2_ma": {} , "VDD5V_mv": {} , "VDD5V_ma": {} , "EXT5V_mv": {} , "EXT5V_ma": {} }})format", + tab_reg[0], tab_reg[1], tab_reg[2], tab_reg[3], tab_reg[4], tab_reg[5], tab_reg[6], tab_reg[7], + tab_reg[8], tab_reg[9], tab_reg[10], tab_reg[11])); + } + return std::string("Error"); + } + + std::string fan_get_speed(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + // mbpoll -m rtu -b 115200 -P none -a 1 -r 1 -t 3 -c 13 -l 10 /dev/ttyS3 + uint16_t tab_reg[2]; + int rc = modbus_read_input_registers(modbus_ctx, 12, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string fan_get_pwm(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + int rc = modbus_read_registers(modbus_ctx, 1, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string fan_set_pwm(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_register(modbus_ctx, 1, tab_reg[0]); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + } + return return_success_result("\"ok\""); + } + + RegPosition get_rgb_reg_pos(int rgb_index) + { + RegPosition res; + int offset = rgb_index * 3; // 每个RGB占3字节 + res.reg_index = offset / 2; + res.byte_offset = offset % 2; + return res; + } + std::string rgb_get_mode(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + int rc = modbus_read_registers(modbus_ctx, 11, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string rgb_set_mode(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_register(modbus_ctx, 11, tab_reg[0]); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string rgb_get_size(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + int rc = modbus_read_registers(modbus_ctx, 10, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string rgb_set_size(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_register(modbus_ctx, 10, tab_reg[0]); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string rgb_get_color(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + int rgb_index = 0; + int rgb_color = 0; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + rgb_index = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + uint16_t tab_reg[2]; + RegPosition reg_pos = get_rgb_reg_pos(rgb_index); + { + int rc = modbus_read_registers(modbus_ctx, reg_pos.reg_index + 12, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + for (int i = 0; i < 2; i++) tab_reg[i] = ntohs(tab_reg[i]); + uint8_t *rgb_color_reg = (uint8_t *)tab_reg; + rgb_color = rgb_color_reg[reg_pos.byte_offset] << 16; + rgb_color |= rgb_color_reg[reg_pos.byte_offset + 1] << 8; + rgb_color |= rgb_color_reg[reg_pos.byte_offset + 2]; + return return_success_result(fmt::format("{}", rgb_color)); + } + } + return std::string("Error"); + } + std::string rgb_set_color(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + int rgb_index = 0; + int rgb_color = 0; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + rgb_index = (int)fan_data["data"]["rgb_index"]; + rgb_color = (int)fan_data["data"]["rgb_color"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + uint16_t tab_reg[2]; + RegPosition reg_pos = get_rgb_reg_pos(rgb_index); + { + int rc = modbus_read_registers(modbus_ctx, reg_pos.reg_index + 12, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } + for (int i = 0; i < 2; i++) tab_reg[i] = ntohs(tab_reg[i]); + } + { + uint8_t *rgb_color_reg = (uint8_t *)tab_reg; + rgb_color_reg[reg_pos.byte_offset] = (rgb_color & 0xff0000) >> 16; + rgb_color_reg[reg_pos.byte_offset + 1] = (rgb_color & 0xff00) >> 8; + rgb_color_reg[reg_pos.byte_offset + 2] = (rgb_color & 0xff); + } + for (int i = 0; i < 2; i++) tab_reg[i] = htons(tab_reg[i]); + { + int rc = modbus_write_registers(modbus_ctx, reg_pos.reg_index + 12, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + } + return return_success_result("\"ok\""); + } + + std::string lcd_get_mode(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + int rc = modbus_read_registers(modbus_ctx, 86, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string lcd_set_mode(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2]; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_register(modbus_ctx, 86, tab_reg[0]); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string lcd_set_ram(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + std::string rgb_ram_base64; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + rgb_ram_base64 = fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + uint16_t *rgb_ram = (uint16_t *)malloc(((BASE64_DECODE_OUT_SIZE(rgb_ram_base64.length()) / 2) + 1) * 2); + int ram_size = base64_decode(rgb_ram_base64.c_str(), rgb_ram_base64.length(), (uint8_t *)rgb_ram); + ram_size = ram_size > 1870 ? 1870 : ram_size; + int rc = modbus_write_registers(modbus_ctx, 88, ram_size / 2, rgb_ram); + free(rgb_ram); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return std::string("Ok"); + } + + std::string lcd_echo(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + std::string put_strs; + uint16_t tab_reg = 0; + uint8_t *c_reg = (uint8_t *)&tab_reg; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + put_strs = fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + auto it = put_strs.begin(); + while (it != put_strs.end()) { + c_reg[0] = *it; + ++it; + if (it != put_strs.end()) { + c_reg[1] = *it; + ++it; + } else { + c_reg[1] = 0; + } + int rc = modbus_write_register(modbus_ctx, 87, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + } + return return_success_result("\"ok\""); + } + + std::string ip_get(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint32_t value = 0; + uint16_t tab_reg[2] = {0}; + + int rc = modbus_read_registers(modbus_ctx, 5, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + for (int i = 0; i < 2; i++) tab_reg[i] = ntohs(tab_reg[i]); + value = ((uint32_t)tab_reg[0] << 16) | tab_reg[1]; + char ip_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &value, ip_str, INET_ADDRSTRLEN); + return return_success_result(fmt::format("\"{}\"", ip_str)); + } + return std::string("Error"); + } + std::string ip_set(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint32_t value; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + std::string ip_str = fan_data["data"]; + if (inet_pton(AF_INET, ip_str.c_str(), &value) != 1) { + return std::string("Error : 无效的 IP 地址\n"); + } + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + uint16_t tab_reg[2]; + tab_reg[0] = (value >> 16) & 0xFFFF; + tab_reg[1] = value & 0xFFFF; + for (int i = 0; i < 2; i++) tab_reg[i] = htons(tab_reg[i]); + int rc = modbus_write_registers(modbus_ctx, 5, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string vddcpu_get(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + + int rc = modbus_read_registers(modbus_ctx, 2, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "读取失败: %s\n", modbus_strerror(errno)); + } else { + return return_success_result(fmt::format("{}", tab_reg[0])); + } + return std::string("Error"); + } + std::string vddcpu_set(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_registers(modbus_ctx, 2, 1, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string modbus_set_speed(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + int modbus_speed; + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + modbus_speed = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + set_modbus_speed(modbus_speed); + return return_success_result("\"ok\""); + } + std::string modbus_get_speed(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + return return_success_result(fmt::format("{}", _modbus_speed)); + } + void set_modbus_speed(int modbus_speed) + { + uint16_t tab_reg[2]; + tab_reg[0] = (modbus_speed >> 16) & 0xFFFF; + tab_reg[1] = modbus_speed & 0xFFFF; + int rc = modbus_write_registers(modbus_ctx, 3, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + std::exit(-1); + } + modbus_close(modbus_ctx); + modbus_free(modbus_ctx); + modbus_ctx = NULL; + usleep(100 * 1000); + modbus_ctx = modbus_new_rtu("/dev/ttyS3", modbus_speed, 'N', 8, 1); + if (modbus_ctx == NULL) { + fprintf(stderr, "Unable to create the context\n"); + std::exit(-1); + } + modbus_set_slave(modbus_ctx, 1); // 设置 Modbus 从站地址为1 + if (modbus_connect(modbus_ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(modbus_ctx); + std::exit(-1); + } + _modbus_speed = modbus_speed; + } + int _modbus_speed = 115200; + + void _init_modbus() + { + modbus_ctx = modbus_new_rtu("/dev/ttyS3", 115200, 'N', 8, 1); + if (modbus_ctx == NULL) { + fprintf(stderr, "Unable to create the context\n"); + std::exit(-1); + } + modbus_set_slave(modbus_ctx, 1); // 设置 Modbus 从站地址为1 + if (modbus_connect(modbus_ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(modbus_ctx); + std::exit(-1); + } + uint8_t tab_rp_bits[2]; + int rc = modbus_read_input_bits(modbus_ctx, 4, 1, tab_rp_bits); + if (rc == -1) { + _modbus_speed = 1152000; + modbus_ctx = modbus_new_rtu("/dev/ttyS3", _modbus_speed, 'N', 8, 1); + if (modbus_ctx == NULL) { + fprintf(stderr, "Unable to create the context\n"); + std::exit(-1); + } + modbus_set_slave(modbus_ctx, 1); // 设置 Modbus 从站地址为1 + if (modbus_connect(modbus_ctx) == -1) { + fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); + modbus_free(modbus_ctx); + std::exit(-1); + } + uint8_t tab_rp_bits[2]; + int rc = modbus_read_input_bits(modbus_ctx, 4, 1, tab_rp_bits); + if (rc == -1) { + fprintf(stderr, "modbus 115200/1152000 速度探测失败: %s\n", modbus_strerror(errno)); + std::exit(-1); + } + } else { + set_modbus_speed(1152000); + } + } + + std::string ext_poweroff(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 0, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string board_poweroff(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 1, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string pcie0_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 4, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string pcie1_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 5, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string gl3510_reset(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 6, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string usbds1_set_big_power(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 7, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string usbds2_set_big_power(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 8, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string usbds1_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 9, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string usbds2_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 10, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string usbds3_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 11, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string grove_uart_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 12, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + std::string grove_iic_set_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 13, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string flash_save_switch(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 14, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string flash_save_value_config(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_bit(modbus_ctx, 15, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + + std::string poweroff(StackFlows::pzmq *_pzmq, const std::shared_ptr &data) + { + uint16_t tab_reg[2] = {0}; + try { + nlohmann::json fan_data = nlohmann::json::parse(data->string()); + tab_reg[0] = (int)fan_data["data"]; + } catch (const nlohmann::json::parse_error &e) { + std::cerr << "解析失败:" << e.what() << std::endl; + return std::string("Error"); + } catch (...) { + std::cout << "data 解析异常" << std::endl; + return std::string("Error"); + } + int rc = modbus_write_register(modbus_ctx, 0, tab_reg[0] >= 1000 ? tab_reg[0] : 1000); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + rc = modbus_write_bit(modbus_ctx, 16, 1); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + return std::string("Error"); + } + return return_success_result("\"ok\""); + } + +public: + llm_ec_prox() : StackFlow("ec_prox") + { + // setup("", "audio.play", "{\"None\":\"None\"}"); + self = this; + // prob modbus speed + _init_modbus(); + + pub_ctx_ = std::make_unique(ec_prox_event_channel, ZMQ_PUB); + + // clang-format off +#define REGISTER_RPC_ACTION(name, func) \ + rpc_ctx_->register_rpc_action(name, [this](StackFlows::pzmq *_pzmq, const std::shared_ptr &data){ \ + std::unique_lock lock(this->modbus_mtx_); \ + return this->func(_pzmq, data); \ + }); + + REGISTER_RPC_ACTION("fan_get_speed", fan_get_speed); + REGISTER_RPC_ACTION("fan_get_pwm", fan_get_pwm); + REGISTER_RPC_ACTION("fan_set_pwm", fan_set_pwm); + + REGISTER_RPC_ACTION("rgb_get_mode", rgb_get_mode); + REGISTER_RPC_ACTION("rgb_set_mode", rgb_set_mode); + REGISTER_RPC_ACTION("rgb_get_size", rgb_get_size); + REGISTER_RPC_ACTION("rgb_set_size", rgb_set_size); + REGISTER_RPC_ACTION("rgb_get_color", rgb_get_color); + REGISTER_RPC_ACTION("rgb_set_color", rgb_set_color); + + REGISTER_RPC_ACTION("board_get_power_info", board_get_power_info); + + REGISTER_RPC_ACTION("ip_get", ip_get); + REGISTER_RPC_ACTION("ip_set", ip_set); + + REGISTER_RPC_ACTION("lcd_get_mode", lcd_get_mode); + REGISTER_RPC_ACTION("lcd_set_mode", lcd_set_mode); + REGISTER_RPC_ACTION("lcd_set_ram", lcd_set_ram); + REGISTER_RPC_ACTION("lcd_echo", lcd_echo); + + + REGISTER_RPC_ACTION("vddcpu_get", vddcpu_get); + REGISTER_RPC_ACTION("vddcpu_set", vddcpu_set); + + REGISTER_RPC_ACTION("modbus_get_speed", modbus_get_speed); + REGISTER_RPC_ACTION("modbus_set_speed", modbus_set_speed); + + REGISTER_RPC_ACTION("ext_poweroff", ext_poweroff); + REGISTER_RPC_ACTION("board_poweroff", board_poweroff); + REGISTER_RPC_ACTION("pcie0_set_switch", pcie0_set_switch); + REGISTER_RPC_ACTION("pcie1_set_switch", pcie1_set_switch); + REGISTER_RPC_ACTION("gl3510_reset", gl3510_reset); + REGISTER_RPC_ACTION("usbds1_set_big_power", usbds1_set_big_power); + REGISTER_RPC_ACTION("usbds2_set_big_power", usbds2_set_big_power); + REGISTER_RPC_ACTION("usbds1_set_switch", usbds1_set_switch); + REGISTER_RPC_ACTION("usbds2_set_switch", usbds2_set_switch); + REGISTER_RPC_ACTION("usbds3_set_switch", usbds3_set_switch); + REGISTER_RPC_ACTION("grove_uart_set_switch", grove_uart_set_switch); + REGISTER_RPC_ACTION("grove_iic_set_switch", grove_iic_set_switch); + REGISTER_RPC_ACTION("flash_save_switch", flash_save_switch); + REGISTER_RPC_ACTION("flash_save_value_config", flash_save_value_config); + REGISTER_RPC_ACTION("poweroff", poweroff); + + + + +#undef REGISTER_RPC_ACTION + // clang-format on + } + int setup(const std::string &work_id, const std::string &object, const std::string &data) override + { + send(std::string("None"), std::string("None"), std::string(""), unit_name_); + return -1; + } + void ax650_ec_prox_exit() + { + pub_ctx_.reset(); + for (int i = 0; i < 3; i++) { + uint32_t value = 115200; + uint16_t tab_reg[2]; + tab_reg[0] = (value >> 16) & 0xFFFF; + tab_reg[1] = value & 0xFFFF; + int rc = modbus_write_registers(modbus_ctx, 3, 2, tab_reg); + if (rc == -1) { + fprintf(stderr, "写入失败: %s\n", modbus_strerror(errno)); + } else { + break; + } + } + modbus_close(modbus_ctx); + modbus_free(modbus_ctx); + std::cout << "all exit!" << std::endl; + } + ~llm_ec_prox() + { + ax650_ec_prox_exit(); + } +}; + +llm_ec_prox *llm_ec_prox::self; +int main(int argc, char *argv[]) +{ + signal(SIGTERM, __sigint); + signal(SIGINT, __sigint); + mkdir("/tmp/llm", 0777); + llm_ec_prox ec_prox; + while (!main_exit_flage) { + sleep(1); + } + ec_prox.llm_firework_exit(); + return 0; +}