Initial commit

This commit is contained in:
CChen616
2024-03-19 15:48:17 +08:00
parent 2ae601ba66
commit 1023fb5796
82 changed files with 43002 additions and 1 deletions

2
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,2 @@
aux_source_directory(. DIR_LIB_SRCS)
add_library(src ${DIR_LIB_SRCS})

73
src/KlippyGcodes.cpp Normal file
View File

@@ -0,0 +1,73 @@
#include "../include/KlippyGcodes.h"
std::string set_bed_temp(int temp) {
return SET_BED_TEMP + (std::string)" S" + std::to_string(temp);
}
std::string set_ext_temp(int temp, int tool) {
return SET_EXT_TEMP + (std::string)" T" + std::to_string(tool) + (std::string)" S" + std::to_string(temp);
}
std::string set_heater_temp(std::string heater, int temp) {
return "SET_HEATER_TEMPERATURE heater=" + heater + " target=" + std::to_string(temp);
}
std::string set_temp_fan_temp(std::string temp_fan, int temp) {
return "SET_TEMPERATURE_FAN_TARGET temperature_fan=" + temp_fan + " target=" + std::to_string(temp);
}
std::string set_fan_speed(int speed) {
// std::cout << "设置速率的计算结果为 = " << ((float)(int(speed) % 101) / 100 * 255) << std::endl;
// std::cout << "设置速率的计算结果为 = " << (int)((float)(int(speed) % 101) / 100 * 255) << std::endl;
std::string speed_temp = std::to_string(int(float(int(speed) % 101) / 100 * 255));
return SET_FAN_SPEED + (std::string)" S" + speed_temp;
}
/* Xindi */
std::string set_fan0_speed(int speed) {
// std::string speed_temp = std::to_string(int(float(int(speed)) / 100 * 255));
std::string speed_temp = std::to_string(float((float)(speed * 255) / 100));
std::cout << speed_temp << std::endl;
return "M106 P0 S" + speed_temp;
}
std::string set_fan2_speed(int speed) {
std::string speed_temp = std::to_string(float((float)(speed * 255) / 100));
return "M106 P2 S" + speed_temp;
}
std::string set_fan3_speed(int speed) {
std::string speed_temp = std::to_string(float((float)(speed * 255) / 100));
return "M106 P3 S" + speed_temp;
}
/* Xindi */
std::string set_extrusion_rate(std::string rate) {
return SET_EXT_FACTOR + (std::string)" S" + rate;
}
std::string set_speed_rate(std::string rate) {
return SET_SPD_FACTOR + (std::string)" S" + rate;
}
std::string testz_move(std::string dist) {
return TESTZ + dist;
}
std::string extrude(std::string dist, int speed) {
return MOVE + (std::string)" E" + dist + (std::string)" F" + std::to_string(speed);
}
std::string bed_mesh_load(std::string profile) {
return "BED_MESH_PROFILE LOAD=" + profile;
}
std::string bed_mesh_remove(std::string profile) {
return "BED_MESH_PROFILE REMOVE=" + profile;
}
std::string bed_mesh_save(std::string profile) {
return "BED_MESH_PROFILE SAVE=" + profile;
}

101
src/KlippyRest.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "../include/KlippyRest.h"
#include "../include/mks_log.h"
#include "../include/event.h"
std::string server_files_metadata(std::string ip, std::string port, std::string filename) {
return send_request(ip, port, "server/files/metadata?filename=" + filename, "GET");
}
std::string printer_objects_query(std::string ip, std::string port, std::string parameter) {
return send_request(ip, port, "printer/objects/query?" + parameter, "GET");
}
std::string printer_print_start(std::string ip, std::string port, std::string filename) {
return send_request(ip, port, "printer/print/start?filename=" + filename, "POST");
}
std::string printer_print_pause(std::string ip, std::string port) {
return send_request(ip, port, "printer/print/pause", "POST");
}
std::string printer_print_resume(std::string ip, std::string port) {
return send_request(ip, port, "printer/print/resume", "POST");
}
std::string printer_print_cancel(std::string ip, std::string port) {
return send_request(ip, port, "printer/print/cancel", "POST");
}
std::string get_server_files_list(std::string ip, std::string port) {
return send_request(ip, port, "server/files/list?", "GET");
}
std::string get_server_files_directory(std::string ip, std::string port) {
return send_request(ip, port, "server/files/directory?", "GET");
}
std::string get_server_info(std::string ip, std::string port) {
return send_request(ip, port, "server/info", "GET");
}
std::string get_oneshot_token(std::string ip, std::string port) {
return send_request(ip, port, "access/oneshot_token", "GET");
}
std::string get_printer_info(std::string ip, std::string port) {
return send_request(ip, port, "printer/info", "GET");
}
// File delete
std::string delete_file_delete(std::string ip, std::string port, std::string filepath) {
return send_request(ip, port, "server/files/" + filepath, "DELETE");
}
std::string get_thumbnail_stream(std::string ip, std::string port, std::string thumbnail) {
std::string url = "http://" + ip + ":" + port + "/server/files/gcodes/" + thumbnail;
http::Request request{url};
struct http::Response response = request.send("GET");
if (response.status.code == 200) {
return std::string{response.body.begin(), response.body.end()};
} else {
return "";
}
}
std::string send_request(std::string ip, std::string port, std::string method, std::string request_type) {
std::string url = "http://" + ip + ":" + port + "/" + method;
std::string str_response = "";
url=replaceCharacters(url," ","%20");
MKSLOG_BLUE("Sending request to %s", url.data());
try
{
http::Request request{url};
struct http::Response response = request.send(request_type);
str_response = std::string{response.body.begin(), response.body.end()};
}
catch(const std::exception& e)
{
std::cerr << "Request failed, error" << e.what() << '\n';
}
return str_response;
}
/*
std::string send_post_request(std::string ip, std::string port, std::string method) {
std::string url = "http://" + ip + ":" + port + "/" + method;
std::cout << url << std::endl;
std::string str_response = "";
MKSLOG_BLUE("Sending request to %s", url.data());
try
{
http::Request request{url};
struct http::Response response = request.send("POST");
str_response = std::string{response.body.begin(), response.body.end()};
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
return str_response;
}
*/

161
src/MakerbaseClient.cpp Normal file
View File

@@ -0,0 +1,161 @@
#include "../include/MakerbaseClient.h"
MakerbaseClient::MakerbaseClient(std::string host = "localhost", std::string port = "7125") {
m_WebsocketClient.clear_access_channels(websocketpp::log::alevel::all); // 开启全部接入日志级别
m_WebsocketClient.clear_error_channels(websocketpp::log::elevel::all); // 开启全部错误日志级别
m_WebsocketClient.set_error_channels(websocketpp::log::elevel::none);
m_WebsocketClient.init_asio(); // 初始化asio
m_WebsocketClient.start_perpetual(); // 避免请求为空时退出实际上也是避免asio退出
// 独立运行client::run()的线程,主要是避免阻塞
m_Thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run, &m_WebsocketClient);
this->host = host;
this->port = port;
this->is_connected = false;
}
MakerbaseClient::~MakerbaseClient()
{
m_WebsocketClient.stop_perpetual();
if (m_ConnectionMetadataPtr != nullptr && m_ConnectionMetadataPtr->get_status() == "Open")
{
websocketpp::lib::error_code ec;
m_WebsocketClient.close(m_ConnectionMetadataPtr->get_hdl(), websocketpp::close::status::going_away, "", ec); // 关闭连接
if (ec) {
std::cout << "> Error initiating close: " << ec.message() << std::endl;
}
}
m_Thread->join();
}
bool MakerbaseClient::Connect(std::string const & url) {
websocketpp::lib::error_code ec;
// 创建connect的共享指针注意此时创建并没有实际建立
client::connection_ptr con = m_WebsocketClient.get_connection(url, ec);
if (ec) {
std::cout << "> Connect initialization error: " << ec.message() << std::endl;
return false;
}
// 创建连接的metadata信息并保存
connection_metadata::ptr metadata_ptr = websocketpp::lib::make_shared<connection_metadata>(con->get_handle(), url);
m_ConnectionMetadataPtr = metadata_ptr;
try {
// 注册连接打开的Handler
con->set_open_handler(websocketpp::lib::bind(
&connection_metadata::on_open,
metadata_ptr,
&m_WebsocketClient,
websocketpp::lib::placeholders::_1
));
// 注册连接失败的Handler
con->set_fail_handler(websocketpp::lib::bind(
&connection_metadata::on_fail,
metadata_ptr,
&m_WebsocketClient,
websocketpp::lib::placeholders::_1
));
// 注册连接关闭的Handler
con->set_close_handler(websocketpp::lib::bind(
&connection_metadata::on_close,
metadata_ptr,
&m_WebsocketClient,
websocketpp::lib::placeholders::_1
));
// 注册连接接收消息的Handler
con->set_message_handler(websocketpp::lib::bind(
&connection_metadata::on_message,
metadata_ptr,
websocketpp::lib::placeholders::_1,
websocketpp::lib::placeholders::_2
));
// 进行连接
m_WebsocketClient.connect(con);
// this->status = m_ConnectionMetadataPtr->get_status();
std::cout << "Websocket连接中" << std::endl;
} catch (const std::exception & e) {
std::cout << e.what() << std::endl;
} catch (websocketpp::lib::error_code e) {
std::cout << e.message() << std::endl;
} catch (...) {
std::cout << "other exception" << std::endl;
}
return true;
}
bool MakerbaseClient::Close(std::string reason) {
websocketpp::lib::error_code ec;
if (m_ConnectionMetadataPtr != nullptr)
{
int close_code = websocketpp::close::status::normal;
// 关闭连接
m_WebsocketClient.close(m_ConnectionMetadataPtr->get_hdl(), close_code, reason, ec);
if (ec) {
std::cout << "> Error initiating close: " << ec.message() << std::endl;
return false;
}
std::cout << "关闭Websocket连接成功" << std::endl;
}
return true;
}
bool MakerbaseClient::Send(std::string message) {
websocketpp::lib::error_code ec;
if (m_ConnectionMetadataPtr != nullptr)
{
// 连接发送数据
m_WebsocketClient.send(m_ConnectionMetadataPtr->get_hdl(), message, websocketpp::frame::opcode::text, ec);
if (ec) {
std::cout << "> Error sending message: " << ec.message() << std::endl;
return false;
} else {
this->sending_message = message;
std::cout << "发送数据成功, 数据内容" + this->sending_message << std::endl;
}
}
return true;
}
bool MakerbaseClient::GetIsConnected() {
return this->is_connected;
}
std::string MakerbaseClient::GetStatus() {
if (m_ConnectionMetadataPtr != nullptr) {
this->status = m_ConnectionMetadataPtr->get_status();
}
if (this->status == "Open") {
this->is_connected = true;
} else {
this->is_connected = false;
}
return this->status;
}
connection_metadata::ptr MakerbaseClient::GetConnectionMetadataPtr() {
return m_ConnectionMetadataPtr;
}
std::string MakerbaseClient::GetURL() {
return "ws://" + this->host + ":" + this->port + "/websocket?";
}

9
src/MakerbaseNetwork.cpp Normal file
View File

@@ -0,0 +1,9 @@
#include "../include/MakerbaseNetwork.h"
std::string get_wlan0_ip() {
char result[MAX_FILE_LEN] = {0};
std::string cmd = "ifconfig wlan0 | awk 'NR==2{print $2}' | tr -d '\n\r'";
execute_cmd(cmd.data(), result);
printf("%s", result);
return result;
}

56
src/MakerbasePanel.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include "../include/MakerbasePanel.h"
#include "../include/KlippyGcodes.h"
#include "../include/MoonrakerAPI.h"
#include "../include/MakerbasePanel.h"
std::string home() {
return json_run_a_gcode(HOME);
}
std::string homexy() {
return json_run_a_gcode(HOME_XY);
}
std::string z_tilt() {
return json_run_a_gcode(Z_TILT);
}
std::string quad_gantry_level() {
return json_run_a_gcode(QUAD_GANTRY_LEVEL);
}
// Move 函数
/**
* @brief
*
* @param axis 可选参数AXIS_X, AXIS_Y, AXIS_Z
* @param dist 距离与方向:如 +10, -100
* @param speed 速度
* @return std::string
*/
std::string move(std::string axis, std::string dist, int speed) {
return json_run_a_gcode(MOVE_RELATIVE + (std::string)"\n" + MOVE + (std::string)" "
+ axis + dist + (std::string)" F" + std::to_string(speed * 60) + (std::string)"\nG90");
}
/* 这个地方写在这里合不合适? */
std::string get_printer_object_status() {
nlohmann::json objects;
objects["webhook"];
objects["gcode_move"];
objects["toolhead"];
objects["configfile"];
objects["extruder"];
objects["heater_bed"];
objects["fan"];
objects["idle_timeout"];
objects["virtual_sdcard"];
objects["print_stats"];
objects["display_status"];
// objects["temperature_sensor sensor_name"];
// objects["filament_switch_sensor sensor_name"];
// objects["output_pin pin_name"];
objects["bed_mesh"];
// objects["gcode_macro macro_name"];
return json_query_printer_object_status(objects);
}

138
src/MakerbaseParseIni.cpp Normal file
View File

@@ -0,0 +1,138 @@
#include "../include/MakerbaseParseIni.h"
dictionary *mksini = NULL;
dictionary *printer_cfg = NULL;
dictionary *mksversion = NULL;
// std::string get_cfg_serial() {
// printer_cfg = iniparser_load("/home/mks/klipper_config/MKS_THR.cfg");
// if (printer_cfg == NULL) {
// std::cout << "cfg parse failure!" << std::endl;
// return "";
// }
// std::string sk = "mcu MKS_THR:serial";
// std::cout << "打开配置文件成功" << std::endl;
// const char *value = iniparser_getstring(mksini, sk.c_str(), "");
// return (std::string)value;
// }
// CLL 用于获取在线更新信息
int updateini_load() {
mksini = iniparser_load("/root/auto_update/update_info.ini");
if (mksini == NULL) {
std::cout << "Ini parse failure" << std::endl;
return -1;
}
return 0;
}
// CLL 用于获取在线更新进度
int progressini_load() {
mksini = iniparser_load("/root/auto_update/update_progress.ini");
if (mksini == NULL) {
std::cout << "Ini parse failure" << std::endl;
return -1;
}
return 0;
}
int mksini_load() {
mksini = iniparser_load(INIPATH);
if (mksini == NULL) {
std::cout << "Ini parse failure!" << std::endl;
return -1;
}
return 0;
}
void mksini_free() {
iniparser_freedict(mksini);
}
std::string mksini_getstring(std::string section, std::string key, std::string def) {
std::string sk = section + ":" + key;
const char *value = iniparser_getstring(mksini, sk.c_str(), def.c_str());
return (std::string)value;
}
int mksini_getint(std::string section, std::string key, int notfound) {
std::string sk = section + ":" + key;
int value = iniparser_getint(mksini, sk.c_str(), notfound);
return value;
}
double mksini_getdouble(std::string section, std::string key, double notfound) {
std::string sk = section + ":" + key;
double value = iniparser_getdouble(mksini, sk.c_str(), notfound);
return value;
}
bool mksini_getboolean(std::string section, std::string key, int notfound) {
std::string sk = section + ":" + key;
int value = iniparser_getboolean(mksini, sk.c_str(), notfound);
return (value == 0) ? false : true;
}
int mksini_set(std::string section, std::string key, std::string value) {
std::string sk = section + ":" + key;
int ret;
ret = iniparser_set(mksini, sk.c_str(), value.c_str());
return ret;
}
void mksini_unset(std::string section, std::string key) {
std::string sk = section + ":" + key;
iniparser_unset(mksini, sk.c_str());
}
// 保存到配置文件
void mksini_save() {
FILE *ini = fopen(INIPATH, "w");
if (ini == NULL) {
printf("[error] open mksini failed");
return;
}
iniparser_dump_ini(mksini, ini);
fclose(ini);
}
int mksversion_load() {
mksversion = iniparser_load(VERSION_PATH);
if (mksversion == NULL) {
std::cout << "Mks version failure!" << std::endl;
return -1;
}
return 0;
}
void mksversion_free() {
iniparser_freedict(mksversion);
}
std::string mksversion_mcu(std::string def) {
std::string version = "version:mcu";
const char *value = iniparser_getstring(mksversion, version.c_str(), def.c_str());
return (std::string)value;
}
std::string mksversion_ui(std::string def) {
std::string version = "version:ui";
const char *value = iniparser_getstring(mksversion, version.c_str(), def.c_str());
return (std::string)value;
}
std::string mksversion_soc(std::string def) {
std::string version = "version:soc";
const char *value = iniparser_getstring(mksversion, version.c_str(), def.c_str());
return (std::string)value;
}

View File

@@ -0,0 +1,205 @@
#include "nlohmann/json.hpp"
#include "../include/MakerbaseClient.h"
#include "../include/MakerbaseCommand.h"
#include "../include/MoonrakerAPI.h"
#include "../include/mks_log.h"
#include "../include/MakerbaseParseMessage.h"
#include "../include/event.h"
#include "../include/mks_error.h"
#include "../include/mks_printer.h"
#include "../include/mks_file.h"
#include "../include/mks_gcode.h"
// #include "../include/systeminfo.h"
// #include "../include/printer.h"
// #include "../include/file.h"
// #include "../include/job.h"
// #include "../include/tjc_event.h"
#include "../include/ui.h"
extern MakerbaseClient *ep;
bool get_status_flag = false;
std::string message;
bool is_get_message = false;
int response_type_id;
nlohmann::json response;
nlohmann::json res;
extern bool filelist_changed;
extern bool all_level_saving;
//4.4.3 CLL 修改网页打印信息订阅
extern bool jump_to_print;
extern nlohmann::json output_metadata;
extern int current_page_id;
void *json_parse(void *arg) {
while (1) {
if (is_get_message == true) {
try
{
response = string2json(message);
res = response;
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
if (res["id"] != nlohmann::detail::value_t::null) {
std::cout << response["id"] << std::endl;
// std::cout << response << std::endl;
int id = response["id"];
switch (id)
{
case 3545:
std::cout << response << std::endl;
parse_file_estimated_time(response);
break;
case 4654:
std::cout << response << std::endl;
if (response["result"] == "ok") {
std::cout << response << std::endl;
} else if (response["result"] != nlohmann::detail::value_t::null) {
if (response["result"]["status"] != nlohmann::detail::value_t::null) {
std::cout << response["result"]["status"] << std::endl;
parse_subscribe_objects_status(response["result"]["status"]);
}
}
break;
case 5445:
std::cout << response << std::endl;
if (response["result"] != nlohmann::detail::value_t::null) {
parse_printer_info(response["result"]);
}
break;
// 解析一下总的时间
case 5656:
std::cout << response << std::endl;
if (response["result"] != nlohmann::detail::value_t::null) {
// parse_server_history_totals(response["result"]);
if (response["result"]["job_totals"] != nlohmann::detail::value_t::null) {
parse_server_history_totals(response["result"]["job_totals"]);
}
}
break;
default:
break;
}
}
if (res["error"] != nlohmann::detail::value_t::null) {
parse_error(response["error"]);
} else {
if (response["method"] != nlohmann::detail::value_t::null) {
// std::cout << response << std::endl;
std::string method = response["method"];
if (response["method"] == "notify_proc_stat_update") {
// MKSLOG_BLUE("%s", message.data());
/*
if (get_status_flag == false) {
// get_object_status(); // 主动获取必备的参数
sleep(1);
sub_object_status(); // 订阅相关的参数
sleep(1);
get_status_flag = true;
}
*/
} else if (method == "notify_gcode_response") {
MKSLOG_RED("%s", message.data());
parse_gcode_response(response["params"]);
MKSLOG_BLUE("Gcode 响应");
} else if (method == "notify_status_update") {
//std::cout << response["params"][0] << std::endl;
parse_subscribe_objects_status(response["params"][0]);
/*
if (get_status_flag == false) {
get_status_flag = true;
}
*/
} else if (method == "notify_klippy_ready") {
std::cout << response << std::endl;
MKSLOG_BLUE("Klippy 准备好了");
// 在这里进行订阅操作
get_object_status();
sub_object_status();
} else if (method == "notify_klippy_shutdown") {
MKSLOG_BLUE("Klippy 关机");
} else if (method == "notify_klippy_disconnected") {
MKSLOG_BLUE("Klippy 已断开连接");
get_object_status();
sub_object_status();
} else if (method == "notify_filelist_changed") {
filelist_changed = true;
MKSLOG_BLUE("文件列表已更改");
if (all_level_saving == false) {
all_level_saving = true;
}
} else if (method == "notify_update_response") {
MKSLOG_BLUE("更新管理器响应");
} else if (method == "notify_update_refreshed") {
MKSLOG_BLUE("更新管理器已刷新");
} else if (method == "notify_cpu_throttled") {
MKSLOG_BLUE("Moonraker 进程统计更新");
} else if (method == "notify_history_changed") {
//MKSLOG_RED("%s", message.data());
//std::cout << response << std::endl;
//4.4.3 CLL 修改网页打印信息订阅
switch (current_page_id)
{
case TJC_PAGE_PRINTING:
case TJC_PAGE_PRINT_ZOFFSET:
case TJC_PAGE_PRINT_FILAMENT:
case TJC_PAGE_PRINTING_2:
break;
default:
parse_file_estimated_time_send(response["params"][0]["job"]["metadata"]);
MKSLOG_BLUE("历史改变");
break;
}
} else if (method == "notify_user_created") {
MKSLOG_BLUE("授权用户创建");
} else if (method == "notify_user_deleted") {
MKSLOG_BLUE("已删除授权用户");
} else if (method == "notify_service_state_changed") {
// std::cout << response << std::endl;
// MKSLOG_BLUE("服务状态已更改");
} else if (method == "notify_job_queue_changed") {
MKSLOG_BLUE("作业队列已更改");
} else if (method == "notify_button_event") {
MKSLOG_BLUE("按钮事件");
} else if (method == "notify_announcement_update") {
MKSLOG_BLUE("公告更新事件");
} else if (method == "notify_announcement_dismissed") {
MKSLOG_BLUE("公告驳回事件");
} else if (method == "notify_announcement_wake") {
MKSLOG_BLUE("公告唤醒事件");
} else if (method == "notify_agent_event") {
MKSLOG_BLUE("代理事件");
} else if (method == "notify_power_changed") {
MKSLOG_BLUE("notify_power_changed");
// std::cout << response << std::endl;
}
}
}
response.clear();
is_get_message = false;
}
// usleep(300);
usleep(50);
}
// pthread_exit(NULL);
}

192
src/MakerbaseSerial.cpp Normal file
View File

@@ -0,0 +1,192 @@
#include <../include/MakerbaseSerial.h>
#include <time.h>
int set_option(int fd, int baudrate, int bits, unsigned char parity, unsigned char stopbit) {
// time_t start_time = 0, end_time = 0;
// time(&start_time);
struct termios newtio, oldtio;
if (tcgetattr(fd, &oldtio) != 0) {
// printf("读取串口参数发生错误\n");
return -1;
}
memset(&newtio, 0, sizeof(struct termios));
cfmakeraw(&newtio); // 设置为原始模式
/* 使能接收 */
newtio.c_cflag |= CREAD;
speed_t speed;
// 数据位相关的比特位清零
newtio.c_cflag &= ~CSIZE;
switch (bits)
{
case 7:
newtio.c_cflag |= CS7;
// printf("7数据位\n");
break;
case 8:
newtio.c_cflag |= CS8;
// printf("8数据位\n");
break;
default:
newtio.c_cflag |= CS8;
// printf("8数据位\n");
break;
}
switch (parity)
{
case 'O':
case 'o':
newtio.c_cflag |= (PARENB | PARODD);
newtio.c_cflag |= INPCK;
// printf("奇校验\n");
break;
case 'E':
case 'e':
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
newtio.c_iflag |= INPCK;
// printf("偶校验\n");
break;
case 'N':
default:
newtio.c_cflag &= ~PARENB;
newtio.c_iflag &= ~INPCK;
// printf("设置为无校验");
break;
}
// 设置波特率
switch (baudrate)
{
case 1200:
speed = B1200;
// printf("波特率为1200\n");
break;
case 1800:
speed = B1800;
// printf("波特率为1800\n");
break;
case 2400:
speed = B2400;
// printf("波特率为2400\n");
break;
case 4800:
speed = B4800;
// printf("波特率为4800\n");
break;
case 9600:
speed = B9600;
printf("波特率为9600\n");
break;
case 19200:
speed = B19200;
// printf("波特率为19200\n");
break;
case 38400:
speed = B38400;
// printf("波特率为38400\n");
break;
case 57600:
speed = B57600;
// printf("波特率为57600\n");
break;
case 115200:
speed = B115200;
// printf("波特率为115200\n");
break;
case 230400:
speed = B230400;
// printf("波特率为230400\n");
break;
case 460800:
speed = B460800;
// printf("波特率为460800\n");
break;
case 500000:
speed = B500000;
// printf("波特率为500000\n");
break;
case 921600:
speed = B921600;
printf("波特率为921600\n");
break;
default:
speed = B115200;
// printf("波特率为115200\n");
break;
}
if (0 > cfsetspeed(&newtio, speed)) {
// printf("设置波特率失败\n");
return -1;
}
// 设置停止位
switch (stopbit) {
case 1:
newtio.c_cflag &= ~CSTOPB;
// printf("设置1个停止位\n");
break;
case 2:
newtio.c_cflag |= CSTOPB;
// printf("设置2个停止位\n");
break;
default:
newtio.c_cflag &= ~CSTOPB;
// printf("默认设置1个停止位\n");
break;
}
// 将MIN和TIME设置为0
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
// 清空缓冲区
if (0 > tcflush(fd, TCIOFLUSH)) {
// printf("清空缓冲区失败\n");
return -1;
}
// 写入配置、使配置生效
if (0 > tcsetattr(fd, TCSANOW, &newtio)) {
// printf("配置串口失败");
return -1;
}
// time(&end_time);
// printf("设置波特率使用的时间: %f\n", difftime(end_time, start_time));
return 0;
}
char *create_command(char *cmd) {
char end[4] = {(char)0xff, (char)0xff, (char)0xff, 0};
return strcat(cmd, end);
}

19
src/MakerbaseShell.cpp Normal file
View File

@@ -0,0 +1,19 @@
#include "../include/MakerbaseShell.h"
void execute_cmd(const char *cmd, char *result) {
char buf_ps[MAX_FILE_LEN];
char ps[MAX_FILE_LEN];
FILE *ptr;
strcpy(ps, cmd);
if ((ptr = popen(ps, "r")) != NULL) {
while (fgets(buf_ps, MAX_FILE_LEN, ptr) != NULL)
{
strcat(result, buf_ps);
if (strlen(result) > MAX_FILE_LEN)
break;
}
pclose(ptr);
} else {
printf("popen %s error\n", ps);
}
}

563
src/MakerbaseWiFi.cpp Normal file
View File

@@ -0,0 +1,563 @@
#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include <regex>
#include <unistd.h>
#include "../include/MakerbaseWiFi.h"
#include "../include/MakerbaseShell.h"
#include "../include/mks_log.h"
#include "../include/mks_wpa_cli.h"
#include "../include/common.h"
struct mks_wifi_status_result_t status_result;
struct mks_wifi_status_t wpa_status;
std::vector<std::string> result_list;
std::vector<std::string> ssid_list;
std::vector<int> level_list;
std::string page_wifi_ssid_list[5] = {"", "", "", "", ""};
int page_wifi_ssid_list_pages = 0;
int page_wifi_current_pages;
std::string get_wifi_name = "";
extern std::string current_connected_ssid_name;
void set_page_wifi_ssid_list(int pages) {
page_wifi_ssid_list[0] = "";
page_wifi_ssid_list[1] = "";
page_wifi_ssid_list[2] = "";
page_wifi_ssid_list[3] = "";
page_wifi_ssid_list[4] = "";
auto it = ssid_list.begin();
for (int i = 0; i < pages * 5; i++) {
it++;
}
if (it != ssid_list.end()) {
page_wifi_ssid_list[0] = *it;
it++;
}
if (it != ssid_list.end()) {
page_wifi_ssid_list[1] = *it;
it++;
}
if (it != ssid_list.end()) {
page_wifi_ssid_list[2] = *it;
it++;
}
if (it != ssid_list.end()) {
page_wifi_ssid_list[3] = *it;
it++;
}
if (it != ssid_list.end()) {
page_wifi_ssid_list[4] = *it;
}
for (int j = 0; j < 5; j++) {
std::cout << page_wifi_ssid_list[j] << std::endl;
}
}
//4.4.1 CLL 修复WiFi刷新
void get_ssid_list_pages() {
if (ssid_list.size() % 5 == 0) {
page_wifi_ssid_list_pages = ssid_list.size() / 5;
} else {
page_wifi_ssid_list_pages = ssid_list.size() / 5 + 1;
}
if (page_wifi_ssid_list_pages > 5) {
page_wifi_ssid_list_pages = 5;
}
}
void get_wlan0_status() {
mks_wifi_run_cmd_status(&status_result);
}
bool detected_wlan0() {
if (access("/var/run/wpa_supplicant/wlan0", F_OK) == 0) {
return true;
} else {
return false;
}
}
//
void split_scan_result(std::string result) {
result_list.clear();
level_list.clear();
ssid_list.clear();
char *sub_result;
std::string token;
std::string delimiter = "\n";
size_t pos = 0;
int n_level = -100;
int index = 0;
while ((pos = result.find(delimiter)) != std::string::npos) {
token = result.substr(0, pos);
result_list.push_back(token);
result.erase(0, pos + delimiter.length());
}
for (int i = 1; i < result_list.size(); i++) {
char bssid[64];
char freq[64];
char level[64];
char flag[64];
char ssid[64];
unsigned char re[100];
sub_result = const_cast<char*>(result_list[i].data());
if (5 == sscanf(sub_result, "%s \t %s \t %s \t %s \t %s", &bssid, &freq, &level, &flag, &ssid)) {
printf_decode(re, 64, ssid);
level_list.push_back(atoi(level));
if (re[0] == '\x00') {
MKSLOG_YELLOW("扫描出来的ssid为\\0");
} else {
ssid_list.push_back((char *)re);
// ssid_list.insert((char *)re);
}
}
memset(sub_result, 0x00, sizeof(sub_result));
memset(ssid, 0x00, sizeof(ssid));
}
for (int j = 0; j < ssid_list.size(); j++) {
if (current_connected_ssid_name == ssid_list[j]) {
std::string temp = ssid_list[j];
ssid_list[j] = ssid_list[0];
ssid_list[0] = temp;
}
}
for (int k = 0; k < ssid_list.size(); k++) {
MKSLOG_RED("%s", ssid_list[k].c_str());
}
}
std::string rescan() {
MKSLOG("wpa_cli SCAN");
return wpa_cli("SCAN");
}
std::string save_wpa_conf() {
MKSLOG("Saving WPA config");
return wpa_cli("SAVE_CONFIG");
}
std::string wpa_cli(std::string command) {
char result[MAX_FILE_LEN];
std::string cmd = "wpa_cli " + command;
execute_cmd(cmd.data(), result);
return result;
}
// WifiChannels:
static std::string lookup(int freq) {
switch (freq)
{
case 2412:
return "2.4GHz 1";
break;
case 2417:
return "2.4GHz 2";
break;
case 2422:
return "2.4GHz 3";
break;
case 2427:
return "2.4GHz 4";
break;
case 2432:
return "2.4GHz 5";
break;
case 2437:
return "2.4GHz 6";
break;
case 2442:
return "2.4GHz 7";
break;
case 2447:
return "2.4GHz 8";
break;
case 2452:
return "2.4GHz 9";
break;
case 2457:
return "2.4GHz 10";
break;
case 2462:
return "2.4GHz 11";
break;
case 2467:
return "2.4GHz 12";
break;
case 2472:
return "2.4GHz 13";
break;
case 2484:
return "2.4GHz 14";
break;
case 5035:
return "5GHz 7";
break;
case 5040:
return "5GHz 8";
break;
case 5045:
return "5GHz 9";
break;
case 5055:
return "5GHz 11";
break;
case 5060:
return "5GHz 12";
break;
case 5080:
return "5GHz 16";
break;
case 5170:
return "5GHz 34";
break;
case 5180:
return "5GHz 36";
break;
case 5190:
return "5GHz 38";
break;
case 5200:
return "5GHz 40";
break;
case 5210:
return "5GHz 42";
break;
case 5220:
return "5GHz 44";
break;
case 5230:
return "5GHz 46";
break;
case 5240:
return "5GHz 48";
break;
case 5260:
return "5GHz 52";
break;
case 5280:
return "5GHz 56";
break;
case 5300:
return "5GHz 60";
break;
case 5320:
return "5GHz 64";
break;
case 5500:
return "5GHz 100";
break;
case 5560:
return "5GHz 112";
break;
case 5580:
return "5GHz 116";
break;
case 5600:
return "5GHz 120";
break;
case 5620:
return "5GHz 124";
break;
case 5640:
return "5GHz 128";
break;
case 5660:
return "5GHz 132";
break;
case 5680:
return "5GHz 136";
break;
case 5700:
return "5GHz 140";
break;
case 5720:
return "5GHz 144";
break;
case 5745:
return "5GHz 149";
break;
case 5765:
return "5GHz 153";
break;
case 5785:
return "5GHz 157";
break;
case 5805:
return "5GHz 161";
break;
case 5825:
return "5GHz 165";
break;
case 4915:
return "5GHz 183";
break;
case 4920:
return "5GHz 184";
break;
case 4925:
return "5GHz 185";
break;
case 4935:
return "5GHz 187";
break;
case 4940:
return "5GHz 188";
break;
case 4945:
return "5GHz 189";
break;
case 4960:
return "5GHz 192";
break;
case 4980:
return "5GHz 196";
break;
default:
return "";
break;
}
}
size_t printf_decode(unsigned char *buf, size_t maxlen, const char *str)
{
const char *pos = str;
size_t len = 0;
int val;
while (*pos) {
if (len + 1 >= maxlen)
break;
switch (*pos) {
case '\\':
pos++;
switch (*pos) {
case '\\':
buf[len++] = '\\';
pos++;
break;
case '"':
buf[len++] = '"';
pos++;
break;
case 'n':
buf[len++] = '\n';
pos++;
break;
case 'r':
buf[len++] = '\r';
pos++;
break;
case 't':
buf[len++] = '\t';
pos++;
break;
case 'e':
buf[len++] = '\033';
pos++;
break;
case 'x':
pos++;
val = hex2byte(pos);
if (val < 0) {
val = hex2num(*pos);
if (val < 0)
break;
buf[len++] = val;
pos++;
} else {
buf[len++] = val;
pos += 2;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
val = *pos++ - '0';
if (*pos >= '0' && *pos <= '7')
val = val * 8 + (*pos++ - '0');
if (*pos >= '0' && *pos <= '7')
val = val * 8 + (*pos++ - '0');
buf[len++] = val;
break;
default:
break;
}
break;
default:
buf[len++] = *pos++;
break;
}
}
if (maxlen > len)
buf[len] = '\0';
return len;
}
int hex2byte(const char *hex)
{
int a, b;
a = hex2num(*hex++);
if (a < 0)
return -1;
b = hex2num(*hex++);
if (b < 0)
return -1;
return (a << 4) | b;
}
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
int parse_scan_results(char* scan_results) {
result_list.clear();
level_list.clear();
ssid_list.clear();
char* lines[1024] = {0};
int num_lines = 0;
char* line = strtok(scan_results, "\n");
while (line != NULL) {
lines[num_lines++] = line;
line = strtok(NULL, "\n");
}
for (int i = 1; i < num_lines; ++i) {
char* fields[5] = {0};
int num_fields = 0;
char ssid_line[128] = {0};
memset(ssid_line, 0x00, sizeof(ssid_line));
strcpy(ssid_line, lines[i]);
int ssid_line_index = 0;
char* field = strtok(lines[i], " \t");
while (field != NULL) {
if (4 == num_fields) {
ssid_line_index = field - lines[i];
}
fields[num_fields++] = field;
field = strtok(NULL, " \t");
}
if (num_fields < 5) {
printf("Invalid scan result: %s\n", lines[i]);
continue;
} else {
unsigned char ssid_name[64];
printf_decode(ssid_name, 64, ssid_line + ssid_line_index);
if (ssid_name[0] == '\x00') {
} else {
ssid_list.push_back((char *)ssid_name);
}
}
if (strstr(fields[3], "ESS") && strstr(fields[3], "privacy") && strstr(fields[3], "hidden-ssid")) {
} else {
}
}
for (int j = 0; j < ssid_list.size(); j++) {
if (current_connected_ssid_name == ssid_list[j]) {
std::string temp = ssid_list[j];
ssid_list[j] = ssid_list[0];
ssid_list[0] = temp;
}
}
for (int k = 0; k < ssid_list.size(); k++) {
MKSLOG_RED("%s", ssid_list[k].c_str());
}
return 0;
}

476
src/MoonrakerAPI.cpp Normal file
View File

@@ -0,0 +1,476 @@
#include "../include/MoonrakerAPI.h"
#include "../include/MakerbaseCommand.h"
#include "nlohmann/json.hpp"
extern int response_type_id;
nlohmann::json string2json(std::string response) {
return nlohmann::json::parse(response);
}
inline std::string create_json_without_params(int cmd) {
response_type_id = cmd;
nlohmann::json api;
api["jsonrpc"] = "2.0";
api["method"] = method2command[cmd];
api["id"] = method2id[cmd];
return api.dump();
}
inline std::string create_json(int cmd, nlohmann::json params) {
response_type_id = cmd;
nlohmann::json api;
api["jsonrpc"] = "2.0";
api["method"] = method2command[cmd];
api["params"] = params;
api["id"] = method2id[cmd];
return api.dump();
}
std::string json_get_klippy_host_information() {
return create_json_without_params(0x03);
}
std::string json_emergency_stop() {
// return create_json(0x04, no_params, 4564);
return create_json_without_params(0x04);
}
std::string json_host_restart() {
return create_json_without_params(0x05);
}
std::string json_firmware_restart() {
return create_json_without_params(0x06);
}
std::string json_list_available_printer_objects() {
return create_json_without_params(0x11);
}
std::string json_query_printer_object_status(nlohmann::json objects) {
nlohmann::json params;
params["objects"] = objects;
return create_json(0x12, params);
}
std::string json_subscribe_to_printer_object_status(nlohmann::json objects) {
nlohmann::json params;
params["objects"] = objects;
return create_json(0x13, params);
}
std::string json_query_endstops() {
return create_json_without_params(0x14);
}
std::string json_query_server_info() {
return create_json_without_params(0x15);
}
std::string json_get_server_configuration() {
return create_json_without_params(0x16);
}
std::string json_request_cached_temperature_data() {
return create_json_without_params(0x17);
}
std::string json_request_cached_gcode_responses(int count) {
nlohmann::json params;
params["count"] = count;
return create_json(0x18, params);
}
std::string json_restart_server() {
return create_json_without_params(0x19);
}
/* GCode APIs */
std::string json_run_a_gcode(std::string script) {
nlohmann::json params;
params["script"] = script;
return create_json(0x21, params);
}
std::string json_get_gcode_help() {
return create_json_without_params(0x22);
}
/* Print Management */
std::string json_print_a_file(std::string filename) {
nlohmann::json params;
params["filename"] = filename;
return create_json(0x31, params);
}
std::string json_pause_a_print() {
return create_json_without_params(0x32);
}
std::string json_resume_a_print() {
return create_json_without_params(0x33);
}
std::string json_cancel_a_print() {
return create_json_without_params(0x34);
}
/* Machine Commands */
std::string json_get_system_info() {
return create_json_without_params(0x41);
}
std::string json_shutdown_the_operating_system(){
return create_json_without_params(0x42);
}
std::string json_reboot_the_operating_system() {
return create_json_without_params(0x43);
}
std::string json_restart_a_system_service(std::string name) {
nlohmann::json params;
params["service"] = name;
return create_json(0x44, params);
}
std::string json_stop_a_system_service(std::string name) {
nlohmann::json params;
params["service"] = name;
return create_json(0x45, params);
}
std::string json_start_a_system_service(std::string name) {
nlohmann::json params;
params["service"] = name;
return create_json(0x46, params);
}
std::string json_get_moonraker_process_stats() {
return create_json_without_params(0x47);
}
/* File Operations */
std::string json_list_available_files() {
nlohmann::json params;
// params["root"] = root_folder;
// return create_json(0x51, params);
return create_json_without_params(0x51);
}
std::string json_get_gcode_metadata(std::string filename) {
nlohmann::json params;
params["filename"] = filename;
return create_json(0x52, params);
}
std::string json_get_directory_information(bool extended) {
nlohmann::json params;
// params["path"] = path;
params["extended"] = extended;
return create_json(0x53, params);
}
std::string json_create_directory(std::string path) {
nlohmann::json params;
params["path"] = path;
return create_json(0x54, params);
}
std::string json_delete_directory(std::string path, bool force) {
nlohmann::json params;
params["path"] = path;
params["force"] = force;
return create_json(0x55, params);
}
std::string json_move_a_file_or_directory(std::string source, std::string dest) {
nlohmann::json params;
params["source"] = source;
params["dest"] = dest;
return create_json(0x56, params);
}
std::string json_copy_a_file_or_directory(std::string source, std::string dest) {
nlohmann::json params;
params["source"] = source;
params["dest"] = dest;
return create_json(0x57, params);
}
// std::string json_file_download() {
// return "";
// }
// std::string json_file_upload() {
// return "";
// }
std::string json_file_delete(std::string path) {
// path: {root}/{filename}
nlohmann::json params;
params["path"] = path;
return create_json(0x5a, params);
}
// std::string json_download_klippy_log() {
// return "";
// }
// std::string json_download_moonraker_log() {
// return "";
// }
/* Authorization */
// std::string json_login_user() {
// return "";
// }
// std::string json_logout_current_user() {
// return "";
// }
// std::string json_get_current_user() {
// return "";
// }
// std::string json_create_user() {
// return "";
// }
// std::string json_delete_user() {
// return "";
// }
// std::string json_list_available_users() {
// return "";
// }
// std::string json_reset_user_password() {
// return "";
// }
// std::string json_generate_a_oneshot_token() {
// return "";
// }
// std::string json_retrieve_information_about_authorization_endpoints() {
// return "";
// }
/* Database APIs */
std::string json_list_namespaces() {
return create_json_without_params(0x71);
}
std::string json_get_database_item(std::string nsp, std::string key) {
nlohmann::json params;
params["namespace"] = nsp;
params["key"] = key;
return create_json(0x72, params);
}
std::string json_add_database_item(std::string nsp, std::string key, int value) {
nlohmann::json params;
params["namespace"] = nsp;
params["key"] = key;
params["value"] = value;
return create_json(0x73, params);
}
std::string json_delete_database_item(std::string nsp, std::string key) {
nlohmann::json params;
params["namespace"] = nsp;
params["key"] = key;
return create_json(0x74, params);
}
/* Job Queue APIs */
std::string json_retrieve_the_job_queue_status() {
return create_json_without_params(0x81);
}
std::string json_enqueue_a_job(std::vector<std::string> filenames) {
nlohmann::json params;
params["filenames"] = filenames;
return create_json(0x82, params);
}
std::string json_remove_a_job(std::vector<std::string> job_ids) {
nlohmann::json params;
params["job_ids"] = job_ids;
return create_json(0x83, params);
}
std::string json_pause_the_job_queue() {
return create_json_without_params(0x84);
}
std::string json_start_the_job_queue() {
return create_json_without_params(0x85);
}
/* Announcement APIs */
std::string json_list_announcements(bool incluede_dismissed) {
nlohmann::json params;
params["include_dismissed"] = incluede_dismissed;
return create_json(0x86, params);
}
std::string json_update_announcements() {
return create_json_without_params(0x87);
}
std::string json_dismiss_an_announcement(std::string entry_id, int wake_time) {
nlohmann::json params;
params["entry_id"] = entry_id;
params["wake_time"] = wake_time;
return create_json(0x88, params);
}
std::string json_list_announcement_feeds() {
return create_json_without_params(0x89);
}
std::string json_add_an_announcement_feed(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x8a, params);
}
std::string json_remove_an_announcement_feed(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x8b, params);
}
/* Webcam APIs */
std::string json_list_webcams() {
return create_json_without_params(0x101);
}
std::string json_get_webcam_information(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x102, params);
}
std::string json_add_or_update_a_webcam(std::string name) {
nlohmann::json params;
params["name"] = name;
params["snapshot_url"] = "/webcam?action=snapshot";
params["stream_url"] = "/webcam?action=stream";
return create_json(0x103, params);
}
std::string json_delete_a_webcam(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x104, params);
}
std::string json_test_a_webcam(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x105, params);
}
/* Update Manager APIs */
std::string json_get_update_status(bool refresh) {
nlohmann::json params;
params["refresh"] = refresh;
return create_json(0x91, params);
}
/* Perform a full update */
std::string json_perform_a_full_update() {
return create_json_without_params(0x90);
}
std::string json_update_moonraker() {
return create_json_without_params(0x92);
}
std::string json_update_klipper() {
return create_json_without_params(0x93);
}
std::string json_update_client(std::string name) {
nlohmann::json params;
params["name"] = name;
return create_json(0x94, params);
}
std::string json_update_system_packages() {
return create_json_without_params(0x95);
}
std::string json_recover_a_corrupt_repo(std::string name, bool hard) {
nlohmann::json params;
params["name"] = name;
params["hard"] = hard;
return create_json(0x96, params);
}
/* Power APIs */
std::string json_get_device_list() {
return create_json_without_params(0xa1);
}
std::string json_get_device_status(std::string device) {
nlohmann::json params;
params["device"] = device;
return create_json(0xa2, params);
}
std::string json_get_device_state(std::string device, std::string action) {
nlohmann::json params;
params["device"] = device;
params["action"] = action;
return create_json(0xa3, params);
}
// std::string json_get_batch_device_status(std::string dev_x[]);
// std::string json_batch_power_on_devices(std::string dev_x[]);
// std::string json_batch_power_off_devices(std::string dev_x[]);
/* WLED APIs */
std::string json_get_strips() {
return create_json_without_params(0xb1);
}
std::string json_get_strip_status() {
nlohmann::json params;
params["lights"];
params["desk"];
return create_json(0xb2, params);
}
std::string json_turn_strip_on() {
nlohmann::json params;
params["lights"];
params["desk"];
return create_json(0xb3, params);
}
std::string json_turn_strip_off() {
nlohmann::json params;
params["lights"];
params["desk"];
return create_json(0xb4, params);
}
std::string json_toggle_strip_on_off_state() {
nlohmann::json params;
params["lights"];
params["desk"];
return create_json(0xb5, params);
}
std::string json_get_job_totals() {
return create_json_without_params(0xd2);
}
std::string json_reset_totals() {
return create_json_without_params(0xd3);
}

17
src/common.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include "../include/common.h"
void super_split(const std::string& s, std::vector<std::string>& v, const std::string& c) {
std::string::size_type pos1, pos2;
size_t len = s.length();
pos2 = s.find(c);
pos1 = 0;
while (std::string::npos != pos2)
{
v.emplace_back(s.substr(pos1, pos2 - pos1));
pos1 = pos2 + c.size();
}
if (pos1 != len) {
v.emplace_back(s.substr(pos1));
}
}

380
src/dictionary.cpp Normal file
View File

@@ -0,0 +1,380 @@
/*-------------------------------------------------------------------------*/
/**
@file dictionary.c
@author N. Devillard
@brief Implements a dictionary for string variables.
This module implements a simple dictionary object, i.e. a list
of string/string associations. This object is useful to store e.g.
informations retrieved from a configuration file (ini files).
*/
/*--------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
Includes
---------------------------------------------------------------------------*/
#include "dictionary.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/** Maximum value size for integers and doubles. */
#define MAXVALSZ 1024
/** Minimal allocated number of entries in a dictionary */
#define DICTMINSZ 128
/** Invalid key token */
#define DICT_INVALID_KEY ((char*)-1)
/*---------------------------------------------------------------------------
Private functions
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
@brief Duplicate a string
@param s String to duplicate
@return Pointer to a newly allocated string, to be freed with free()
This is a replacement for strdup(). This implementation is provided
for systems that do not have it.
*/
/*--------------------------------------------------------------------------*/
static char * xstrdup(const char * s)
{
char * t ;
size_t len ;
if (!s)
return NULL ;
len = strlen(s) + 1 ;
t = (char*) malloc(len) ;
if (t) {
memcpy(t, s, len) ;
}
return t ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Double the size of the dictionary
@param d Dictionary to grow
@return This function returns non-zero in case of failure
*/
/*--------------------------------------------------------------------------*/
static int dictionary_grow(dictionary * d)
{
char ** new_val ;
char ** new_key ;
unsigned * new_hash ;
new_val = (char**) calloc(d->size * 2, sizeof *d->val);
new_key = (char**) calloc(d->size * 2, sizeof *d->key);
new_hash = (unsigned*) calloc(d->size * 2, sizeof *d->hash);
if (!new_val || !new_key || !new_hash) {
/* An allocation failed, leave the dictionary unchanged */
if (new_val)
free(new_val);
if (new_key)
free(new_key);
if (new_hash)
free(new_hash);
return -1 ;
}
/* Initialize the newly allocated space */
memcpy(new_val, d->val, d->size * sizeof(char *));
memcpy(new_key, d->key, d->size * sizeof(char *));
memcpy(new_hash, d->hash, d->size * sizeof(unsigned));
/* Delete previous data */
free(d->val);
free(d->key);
free(d->hash);
/* Actually update the dictionary */
d->size *= 2 ;
d->val = new_val;
d->key = new_key;
d->hash = new_hash;
return 0 ;
}
/*---------------------------------------------------------------------------
Function codes
---------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/**
@brief Compute the hash key for a string.
@param key Character string to use for key.
@return 1 unsigned int on at least 32 bits.
This hash function has been taken from an Article in Dr Dobbs Journal.
This is normally a collision-free function, distributing keys evenly.
The key is stored anyway in the struct so that collision can be avoided
by comparing the key itself in last resort.
*/
/*--------------------------------------------------------------------------*/
unsigned dictionary_hash(const char * key)
{
size_t len ;
unsigned hash ;
size_t i ;
if (!key)
return 0 ;
len = strlen(key);
for (hash=0, i=0 ; i<len ; i++) {
hash += (unsigned)key[i] ;
hash += (hash<<10);
hash ^= (hash>>6) ;
}
hash += (hash <<3);
hash ^= (hash >>11);
hash += (hash <<15);
return hash ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Create a new dictionary object.
@param size Optional initial size of the dictionary.
@return 1 newly allocated dictionary object.
This function allocates a new dictionary object of given size and returns
it. If you do not know in advance (roughly) the number of entries in the
dictionary, give size=0.
*/
/*-------------------------------------------------------------------------*/
dictionary * dictionary_new(size_t size)
{
dictionary * d ;
/* If no size was specified, allocate space for DICTMINSZ */
if (size<DICTMINSZ) size=DICTMINSZ ;
d = (dictionary*) calloc(1, sizeof *d) ;
if (d) {
d->size = size ;
d->val = (char**) calloc(size, sizeof *d->val);
d->key = (char**) calloc(size, sizeof *d->key);
d->hash = (unsigned*) calloc(size, sizeof *d->hash);
}
return d ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Delete a dictionary object
@param d dictionary object to deallocate.
@return void
Deallocate a dictionary object and all memory associated to it.
*/
/*--------------------------------------------------------------------------*/
void dictionary_del(dictionary * d)
{
ssize_t i ;
if (d==NULL) return ;
for (i=0 ; i<d->size ; i++) {
if (d->key[i]!=NULL)
free(d->key[i]);
if (d->val[i]!=NULL)
free(d->val[i]);
}
free(d->val);
free(d->key);
free(d->hash);
free(d);
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get a value from a dictionary.
@param d dictionary object to search.
@param key Key to look for in the dictionary.
@param def Default value to return if key not found.
@return 1 pointer to internally allocated character string.
This function locates a key in a dictionary and returns a pointer to its
value, or the passed 'def' pointer if no such key can be found in
dictionary. The returned character pointer points to data internal to the
dictionary object, you should not try to free it or modify it.
*/
/*--------------------------------------------------------------------------*/
const char * dictionary_get(const dictionary * d, const char * key, const char * def)
{
unsigned hash ;
ssize_t i ;
hash = dictionary_hash(key);
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
/* Compare hash */
if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
return d->val[i] ;
}
}
}
return def ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Set a value in a dictionary.
@param d dictionary object to modify.
@param key Key to modify or add.
@param val Value to add.
@return int 0 if Ok, anything else otherwise
If the given key is found in the dictionary, the associated value is
replaced by the provided one. If the key cannot be found in the
dictionary, it is added to it.
It is Ok to provide a NULL value for val, but NULL values for the dictionary
or the key are considered as errors: the function will return immediately
in such a case.
Notice that if you dictionary_set a variable to NULL, a call to
dictionary_get will return a NULL value: the variable will be found, and
its value (NULL) is returned. In other words, setting the variable
content to NULL is equivalent to deleting the variable from the
dictionary. It is not possible (in this implementation) to have a key in
the dictionary without value.
This function returns non-zero in case of failure.
*/
/*--------------------------------------------------------------------------*/
int dictionary_set(dictionary * d, const char * key, const char * val)
{
ssize_t i ;
unsigned hash ;
if (d==NULL || key==NULL) return -1 ;
/* Compute hash for this key */
hash = dictionary_hash(key) ;
/* Find if value is already in dictionary */
if (d->n>0) {
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
if (hash==d->hash[i]) { /* Same hash value */
if (!strcmp(key, d->key[i])) { /* Same key */
/* Found a value: modify and return */
if (d->val[i]!=NULL)
free(d->val[i]);
d->val[i] = (val ? xstrdup(val) : NULL);
/* Value has been modified: return */
return 0 ;
}
}
}
}
/* Add a new value */
/* See if dictionary needs to grow */
if (d->n==d->size) {
/* Reached maximum size: reallocate dictionary */
if (dictionary_grow(d) != 0)
return -1;
}
/* Insert key in the first empty slot. Start at d->n and wrap at
d->size. Because d->n < d->size this will necessarily
terminate. */
for (i=d->n ; d->key[i] ; ) {
if(++i == d->size) i = 0;
}
/* Copy key */
d->key[i] = xstrdup(key);
d->val[i] = (val ? xstrdup(val) : NULL) ;
d->hash[i] = hash;
d->n ++ ;
return 0 ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Delete a key in a dictionary
@param d dictionary object to modify.
@param key Key to remove.
@return void
This function deletes a key in a dictionary. Nothing is done if the
key cannot be found.
*/
/*--------------------------------------------------------------------------*/
void dictionary_unset(dictionary * d, const char * key)
{
unsigned hash ;
ssize_t i ;
if (key == NULL || d == NULL) {
return;
}
hash = dictionary_hash(key);
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
/* Compare hash */
if (hash==d->hash[i]) {
/* Compare string, to avoid hash collisions */
if (!strcmp(key, d->key[i])) {
/* Found key */
break ;
}
}
}
if (i>=d->size)
/* Key not found */
return ;
free(d->key[i]);
d->key[i] = NULL ;
if (d->val[i]!=NULL) {
free(d->val[i]);
d->val[i] = NULL ;
}
d->hash[i] = 0 ;
d->n -- ;
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump
@param f Opened file pointer.
@return void
Dumps a dictionary onto an opened file pointer. Key pairs are printed out
as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as
output file pointers.
*/
/*--------------------------------------------------------------------------*/
void dictionary_dump(const dictionary * d, FILE * out)
{
ssize_t i ;
if (d==NULL || out==NULL) return ;
if (d->n<1) {
fprintf(out, "empty dictionary\n");
return ;
}
for (i=0 ; i<d->size ; i++) {
if (d->key[i]) {
fprintf(out, "%20s\t[%s]\n",
d->key[i],
d->val[i] ? d->val[i] : "UNDEF");
}
}
return ;
}

3496
src/event.cpp Normal file

File diff suppressed because it is too large Load Diff

836
src/iniparser.cpp Normal file
View File

@@ -0,0 +1,836 @@
/*-------------------------------------------------------------------------*/
/**
@file iniparser.c
@author N. Devillard
@brief Parser for ini files.
*/
/*--------------------------------------------------------------------------*/
/*---------------------------- Includes ------------------------------------*/
#include <ctype.h>
#include <stdarg.h>
#include "iniparser.h"
/*---------------------------- Defines -------------------------------------*/
#define ASCIILINESZ (1024)
#define INI_INVALID_KEY ((char*)-1)
/*---------------------------------------------------------------------------
Private to this module
---------------------------------------------------------------------------*/
/**
* This enum stores the status for each parsed line (internal use only).
*/
typedef enum _line_status_ {
LINE_UNPROCESSED,
LINE_ERROR,
LINE_EMPTY,
LINE_COMMENT,
LINE_SECTION,
LINE_VALUE
} line_status ;
/*-------------------------------------------------------------------------*/
/**
@brief Convert a string to lowercase.
@param in String to convert.
@param out Output buffer.
@param len Size of the out buffer.
@return ptr to the out buffer or NULL if an error occured.
This function convert a string into lowercase.
At most len - 1 elements of the input string will be converted.
*/
/*--------------------------------------------------------------------------*/
static const char * strlwc(const char * in, char *out, unsigned len)
{
unsigned i ;
if (in==NULL || out == NULL || len==0) return NULL ;
i=0 ;
while (in[i] != '\0' && i < len-1) {
out[i] = (char)tolower((int)in[i]);
i++ ;
}
out[i] = '\0';
return out ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Duplicate a string
@param s String to duplicate
@return Pointer to a newly allocated string, to be freed with free()
This is a replacement for strdup(). This implementation is provided
for systems that do not have it.
*/
/*--------------------------------------------------------------------------*/
static char * xstrdup(const char * s)
{
char * t ;
size_t len ;
if (!s)
return NULL ;
len = strlen(s) + 1 ;
t = (char*) malloc(len) ;
if (t) {
memcpy(t, s, len) ;
}
return t ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Remove blanks at the beginning and the end of a string.
@param str String to parse and alter.
@return unsigned New size of the string.
*/
/*--------------------------------------------------------------------------*/
static unsigned strstrip(char * s)
{
char *last = NULL ;
char *dest = s;
if (s==NULL) return 0;
last = s + strlen(s);
while (isspace((int)*s) && *s) s++;
while (last > s) {
if (!isspace((int)*(last-1)))
break ;
last -- ;
}
*last = (char)0;
memmove(dest,s,last - s + 1);
return last - s;
}
/*-------------------------------------------------------------------------*/
/**
@brief Default error callback for iniparser: wraps `fprintf(stderr, ...)`.
*/
/*--------------------------------------------------------------------------*/
static int default_error_callback(const char *format, ...)
{
int ret;
va_list argptr;
va_start(argptr, format);
ret = vfprintf(stderr, format, argptr);
va_end(argptr);
return ret;
}
static int (*iniparser_error_callback)(const char*, ...) = default_error_callback;
/*-------------------------------------------------------------------------*/
/**
@brief Configure a function to receive the error messages.
@param errback Function to call.
By default, the error will be printed on stderr. If a null pointer is passed
as errback the error callback will be switched back to default.
*/
/*--------------------------------------------------------------------------*/
void iniparser_set_error_callback(int (*errback)(const char *, ...))
{
if (errback) {
iniparser_error_callback = errback;
} else {
iniparser_error_callback = default_error_callback;
}
}
/*-------------------------------------------------------------------------*/
/**
@brief Get number of sections in a dictionary
@param d Dictionary to examine
@return int Number of sections found in dictionary
This function returns the number of sections found in a dictionary.
The test to recognize sections is done on the string stored in the
dictionary: a section name is given as "section" whereas a key is
stored as "section:key", thus the test looks for entries that do not
contain a colon.
This clearly fails in the case a section name contains a colon, but
this should simply be avoided.
This function returns -1 in case of error.
*/
/*--------------------------------------------------------------------------*/
int iniparser_getnsec(const dictionary * d)
{
int i ;
int nsec ;
if (d==NULL) return -1 ;
nsec=0 ;
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
if (strchr(d->key[i], ':')==NULL) {
nsec ++ ;
}
}
return nsec ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get name for section n in a dictionary.
@param d Dictionary to examine
@param n Section number (from 0 to nsec-1).
@return Pointer to char string
This function locates the n-th section in a dictionary and returns
its name as a pointer to a string statically allocated inside the
dictionary. Do not free or modify the returned string!
This function returns NULL in case of error.
*/
/*--------------------------------------------------------------------------*/
const char * iniparser_getsecname(const dictionary * d, int n)
{
int i ;
int foundsec ;
if (d==NULL || n<0) return NULL ;
foundsec=0 ;
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
if (strchr(d->key[i], ':')==NULL) {
foundsec++ ;
if (foundsec>n)
break ;
}
}
if (foundsec<=n) {
return NULL ;
}
return d->key[i] ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Dump a dictionary to an opened file pointer.
@param d Dictionary to dump.
@param f Opened file pointer to dump to.
@return void
This function prints out the contents of a dictionary, one element by
line, onto the provided file pointer. It is OK to specify @c stderr
or @c stdout as output files. This function is meant for debugging
purposes mostly.
*/
/*--------------------------------------------------------------------------*/
void iniparser_dump(const dictionary * d, FILE * f)
{
int i ;
if (d==NULL || f==NULL) return ;
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
if (d->val[i]!=NULL) {
fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);
} else {
fprintf(f, "[%s]=UNDEF\n", d->key[i]);
}
}
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Save a dictionary to a loadable ini file
@param d Dictionary to dump
@param f Opened file pointer to dump to
@return void
This function dumps a given dictionary into a loadable ini file.
It is Ok to specify @c stderr or @c stdout as output files.
*/
/*--------------------------------------------------------------------------*/
void iniparser_dump_ini(const dictionary * d, FILE * f)
{
int i ;
int nsec ;
const char * secname ;
if (d==NULL || f==NULL) return ;
nsec = iniparser_getnsec(d);
if (nsec<1) {
/* No section in file: dump all keys as they are */
for (i=0 ; i<d->size ; i++) {
if (d->key[i]==NULL)
continue ;
fprintf(f, "%s = %s\n", d->key[i], d->val[i]);
}
return ;
}
for (i=0 ; i<nsec ; i++) {
secname = iniparser_getsecname(d, i) ;
iniparser_dumpsection_ini(d, secname, f);
}
fprintf(f, "\n");
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Save a dictionary section to a loadable ini file
@param d Dictionary to dump
@param s Section name of dictionary to dump
@param f Opened file pointer to dump to
@return void
This function dumps a given section of a given dictionary into a loadable ini
file. It is Ok to specify @c stderr or @c stdout as output files.
*/
/*--------------------------------------------------------------------------*/
void iniparser_dumpsection_ini(const dictionary * d, const char * s, FILE * f)
{
int j ;
char keym[ASCIILINESZ+1];
int seclen ;
if (d==NULL || f==NULL) return ;
if (! iniparser_find_entry(d, s)) return ;
seclen = (int)strlen(s);
fprintf(f, "\n[%s]\n", s);
sprintf(keym, "%s:", s);
for (j=0 ; j<d->size ; j++) {
if (d->key[j]==NULL)
continue ;
if (!strncmp(d->key[j], keym, seclen+1)) {
fprintf(f,
"%-30s = %s\n",
d->key[j]+seclen+1,
d->val[j] ? d->val[j] : "");
}
}
fprintf(f, "\n");
return ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the number of keys in a section of a dictionary.
@param d Dictionary to examine
@param s Section name of dictionary to examine
@return Number of keys in section
*/
/*--------------------------------------------------------------------------*/
int iniparser_getsecnkeys(const dictionary * d, const char * s)
{
int seclen, nkeys ;
char keym[ASCIILINESZ+1];
int j ;
nkeys = 0;
if (d==NULL) return nkeys;
if (! iniparser_find_entry(d, s)) return nkeys;
seclen = (int)strlen(s);
strlwc(s, keym, sizeof(keym));
keym[seclen] = ':';
for (j=0 ; j<d->size ; j++) {
if (d->key[j]==NULL)
continue ;
if (!strncmp(d->key[j], keym, seclen+1))
nkeys++;
}
return nkeys;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the number of keys in a section of a dictionary.
@param d Dictionary to examine
@param s Section name of dictionary to examine
@param keys Already allocated array to store the keys in
@return The pointer passed as `keys` argument or NULL in case of error
This function queries a dictionary and finds all keys in a given section.
The keys argument should be an array of pointers which size has been
determined by calling `iniparser_getsecnkeys` function prior to this one.
Each pointer in the returned char pointer-to-pointer is pointing to
a string allocated in the dictionary; do not free or modify them.
*/
/*--------------------------------------------------------------------------*/
const char ** iniparser_getseckeys(const dictionary * d, const char * s, const char ** keys)
{
int i, j, seclen ;
char keym[ASCIILINESZ+1];
if (d==NULL || keys==NULL) return NULL;
if (! iniparser_find_entry(d, s)) return NULL;
seclen = (int)strlen(s);
strlwc(s, keym, sizeof(keym));
keym[seclen] = ':';
i = 0;
for (j=0 ; j<d->size ; j++) {
if (d->key[j]==NULL)
continue ;
if (!strncmp(d->key[j], keym, seclen+1)) {
keys[i] = d->key[j];
i++;
}
}
return keys;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key
@param d Dictionary to search
@param key Key string to look for
@param def Default value to return if key not found.
@return pointer to statically allocated character string
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the pointer passed as 'def' is returned.
The returned char pointer is pointing to a string allocated in
the dictionary, do not free or modify it.
*/
/*--------------------------------------------------------------------------*/
const char * iniparser_getstring(const dictionary * d, const char * key, const char * def)
{
const char * lc_key ;
const char * sval ;
char tmp_str[ASCIILINESZ+1];
if (d==NULL || key==NULL)
return def ;
lc_key = strlwc(key, tmp_str, sizeof(tmp_str));
sval = dictionary_get(d, lc_key, def);
return sval ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to an long int
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return long integer
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
Supported values for integers include the usual C notation
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
are supported. Examples:
"42" -> 42
"042" -> 34 (octal -> decimal)
"0x42" -> 66 (hexa -> decimal)
Warning: the conversion may overflow in various ways. Conversion is
totally outsourced to strtol(), see the associated man page for overflow
handling.
Credits: Thanks to A. Becker for suggesting strtol()
*/
/*--------------------------------------------------------------------------*/
long int iniparser_getlongint(const dictionary * d, const char * key, long int notfound)
{
const char * str ;
str = iniparser_getstring(d, key, INI_INVALID_KEY);
if (str==INI_INVALID_KEY) return notfound ;
return strtol(str, NULL, 0);
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to an int
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return integer
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
Supported values for integers include the usual C notation
so decimal, octal (starting with 0) and hexadecimal (starting with 0x)
are supported. Examples:
"42" -> 42
"042" -> 34 (octal -> decimal)
"0x42" -> 66 (hexa -> decimal)
Warning: the conversion may overflow in various ways. Conversion is
totally outsourced to strtol(), see the associated man page for overflow
handling.
Credits: Thanks to A. Becker for suggesting strtol()
*/
/*--------------------------------------------------------------------------*/
int iniparser_getint(const dictionary * d, const char * key, int notfound)
{
return (int)iniparser_getlongint(d, key, notfound);
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a double
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return double
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
*/
/*--------------------------------------------------------------------------*/
double iniparser_getdouble(const dictionary * d, const char * key, double notfound)
{
const char * str ;
str = iniparser_getstring(d, key, INI_INVALID_KEY);
if (str==INI_INVALID_KEY) return notfound ;
return atof(str);
}
/*-------------------------------------------------------------------------*/
/**
@brief Get the string associated to a key, convert to a boolean
@param d Dictionary to search
@param key Key string to look for
@param notfound Value to return in case of error
@return integer
This function queries a dictionary for a key. A key as read from an
ini file is given as "section:key". If the key cannot be found,
the notfound value is returned.
A true boolean is found if one of the following is matched:
- A string starting with 'y'
- A string starting with 'Y'
- A string starting with 't'
- A string starting with 'T'
- A string starting with '1'
A false boolean is found if one of the following is matched:
- A string starting with 'n'
- A string starting with 'N'
- A string starting with 'f'
- A string starting with 'F'
- A string starting with '0'
The notfound value returned if no boolean is identified, does not
necessarily have to be 0 or 1.
*/
/*--------------------------------------------------------------------------*/
int iniparser_getboolean(const dictionary * d, const char * key, int notfound)
{
int ret ;
const char * c ;
c = iniparser_getstring(d, key, INI_INVALID_KEY);
if (c==INI_INVALID_KEY) return notfound ;
if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') {
ret = 1 ;
} else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') {
ret = 0 ;
} else {
ret = notfound ;
}
return ret;
}
/*-------------------------------------------------------------------------*/
/**
@brief Finds out if a given entry exists in a dictionary
@param ini Dictionary to search
@param entry Name of the entry to look for
@return integer 1 if entry exists, 0 otherwise
Finds out if a given entry exists in the dictionary. Since sections
are stored as keys with NULL associated values, this is the only way
of querying for the presence of sections in a dictionary.
*/
/*--------------------------------------------------------------------------*/
int iniparser_find_entry(const dictionary * ini, const char * entry)
{
int found=0 ;
if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) {
found = 1 ;
}
return found ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Set an entry in a dictionary.
@param ini Dictionary to modify.
@param entry Entry to modify (entry name)
@param val New value to associate to the entry.
@return int 0 if Ok, -1 otherwise.
If the given entry can be found in the dictionary, it is modified to
contain the provided value. If it cannot be found, the entry is created.
It is Ok to set val to NULL.
*/
/*--------------------------------------------------------------------------*/
int iniparser_set(dictionary * ini, const char * entry, const char * val)
{
char tmp_str[ASCIILINESZ+1];
return dictionary_set(ini, strlwc(entry, tmp_str, sizeof(tmp_str)), val) ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Delete an entry in a dictionary
@param ini Dictionary to modify
@param entry Entry to delete (entry name)
@return void
If the given entry can be found, it is deleted from the dictionary.
*/
/*--------------------------------------------------------------------------*/
void iniparser_unset(dictionary * ini, const char * entry)
{
char tmp_str[ASCIILINESZ+1];
dictionary_unset(ini, strlwc(entry, tmp_str, sizeof(tmp_str)));
}
/*-------------------------------------------------------------------------*/
/**
@brief Load a single line from an INI file
@param input_line Input line, may be concatenated multi-line input
@param section Output space to store section
@param key Output space to store key
@param value Output space to store value
@return line_status value
*/
/*--------------------------------------------------------------------------*/
static line_status iniparser_line(
const char * input_line,
char * section,
char * key,
char * value)
{
line_status sta ;
char * line = NULL;
size_t len ;
line = xstrdup(input_line);
len = strstrip(line);
sta = LINE_UNPROCESSED ;
if (len<1) {
/* Empty line */
sta = LINE_EMPTY ;
} else if (line[0]=='#' || line[0]==';') {
/* Comment line */
sta = LINE_COMMENT ;
} else if (line[0]=='[' && line[len-1]==']') {
/* Section name */
sscanf(line, "[%[^]]", section);
strstrip(section);
strlwc(section, section, len);
sta = LINE_SECTION ;
} else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2
|| sscanf (line, "%[^=] = '%[^\']'", key, value) == 2) {
/* Usual key=value with quotes, with or without comments */
strstrip(key);
strlwc(key, key, len);
/* Don't strip spaces from values surrounded with quotes */
sta = LINE_VALUE ;
} else if (sscanf (line, "%[^=] = %[^;#]", key, value) == 2) {
/* Usual key=value without quotes, with or without comments */
strstrip(key);
strlwc(key, key, len);
strstrip(value);
/*
* sscanf cannot handle '' or "" as empty values
* this is done here
*/
if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) {
value[0]=0 ;
}
sta = LINE_VALUE ;
} else if (sscanf(line, "%[^=] = %[;#]", key, value)==2
|| sscanf(line, "%[^=] %[=]", key, value) == 2) {
/*
* Special cases:
* key=
* key=;
* key=#
*/
strstrip(key);
strlwc(key, key, len);
value[0]=0 ;
sta = LINE_VALUE ;
} else {
/* Generate syntax error */
sta = LINE_ERROR ;
}
free(line);
return sta ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Parse an ini file and return an allocated dictionary object
@param ininame Name of the ini file to read.
@return Pointer to newly allocated dictionary
This is the parser for ini files. This function is called, providing
the name of the file to be read. It returns a dictionary object that
should not be accessed directly, but through accessor functions
instead.
The returned dictionary must be freed using iniparser_freedict().
*/
/*--------------------------------------------------------------------------*/
dictionary * iniparser_load(const char * ininame)
{
FILE * in ;
char line [ASCIILINESZ+1] ;
char section [ASCIILINESZ+1] ;
char key [ASCIILINESZ+1] ;
char tmp [(ASCIILINESZ * 2) + 2] ;
char val [ASCIILINESZ+1] ;
int last=0 ;
int len ;
int lineno=0 ;
int errs=0;
int mem_err=0;
dictionary * dict ;
if ((in=fopen(ininame, "r"))==NULL) {
iniparser_error_callback("iniparser: cannot open %s\n", ininame);
return NULL ;
}
dict = dictionary_new(0) ;
if (!dict) {
fclose(in);
return NULL ;
}
memset(line, 0, ASCIILINESZ);
memset(section, 0, ASCIILINESZ);
memset(key, 0, ASCIILINESZ);
memset(val, 0, ASCIILINESZ);
last=0 ;
while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) {
lineno++ ;
len = (int)strlen(line)-1;
if (len<=0)
continue;
/* Safety check against buffer overflows */
if (line[len]!='\n' && !feof(in)) {
iniparser_error_callback(
"iniparser: input line too long in %s (%d)\n",
ininame,
lineno);
dictionary_del(dict);
fclose(in);
return NULL ;
}
/* Get rid of \n and spaces at end of line */
while ((len>=0) &&
((line[len]=='\n') || (isspace(line[len])))) {
line[len]=0 ;
len-- ;
}
if (len < 0) { /* Line was entirely \n and/or spaces */
len = 0;
}
/* Detect multi-line */
if (line[len]=='\\') {
/* Multi-line value */
last=len ;
continue ;
} else {
last=0 ;
}
switch (iniparser_line(line, section, key, val)) {
case LINE_EMPTY:
case LINE_COMMENT:
break ;
case LINE_SECTION:
mem_err = dictionary_set(dict, section, NULL);
break ;
case LINE_VALUE:
sprintf(tmp, "%s:%s", section, key);
mem_err = dictionary_set(dict, tmp, val);
break ;
case LINE_ERROR:
iniparser_error_callback(
"iniparser: syntax error in %s (%d):\n-> %s\n",
ininame,
lineno,
line);
errs++ ;
break;
default:
break ;
}
memset(line, 0, ASCIILINESZ);
last=0;
if (mem_err<0) {
iniparser_error_callback("iniparser: memory allocation failure\n");
break ;
}
}
if (errs) {
dictionary_del(dict);
dict = NULL ;
}
fclose(in);
return dict ;
}
/*-------------------------------------------------------------------------*/
/**
@brief Free all memory associated to an ini dictionary
@param d Dictionary to free
@return void
Free all memory associated to an ini dictionary.
It is mandatory to call this function before the dictionary object
gets out of the current context.
*/
/*--------------------------------------------------------------------------*/
void iniparser_freedict(dictionary * d)
{
dictionary_del(d);
}

10
src/mks_error.cpp Normal file
View File

@@ -0,0 +1,10 @@
#include "../include/MoonrakerAPI.h"
#include "../include/mks_error.h"
#include "../include/event.h"
void parse_error(nlohmann::json error) {
std::cout << error << std::endl;
}

471
src/mks_file.cpp Normal file
View File

@@ -0,0 +1,471 @@
#include <iostream>
#include <stack>
#include <set>
#include <fstream>
#include <string>
#include <sstream>
#include "../include/send_msg.h"
#include "../include/mks_file.h"
#include "../include/KlippyRest.h"
#include "../include/event.h"
#include "../include/ui.h"
#include "../include/mks_preview.h"
// List available files
// Get gcode metadata
std::string file_filename; // 文件名
std::string file_current_filename; // 当前文件名
std::string file_previous_filename; // 先前文件名
float file_filament_total; // 用料
float file_estimated_time; // 文件预估时间
// Directory
std::stack<std::string> file_path_stack; // 路径栈
std::string file_root_path; // Gcodes根目录
std::string file_previous_path; // 之前的路径
std::string file_current_path; // 文件当前所在的路径
std::string file_print_path; // 要打印的文件路径
// 文件管理
std::set<std::string> server_files_list; // gcodes文件列表
std::set<std::string> server_files_get_directroy; // 路径下面的目录列表
std::set<std::string> newfiles;
std::set<std::string> deletedfiles;
std::set<std::string> updatedfiles;
// 解析文件内容相关
std::set<std::string> page_files_dirname_list;
std::set<std::string> page_files_filename_list;
std::set<std::string> page_files_dirname_filename_list;
std::string page_files_last_printing_files_dir;
bool page_files_is_last_print_files_dir;
// 文件列表相关处理变量
bool filelist_changed = false;
int page_files_pages;
int page_files_current_pages;
int page_files_folder_layers;
std::string page_files_list_name[9] = {"", "", "", "", "", "", "", "", ""}; // 文件列表显示文件名称
std::string page_files_list_show_name[9] = {"", "", "", "", "", "", "", "", ""}; // 文件列表名称
std::string page_files_list_show_type[9] = {"[n]", "[n]", "[n]", "[n]", "[n]", "[n]", "[n]", "[n]", "[n]"}; // 文件类型: [f]或者[d],或者[n]
bool page_files_refresh_status = false;
std::stack<std::string> page_files_path_stack; // 路径栈
std::string page_files_root_path; // Klippy根目录
std::string page_files_previous_path; // 之前的路径
std::string page_files_path; // 文件所在路径
std::string page_files_print_files_path; // 要打印的文件路径
int file_metadata_estimated_time = 0;
std::string file_metadata_filename;
float file_metadata_filament_total = 0.0;
int file_metadata_object_height = 0;
std::string file_metadata_filament_name;
std::string file_metadata_filament_type;
float file_metadata_filament_weight_total = 0.0;
std::string file_metadata_gimage;
std::string file_metadata_simage;
bool mks_file_parse_finished = false;
extern bool show_preview_complete;
extern int current_page_id;
//4.4.2 CLL 文件列表页面新增本地、U盘按钮
extern std::string file_mode;
extern bool jump_to_print;
std::string thumbnail_relative_path;
std::string thumbnail_path;
bool cache_clicked = false;
void parse_file_estimated_time(nlohmann::json response) {
if (response["result"]["estimated_time"] != nlohmann::detail::value_t::null) {
file_metadata_estimated_time = (float)response["result"]["estimated_time"];
}
if (response["result"]["filename"] != nlohmann::detail::value_t::null) {
file_metadata_filename = response["result"]["filename"];
}
if (response["result"]["filament_total"] != nlohmann::detail::value_t::null) {
file_metadata_filament_total = (int)response["result"]["filament_total"];
MKSLOG_RED("用料长度%f", file_metadata_filament_total);
}
if (response["result"]["object_height"] != nlohmann::detail::value_t::null) {
file_metadata_object_height = (int)response["result"]["object_height"];
}
if (response["result"]["filament_name"] != nlohmann::detail::value_t::null) {
file_metadata_filament_name = response["result"]["filament_name"];
}
if (response["result"]["filament_type"] != nlohmann::detail::value_t::null) {
file_metadata_filament_type = response["result"]["filament_type"];
}
if (response["result"]["filament_weight_total"] != nlohmann::detail::value_t::null) {
file_metadata_filament_weight_total = response["result"]["filament_weight_total"];
}
if (response["result"]["gimage"] != nlohmann::detail::value_t::null) {
file_metadata_gimage = response["result"]["gimage"];
}
if (response["result"]["simage"] != nlohmann::detail::value_t::null) {
file_metadata_simage = response["result"]["simage"];
}
if (response["result"]["thumbnails"] != nlohmann::detail::value_t::null) {
for (int i = 0; response["result"]["thumbnails"][i] != nlohmann::detail::value_t::null; i++) {
if (response["result"]["thumbnails"][i]["width"] == 168|| response["result"]["thumbnails"][i]["width"] == 300) {
thumbnail_relative_path = response["result"]["thumbnails"][i]["relative_path"];
if (getParentDirectory(file_metadata_filename) == "") {
thumbnail_path = thumbnail_relative_path;
} else {
thumbnail_path = getParentDirectory(file_metadata_filename) + "/" + thumbnail_relative_path;
}
MKSLOG_RED("图片路径%s", thumbnail_path.c_str());
break;
}
if (response["result"]["thumbnails"][i] == nlohmann::detail::value_t::null) {
thumbnail_relative_path.clear();
thumbnail_path.clear();
}
}
}
mks_file_parse_finished = true;
}
void parse_server_files_list(nlohmann::json result) {
server_files_list.clear();
std::string path_temp = "";
for (int i = 0; i < result.size(); i++) {
path_temp = result[i]["path"];
server_files_list.insert(path_temp);
}
}
void parse_server_files_get_directory(nlohmann::json result) {
server_files_get_directroy.clear();
server_files_list.clear();
std::string dirname_temp = "";
std::string filename_temp = "";
for (int i = 0; i < result["dirs"].size(); i++) {
std::cout << result["dirs"][i]["dirname"] << std::endl;
dirname_temp = result["dirs"][i]["dirname"];
server_files_list.insert(filename_temp);
}
for (int j = 0; j < result["files"].size(); j++) {
std::cout << result["files"][j]["filename"] << std::endl;
filename_temp = result["files"][j]["filename"];
server_files_list.insert(filename_temp);
}
}
void parse_server_files_metadata(nlohmann::json result) {
}
void parse_create_directory(nlohmann::json result) {
std::cout << "path: " << result["item"]["path"] << std::endl;
std::cout << "root: " << result["item"]["root"] << std::endl;
std::cout << "action: " << result["action"] << std::endl;
}
void parse_delete_directory(nlohmann::json result) {
std::cout << "path: " << result["item"]["path"] << std::endl;
std::cout << "root: " << result["item"]["root"] << std::endl;
}
void parse_move_a_file_or_directory(nlohmann::json result) {
std::cout << "item: " << result["item"] << std::endl;
std::cout << "source_item" << result["source_item"] << std::endl;
std::cout << "action: " << result["action"] << std::endl;
}
void parse_copy_a_file_or_directory(nlohmann::json result) {
std::cout << "root: " << result["item"]["root"] << std::endl;
std::cout << "path: " << result["item"]["path"] << std::endl;
std::cout << "action: " << result["action"] << std::endl;
}
void parse_file_delete(nlohmann::json result) {
std::cout << "path: " << result["item"]["path"] << std::endl;
std::cout << "root: " << result["item"]["root"] << std::endl;
std::cout << "action: " << result["action"] << std::endl;
}
// 获取文件列表信息
void get_page_files_filelist(std::string current_dir) {
if (page_files_last_printing_files_dir == current_dir) {
page_files_is_last_print_files_dir = true;
} else {
page_files_is_last_print_files_dir = false;
}
page_files_dirname_list.clear();
page_files_filename_list.clear();
page_files_dirname_filename_list.clear();
nlohmann::json json_temp;
nlohmann::json result;
//4.4.2 CLL 新增在文件首页第一个显示打印过文件
std::string temp_dirname = "";
std::string temp_filename = "";
std::string json_files_directory = send_request("localhost", "7125", "server/files/directory?path=gcodes//.cache", "GET");
if (json_files_directory != "" && page_files_folder_layers == 0) {
json_temp = nlohmann::json::parse(json_files_directory);
result = json_temp["result"];
if (0 < result["files"].size()) {
std::cout << result["files"][0]["filename"] << std::endl;
temp_filename = result["files"][0]["filename"];
if (temp_filename.find(".gcode") != -1) {
if (temp_filename.find(".") != 0) {
page_files_filename_list.insert(temp_filename);
auto it = page_files_filename_list.begin();
page_files_dirname_filename_list.insert("[c] " + *it);
page_files_filename_list.clear();
}
}
}
}
json_files_directory = send_request("localhost", "7125", "server/files/directory?path=" + current_dir, "GET");
if (json_files_directory != "") {
json_temp = nlohmann::json::parse(json_files_directory);
result = json_temp["result"];
}
for (int i = 0; i < result["dirs"].size(); i++) {
temp_dirname = result["dirs"][i]["dirname"];
if (temp_dirname != "System Volume Information" && temp_dirname.find(".") != 0 && temp_dirname != "sda1") {
page_files_dirname_list.insert(temp_dirname);
}
}
for (int j = 0; j < result["files"].size(); j++) {
std::cout << result["files"][j]["filename"] << std::endl;
temp_filename = result["files"][j]["filename"];
if (temp_filename.find(".gcode") != -1) {
if (temp_filename.find(".") != 0) {
page_files_filename_list.insert(temp_filename);
}
}
}
for (auto it = page_files_dirname_list.begin(); it != page_files_dirname_list.end(); it++) {
page_files_dirname_filename_list.insert("[d] " + *it);
}
for (auto it = page_files_filename_list.begin(); it != page_files_filename_list.end(); it++) {
page_files_dirname_filename_list.insert("[f] " + *it);
}
if (0 == page_files_dirname_filename_list.size() % 4) { // CLL 此函数后的除数为一页所包含的文件数
page_files_pages = page_files_dirname_filename_list.size() / 4 - 1;
if (page_files_pages <= 0) {
page_files_pages = 0;
}
} else {
page_files_pages = page_files_dirname_filename_list.size() / 4;
}
}
void set_page_files_show_list(int pages) {
page_files_list_name[0] = "";
page_files_list_name[1] = "";
page_files_list_name[2] = "";
page_files_list_name[3] = "";
auto it = page_files_dirname_filename_list.begin();
for (int i = 0; i < pages * 4; i++) {
it++;
std::cout << *it << std::endl;
}
for (int i = 0; i < 4; i++) {
if (it != page_files_dirname_filename_list.end()) {
page_files_list_name[i] = *it;
it++;
}
}
// 打印测试
for (int j = 0; j < 4; j++) {
if (page_files_list_name[j] != "") {
page_files_list_show_type[j] = page_files_list_name[j].substr(0, 3);
page_files_list_show_name[j] = page_files_list_name[j].substr(4);
} else {
page_files_list_show_type[j] = "[n]";
page_files_list_show_name[j] = "";
}
}
}
void get_sub_dir_files_list(int button) {
//4.4.2 CLL 在文件列表界面第一页显示打印过文件
if ("[c]" == page_files_list_show_type[button]) {
jump_to_print = false;
show_preview_complete = false;
cache_clicked = true;
page_files_path_stack.push(page_files_path);
page_files_print_files_path = page_files_path + "/.cache/" + page_files_list_show_name[button];
page_files_folder_layers++;
get_file_estimated_time(page_files_print_files_path.substr(1));
page_to(TJC_PAGE_PREVIEW);
} else if ("[d]" == page_files_list_show_type[button]) {
page_files_path_stack.push(page_files_path);
page_files_path = page_files_path + "/" + page_files_list_show_name[button];
page_files_folder_layers++;
page_to(TJC_PAGE_FILE_LIST);
page_files_current_pages = 0;
refresh_page_files(page_files_current_pages);
refresh_page_files_list();
} else if ("[f]" == page_files_list_show_type[button]) {
jump_to_print = false;
show_preview_complete = false;
cache_clicked = false;
page_files_path_stack.push(page_files_path);
page_files_print_files_path = page_files_path + "/" + page_files_list_show_name[button];
page_files_folder_layers++;
MKSLOG("%s", page_files_print_files_path.substr(1).c_str());
get_file_estimated_time(page_files_print_files_path.substr(1));
page_to(TJC_PAGE_PREVIEW);
}
}
void get_parenet_dir_files_list() {
page_files_previous_path = page_files_path_stack.top();
page_files_path = page_files_previous_path;
if (current_page_id != TJC_PAGE_PREVIEW) {
page_files_current_pages = 0;
}
//4.4.2 CLL 文件列表页面新增本地、U盘切换按钮
if (detect_disk() == -1 && file_mode == "USB") {
page_to(TJC_PAGE_FILE_LIST);
page_files_pages = 0;
page_files_current_pages = 0;
page_files_folder_layers = 1;
page_files_previous_path = "";
page_files_root_path = "gcodes/";
page_files_path = "/sda1";
refresh_page_files(page_files_current_pages);
refresh_page_files_list();
get_object_status();
} else if (page_files_folder_layers > 0) {
page_to(TJC_PAGE_FILE_LIST);
page_files_folder_layers--;
if (page_files_folder_layers == 0) {
refresh_page_files(page_files_current_pages);
refresh_page_files_list();
page_files_previous_path = "";
page_files_path = "";
} else {
refresh_page_files(page_files_current_pages);
refresh_page_files_list();
page_files_path_stack.pop();
}
}
}
void parse_file_estimated_time_send(nlohmann::json response) {
if (response["estimated_time"] != nlohmann::detail::value_t::null) {
file_metadata_estimated_time = (float)response["estimated_time"];
}
if (response["filename"] != nlohmann::detail::value_t::null) {
file_metadata_filename = response["filename"];
}
if (response["filament_total"] != nlohmann::detail::value_t::null) {
file_metadata_filament_total = (int)response["filament_total"];
MKSLOG_RED("用料长度%f", file_metadata_filament_total);
}
if (response["object_height"] != nlohmann::detail::value_t::null) {
file_metadata_object_height = (int)response["object_height"];
}
if (response["filament_name"] != nlohmann::detail::value_t::null) {
file_metadata_filament_name = response["filament_name"];
}
if (response["filament_type"] != nlohmann::detail::value_t::null) {
file_metadata_filament_type = response["filament_type"];
}
if (response["filament_weight_total"] != nlohmann::detail::value_t::null) {
file_metadata_filament_weight_total = response["filament_weight_total"];
}
if (response["gimage"] != nlohmann::detail::value_t::null) {
file_metadata_gimage = response["gimage"];
MKSLOG_RED("gimage");
}
if (response["simage"] != nlohmann::detail::value_t::null) {
file_metadata_simage = response["simage"];
MKSLOG_RED("simage");
}
if (response["result"]["thumbnails"] != nlohmann::detail::value_t::null) {
if (response["result"]["thumbnails"].back() != nlohmann::detail::value_t::null) {
thumbnail_relative_path = response["result"]["thumbnails"].back()["relative_path"];
if (getParentDirectory(file_metadata_filename) == "") {
thumbnail_path = thumbnail_relative_path;
} else {
thumbnail_path = getParentDirectory(file_metadata_filename) + "/" + thumbnail_relative_path;
}
MKSLOG_RED("图片路径%s", thumbnail_path.c_str());
}
} else {
thumbnail_relative_path.clear();
thumbnail_path.clear();
}
mks_file_parse_finished = true;
}
std::string getParentDirectory(const std::string& path) {
size_t found = path.find_last_of("/\\");
if (found != std::string::npos) {
return path.substr(0, found);
} else {
return ""; // 如果没有找到分隔符,说明是根目录,返回空字符串或根据需求返回当前目录 "."
}
}
int output_imgdata(std::string thumbpath, int size) {
std::string path;
if (size != 176) {
path = "/home/mks/gcode_files/" + thumbpath;
} else {
path = thumbpath;
}
// std::string path = "/home/mks/printer_data/gcodes/" + thumbpath;
std::string temp= "python3 /home/mks/gene4.py \"" + path + "\" /home/mks/tjc " + std::to_string(size);
std::cout << temp << std::endl;
const char* command = temp.c_str();
system(command);
return 0;
}
int output_jpg(std::string thumbpath, int size) {
std::string path = "/home/mks/gcode_files/" + thumbpath;
std::string path2 = path + ".jpg";
// std::string temp= "python3 /home/mks/gene5.py \"" + path + "\" /home/mks/tjc.jpg " + std::to_string(size);
std::string temp= "python3 /home/mks/gene5.py \"" + path + "\" \"" + path2 +"\" " + std::to_string(size);
std::cout << temp << std::endl;
const char* command = temp.c_str();
if (access(path2.c_str(), F_OK) == -1) {
system(command);
}
return 0;
}
// 自定义函数来提取文件名
std::string extractFileName(const std::string& filePath) {
size_t lastSlash = filePath.find_last_of("/\\"); // 找到最后一个路径分隔符的位置
if (lastSlash != std::string::npos) {
return filePath.substr(lastSlash + 1); // 提取文件名部分
}
return filePath; // 如果没有路径分隔符,则返回整个路径
}

238
src/mks_gcode.cpp Normal file
View File

@@ -0,0 +1,238 @@
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <regex>
#include "../include/MakerbaseCommand.h"
#include "../include/MoonrakerAPI.h"
#include "../include/mks_log.h"
#include "../include/mks_gcode.h"
#include "../include/event.h"
#include "../include/ui.h"
#include "../include/mks_file.h"
extern std::string str_manual_level_offset;
extern std::string printer_webhooks_state;
extern std::string printer_webhooks_state_message;
/* 共振补偿值 */
extern std::string page_syntony_shaper_freq_x;
extern std::string page_syntony_shaper_freq_y;
extern bool all_level_saving;
std::string filament_message;
//4.4.2 CLL 修改调平无需手动设置zoffset
extern bool step_1;
extern bool step_2;
extern bool step_3;
extern bool step_4;
//4.4.2 CLL 新增息屏功能
extern int current_page_id;
extern int previous_page_id;
extern bool previous_caselight_value;
extern std::string printer_idle_timeout_state;
// extern std::string mks_babystep_value; // 获取调平补偿值后保存babystep
//4.4.3 CLL 修改网页打印信息订阅
nlohmann::json output_metadata;
extern bool jump_to_print;
extern bool jump_to_memory_warning;
extern std::string printer_print_stats_state;
extern std::string error_message;
extern bool jump_to_resume_print;
void parse_gcode_response(nlohmann::json params) {
std::cout << params << std::endl;
if (params != nlohmann::detail::value_t::null) {
std::string params0 = params[0];
//4.4.2 CLL 新增息屏功能
if (current_page_id == TJC_PAGE_SCREEN_SLEEP) { // SCREEN_SLEEP中没有刷新函数跳转不会出现冲突
page_to(previous_page_id);
if (previous_caselight_value == true) {
led_on_off();
previous_caselight_value = false;
}
}
// std::cout << params0.substr(0, 23) << std::endl;
// bltouch: z_offset: 1.000
if (params0 == "// Klipper state: Ready") {
printer_idle_timeout_state = "Ready";
MKSLOG("重启Klipper已准备就绪发送订阅内容");
printer_webhooks_state = "ready";
printer_webhooks_state_message = "Klipper state: Ready";
// if (all_level_saving == false) {
sleep(5);
sub_object_status();
sleep(2);
get_object_status();
// printer_set_babystep();
// sleep(1);
init_mks_status(); // 重启后初始化之前保存的参数
if (all_level_saving == false) {
all_level_saving = true;
}
// printer_webhooks_state_message = "Klipper state: Ready";
MKSLOG_YELLOW("重启之后打印下 %s", printer_webhooks_state.c_str());
} else if (params0 == "// Klipper state: Disconnect") {
sub_object_status();
// sleep(2);
// get_object_status();
// Klipper state: Disconnect
} else if (params0.substr(0, 19) == "// PID parameters: ") {
MKSLOG_RED("// PID parameters: ");
std::string str{"(\\d+\\.\\d+)"}; // 匹配小数
std::smatch matchResult;
std::regex re(str);
if (std::regex_match(params0, matchResult, re)) {
std::cout << "pid_Kp == " << matchResult[0] << std::endl;
std::cout << "pid_Ki == " << matchResult[1] << std::endl;
std::cout << "pid_Kd == " << matchResult[2] << std::endl;
}
// 匹配到的pid转化为字符串尝试一下
std::cout << (std::string)matchResult[0] << std::endl;
std::cout << (std::string)matchResult[1] << std::endl;
std::cout << (std::string)matchResult[2] << std::endl;
std::cout << "成功获得PID的数值" << std::endl;
} else if (params0.substr(0, 20) == "// probe: z_offset: ") {
MKSLOG_RED("得到z_offset: %s", params0.substr(20).c_str());
float temp;
std::stringstream ss;
ss << params0.substr(20);
ss >> temp;
temp = -temp;
temp = temp - 0.15; // 按照要求减去0.15mm
std::string value = std::to_string(temp);
std::string babystep = value.substr(0, value.find(".") + 4);
set_mks_babystep(babystep); // 设置babystep到我们的配置文件里面去
} else if (params0.substr(0, 22) == "// bltouch: z_offset: ") {
MKSLOG_RED("得到z_offset: %s", params0.substr(22).c_str());
float temp;
std::stringstream ss;
ss << params0.substr(22);
ss >> temp;
temp = -temp;
std::string value = std::to_string(temp);
std::string babystep = value.substr(0, value.find(".") + 4);
set_mks_babystep(babystep); // 设置babystep到我们的配置文件里面去
} else if (params0 == "// action:cancel") {
//back_to_main();
} else if (params0.substr(0, 28) == "// Klipper state: Disconnect") {
// printer_webhooks_state_message = "Restarting ...";
} else if (params0.substr(0, 23) == "!! Must home axis first") {
move_home_tips();
} else if (params0.substr(0, 29) == "!! Extrude below minimum temp") {
filament_tips();
} else if (params0.substr(0, 31) == "// Recommended shaper_type_x = ") {
std::string str{"(\\d+\\.\\d+)"}; // 匹配小数
std::smatch matchResult;
std::regex re(str);
std::string temp = params0.substr(31);
if (std::regex_search(temp, matchResult, re)) {
page_syntony_shaper_freq_x = matchResult[0];
}
std::cout << "得到共振补偿的界面" << std::endl;
// page_syntony_shaper_freq_x = params0.substr(52);
MKSLOG_YELLOW("Shaper_freq_x = %s", page_syntony_shaper_freq_x.c_str());
} else if (params0.substr(0, 31) == "// Recommended shaper_type_y = ") {
std::string str{"(\\d+\\.\\d+)"};
std::smatch matchResult;
std::regex re(str);
std::string temp = params0.substr(31);
if (std::regex_search(temp, matchResult, re)) {
page_syntony_shaper_freq_y = matchResult[0];
}
std::cout << "得到共振补偿的界面" << std::endl;
MKSLOG_YELLOW("Shaper_freq_y = %s", page_syntony_shaper_freq_y.c_str());
// page_syntony_shaper_freq_y = params0.substr(51);
} else if (params0.substr(0, 14) == "// Z position:") {
int start = params0.find(">") + 1;
int end = params0.substr(start).find("<") - 1;
str_manual_level_offset = params0.substr(start, end);
std::cout << params0.substr(start, end) << std::endl;
} else if (params0.substr(0, 21) == "!! Move out of range:") {
move_tips();
} else if (params0.substr(0, 52) == "!! Can not update MCU 'mcu' config as it is shutdown") {
printer_webhooks_state_message = "Can not update MCU 'mcu' config as it is shutdown";
} else if (params0.substr(0, 33) == "// accelerometer values (x, y, z)") {
} else if (params0.substr(0, 12) == "// Lost comm") {
} else if (params0 == "Can not update") {
} else if (params0.find("Result is z=") != -1) { //4.4.3 CLL 修改自动取zoffset值时等打印机变为就绪状态时再保存数据
if (current_page_id == TJC_PAGE_AUTO_MOVING || current_page_id == TJC_PAGE_OPEN_CALIBRATE) {
// set_mks_babystep(params0.substr(15));
// save_current_zoffset();
}
} else if (params0 == "!! Insufficient disk space, unable to read the file.") {
jump_to_memory_warning = true;
} else if (params0.substr(0, 2) == "!!") {
error_message = params0;
detect_error();
} else if (params0.find("// Filament dia (measured mm):") != -1 || params0.find("// Filament NOT present") != -1 || params0.find("echo: Filament run out") != -1) { //4.4.2 CLL 使mates和霍尔宽度检测器适配
filament_message = params0;
check_filament_width();
} else if (params0.substr(0, 12) == "// metadata=") { //4.1.7 CLL 修改网页打印信息订阅 已弃用
/*
std::string str_metadata = params0.substr(12);
output_metadata = string2json(str_metadata);
std::cout << output_metadata << std::endl;
parse_file_estimated_time_send(output_metadata);
printer_print_stats_state = "printing";
MKSLOG_BLUE("跳转至打印");
*/
} else if (params0.find("echo: Position init complete") != -1) { // CLL 收到echo:前缀的返回信息即是自定义的返回信息
if (current_page_id == TJC_PAGE_OPEN_CALIBRATE || current_page_id == TJC_PAGE_AUTO_MOVING) {
step_1 = true;
}
} else if (params0.find("echo: Bed mesh calibrate complete") != -1) {
if (current_page_id == TJC_PAGE_OPEN_CALIBRATE) {
step_2 = true;
printer_webhooks_state = "shutdown";
}
if (current_page_id == TJC_PAGE_AUTO_MOVING) {
step_4 = true;
}
} else if (params0.find("echo: Input shaping complete") != -1) {
if (current_page_id == TJC_PAGE_OPEN_CALIBRATE) {
step_3 = true;
}
if (current_page_id == TJC_PAGE_SYNTONY_MOVE) {
step_1 = true;
}
} else if (params0.find("echo: Nozzle cleared") != -1) {
if (current_page_id == TJC_PAGE_AUTO_MOVING) {
step_2 = true;
}
} else if (params0.find("echo: Nozzle cooled") != -1) {
if (current_page_id == TJC_PAGE_AUTO_MOVING) {
step_3 = true;
}
} else if (params0.find("echo: Heat up complete") != -1) {
if (current_page_id == TJC_PAGE_FILAMENT_POP_2 || current_page_id == TJC_PAGE_FILAMENT_POP_3 || current_page_id == TJC_PAGE_AUTO_UNLOAD) {
step_1 = true;
}
} else if (params0.find("echo: Unload finish") != -1) {
if (current_page_id == TJC_PAGE_AUTO_UNLOAD) {
step_2 = true;
}
} else if (params0.find("echo: Load finish") != -1) {
if (current_page_id == TJC_PAGE_FILAMENT_POP_3 || current_page_id == TJC_PAGE_FILAMENT_POP_2) {
step_2 = true;
}
} else if (params0.find("echo: Detected unexpected interruption during the last print.") != -1 || params0.find("echo: Yes: RESUME_INTERRUPTED") != -1 || params0.find("echo: No: CLEAR_LAST_FILE") != -1) {
jump_to_resume_print = true;
}
}
}

359
src/mks_gpio.cpp Normal file
View File

@@ -0,0 +1,359 @@
#include "../include/mks_gpio.h"
#include "../include/mks_log.h"
#include "../include/event.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
// static char gpio_path[64];
static int gpio_config(const char *attr, const char *val, const char *gpio_path) {
char file_path[64];
int len;
int fd;
sprintf(file_path, "%s/%s", gpio_path, attr);
if (0 > (fd = open(file_path, O_WRONLY))) {
perror("open error");
return fd;
}
len = strlen(val);
if (len != write(fd, val, len)) {
perror("write error");
close(fd);
return -1;
}
close(fd);
return 0;
}
// 32+2*8+5=53
int set_GPIO1_C5_low() {
if (access("/sys/class/gpio/gpio53", F_OK)) {
int fd;
int len;
char arg[] = "53";
if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
perror("open error");
return -1;
}
len = strlen(arg);
if (len != write(fd, arg, len)) {
perror("write error");
close(fd);
return -1;
}
close(fd); // 关闭文件
}
/* 配置为输出模式 */
if (gpio_config("direction", "out", "/sys/class/gpio/gpio53")) {
printf("配置输出模式出错\n");
return -1;
}
/* 极性设置 */
if (gpio_config("active_low", "0", "/sys/class/gpio/gpio53")) {
printf("配置极性设置出错\n");
return -1;
}
/* 控制GPIO输出低电平 */
if (gpio_config("value", "0", "/sys/class/gpio/gpio53")) {
printf("配置输出低电平出错\n");
return -1;
}
return 0;
}
int set_GPIO1_C5_high() {
if (access("/sys/class/gpio/gpio53", F_OK)) {
int fd;
int len;
char arg[] = "53";
if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
perror("open error");
return -1;
}
len = strlen(arg);
if (len != write(fd, arg, len)) {
perror("write error");
close(fd);
return -1;
}
close(fd); // 关闭文件
}
/* 配置为输出模式 */
if (gpio_config("direction", "out", "/sys/class/gpio/gpio53")) {
printf("配置输出模式出错\n");
return -1;
}
/* 极性设置 */
if (gpio_config("active_low", "0", "/sys/class/gpio/gpio53")) {
printf("配置极性设置出错\n");
return -1;
}
/* 控制GPIO输出高电平 */
if (gpio_config("value", "1", "/sys/class/gpio/gpio53")) {
printf("配置输出低电平出错\n");
return -1;
}
return 0;
}
// 32+1*8+2=42
int init_GPIO1_B2() {
if (access("/sys/class/gpio/gpio42", F_OK)) {
int fd;
int len;
char arg[] = "42";
if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
perror("open error");
return -1;
}
len = strlen(arg);
if (len != write(fd, arg, len)) {
perror("write error");
close(fd);
exit(-1);
}
close(fd);
}
/* 配置为输入模式 */
if (gpio_config("direction", "in", "/sys/class/gpio/gpio42")) {
return -1;
}
/* 极性设置 */
if (gpio_config("active_low", "0", "/sys/class/gpio/gpio42")) {
return -1;
}
/* 配置为非中断方式 */
if (gpio_config("edge", "falling", "/sys/class/gpio/gpio42")) {
return -1;
}
return 0;
}
void *monitor_GPIO1_B2(void *arg) {
struct pollfd pfd;
int ret;
char val;
/* 打开 value 属性文件 */
if (0 > (pfd.fd = open("/sys/class/gpio/gpio42/value", O_RDONLY))) {
perror("打开value出错");
// return ;
}
/* 调用 poll */
pfd.events = POLLPRI; // 只关心高优先级数据可读(中断)
read(pfd.fd, &val, 1); // 先读取一次清除状态
for (;;) {
ret = poll(&pfd, 1, -1);
if (0 > ret) {
perror("poll error");
// return ;
} else if (0 == ret) {
fprintf(stderr, "poll timeout.\n");
continue;
}
/* 检验高优先级数据是否可读 */
if (pfd.revents & POLLPRI) {
if (0 > lseek(pfd.fd, 0, SEEK_SET)) { // 将读位置移动到头部
perror("lseek error");
// return ;
}
if (0 > read(pfd.fd, &val, 1)) {
perror("read error");
// return ;
}
if ((val - '0') == 0) {
// 检测到低电平之后要执行的
// set_GPIO1_C5_low();
//4.4.1 CLL 屏蔽关机页面
system("echo TEST > /root/TESTGPIO; sync");
//go_to_page_power_off();
system("sync; shutdown -h now;");
}
}
usleep(110000); // 检测电平减少一点
}
}
int init_GPIO1_C3() {
if (access("/sys/class/gpio/gpio51", F_OK)) {
int fd;
int len;
char arg[] = "51";
if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
perror("open error");
return -1;
}
len = strlen(arg);
if (len != write(fd, arg, len)) {
perror("write error");
close(fd);
exit(-1);
}
close(fd);
}
/* 配置为输入模式 */
if (gpio_config("direction", "in", "/sys/class/gpio/gpio51")) {
return -1;
}
/* 极性设置 */
if (gpio_config("active_low", "0", "/sys/class/gpio/gpio51")) {
return -1;
}
/* 配置为非中断方式 */
if (gpio_config("edge", "both", "/sys/class/gpio/gpio51")) {
// if (gpio_config("edge", "rising", "/sys/class/gpio/gpio51")) {
return -1;
}
return 0;
}
void *monitor_GPIO1_C3(void *arg) {
struct pollfd pfd;
int ret;
char val;
int cnt = 0;
const int debounce_limit = 5; // 防抖计数器限制
const int debounce_interval = 30; // 防抖时间间隔(毫秒)
/* 打开 value 属性文件 */
if (0 > (pfd.fd = open("/sys/class/gpio/gpio51/value", O_RDONLY))) {
perror("打开value出错");
// return ;
}
/* 调用 poll */
pfd.events = POLLPRI; // 只关心高优先级数据可读(中断)
read(pfd.fd, &val, 1); // 先读取一次清除状态
for (;;) {
ret = poll(&pfd, 1, -1);
if (0 > ret) {
perror("poll error");
// return ;
} else if (0 == ret) {
fprintf(stderr, "poll timeout.\n");
continue;
}
/* 检验高优先级数据是否可读 */
if (pfd.revents & POLLPRI) {
if (0 > lseek(pfd.fd, 0, SEEK_SET)) { // 将读位置移动到头部
perror("lseek error");
// return ;
}
if (0 > read(pfd.fd, &val, 1)) {
perror("read error");
// return ;
}
if ((val - '0') == 1) {
if (cnt >= debounce_limit) {
// 检测到低电平之后要执行的
// set_GPIO1_C5_low();
// system("echo TEST > /root/TESTGPIO; sync");
go_to_page_power_off();
shutdown_mcu();
set_GPIO1_B3_low();
system("sync");
// system("sync; shutdown -h now;");
cnt = 0;
} else {
cnt++;
usleep(debounce_interval * 1000);
}
}else {
cnt = 0;
}
MKSLOG_BLUE("cnt=%d",cnt);
}
usleep(110000);
// 检测电平减少一点
}
}
int set_GPIO1_B3_low() {
if (access("/sys/class/gpio/gpio43", F_OK)) {
int fd;
int len;
char arg[] = "43";
if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) {
perror("open error");
return -1;
}
len = strlen(arg);
if (len != write(fd, arg, len)) {
perror("write error");
close(fd);
return -1;
}
close(fd); // 关闭文件
}
/* 配置为输出模式 */
if (gpio_config("direction", "out", "/sys/class/gpio/gpio43")) {
printf("配置输出模式出错\n");
return -1;
}
/* 极性设置 */
if (gpio_config("active_low", "0", "/sys/class/gpio/gpio43")) {
printf("配置极性设置出错\n");
return -1;
}
/* 控制GPIO输出低电平 */
if (gpio_config("value", "0", "/sys/class/gpio/gpio43")) {
printf("配置输出低电平出错\n");
return -1;
}
return 0;
}

63
src/mks_init.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "../include/mks_init.h"
#include "../include/MakerbaseShell.h"
std::string serial_by_id;
bool get_by_id() {
struct dirent *dir;
DIR *dirp;
dirp = opendir("/dev/serial/by-id");
if (NULL == dirp) {
printf("读取串口失败!!!!!!!!!!!!!!!!\n");
return false;
} else {
serial_by_id = generate_by_id();
serial_by_id = serial_by_id.substr(0, 58);
std::cout << serial_by_id.length() << " 成功读取到ID号 " + serial_by_id << std::endl;
closedir(dirp);
return true;
}
}
std::string generate_by_id() {
char result[MAX_FILE_LEN] = {0};
std::string cmd = "ls /dev/serial/by-id/*";
execute_cmd(cmd.data(), result);
printf("%s", result);
return result;
}
bool FileStringReplace(std::ifstream &instream, std::ofstream &outstream)
{
std::string str;
size_t pos = 0;
while (getline(instream, str)) // 按行读取
{
pos = str.find("serial:"); // 查找每一行中的"Tom"
if (pos != std::string::npos)
{
str = str.replace(pos, str.length(), "Jerry"); // 将Tom替换为Jerry
outstream << str << std::endl;
continue;
}
outstream << str << std::endl;
}
return true;
}
std::string get_cfg_by_id() {
std::string path = "/home/mks/klipper_config/MKS_THR.cfg";
std::ifstream data(path.c_str());
std::string strline;
std::string ret;
while (getline(data, strline)) {
bool exists = strline.find("serial: ") == std::string::npos;
if (!exists) {
std::cout << strline.length() << " CFG文件里面的serial的值 " + strline.substr(8, 62) << std::endl;
ret = strline.substr(8, 63);
break;
}
}
data.close();
return ret;
}

26
src/mks_job.cpp Normal file
View File

@@ -0,0 +1,26 @@
/*
#include <stdio.h>
#include <sqlite3.h>
sqlite3 *db = NULL;
int mks_open_database() {
int rc = 0;
rc = sqlite3_open("/root/mks.db", &db);
if (rc != SQLITE_OK) {
printf("Open db error :%s", sqlite3_errmsg(db));
return -1;
}
return 0;
}
void mks_close_database() {
if (db != NULL) {
sqlite3_close(db);
db = NULL;
}
}
*/

55
src/mks_preview.cpp Normal file
View File

@@ -0,0 +1,55 @@
#include "../include/mks_preview.h"
bool gimage_is_showed = false;
bool simage_is_showed = false;
// std::vector<std::string> gimage;
// std::vector<std::string> simage;
// std::string str_gimage = "";
// std::vector<std::string> gimage_temp;
// std::vector<std::string> simage_temp;
/*
void generate_gimage(std::string filename) {
gimage.clear();
// gimage_temp.clear();
std::string path = "/home/mks/gcode_files" + filename;
std::ifstream data(path.c_str());
std::string strline;
while (getline(data, strline)) {
bool exists = strline.find(";gimage:") == std::string::npos;
if (!exists) {
std::cout << strline.substr(8) + "\n" << std::endl;
gimage.push_back(strline.substr(8));
// str_gimage += strline.substr(8);
}
// std::cout << str_gimage << std::endl;
}
data.close();
}
*/
/*
void generate_simage(std::string filename) {
simage.clear();
// simage_temp.clear();
std::string path = "/home/mks/gcode_files" + filename;
std::ifstream data(path.c_str());
std::string strline;
while (getline(data, strline)) {
bool exists = strline.find(";simage:") == std::string::npos;
if (!exists) {
std::cout << strline.substr(8) + "\n" << std::endl;
// simage.push_back(strline.substr(8));
}
}
data.close();
// for (int i = 0; i < simage.size(); i++) {
// std::cout << simage[i] << "\n" << std::endl;
// }
}
*/

622
src/mks_printer.cpp Normal file
View File

@@ -0,0 +1,622 @@
#include <iostream>
#include "../include/mks_printer.h"
// mks ini data
bool mks_led_status;
bool mks_beep_status;
bool mks_fila_status;
int mks_language_status;
int mks_extruder_target;
int mks_heater_bed_target;
int mks_hot_target;
std::string mks_babystep_value;
std::string mks_adxl_offset;
std::string mks_version_soc;
std::string mks_version_mcu;
std::string mks_version_ui;
// webhooks
std::string printer_webhooks_state;
std::string printer_webhooks_state_message;
std::string current_webhooks_state_message;
// gcode_move
float printer_gcode_move_speed_factor;
float printer_gcode_move_speed;
float printer_gcode_move_extrude_factor;
float printer_gcode_move_homing_origin[4]; // [X, Y, Z, E] - 返回应用于每个轴的“gcode 偏移”。例如可以检查“Z”轴以确定通过“babystepping”应用了多少偏移量。
float printer_gcode_move_position[4];
float printer_gcode_move_gcode_position[4];
// toolhead
std::string printer_toolhead_homed_axes;
float printer_toolhead_print_time;
float printer_toolhead_extimated_print_time;
double printer_toolhead_position[4];
double printer_toolhead_axis_minimum[4];
double printer_toolhead_axis_maximum[4];
// x, y, z坐标
double x_position;
double y_position;
double z_position;
// gcode, z坐标
double gcode_z_position;
float e_position;
// extruder
int printer_extruder_temperature = 0;
int printer_extruder_target = 0;
// heater bed
int printer_heater_bed_temperature = 0;
int printer_heater_bed_target = 0;
// hot
int printer_hot_temperature = 0;
int printer_hot_target = 0;
// fan
float printer_fan_speed;
// heater fan
float printer_heater_fan_speed;
// heater_fan my_nozzle_fan1
float printer_heater_fan_my_nozzle_fan1_speed;
// output_pin fan0
float printer_out_pin_fan0_value;
// output_pin fan2
float printer_out_pin_fan2_value;
float printer_out_pin_fan3_value;
float printer_out_pin_beep_value;
// idle_timeout
std::string printer_idle_timeout_state;
float printer_printing_time;
// virtual sdcard
// print stats
std::string printer_print_stats_filename;
float printer_print_stats_total_duration;
float printer_print_stats_print_duration;
float printer_print_stats_filament_used;
std::string printer_print_stats_state; // 这个状态很有用
std::string printer_print_stats_message; // error detected, error message
// display status
std::string printer_display_status_message;
int printer_display_status_progress = 0;
// temperature_sensor sensor_name
// temperature_fan fan_name
// filament_switch_sensor sensor_name
// output_pin pin_name
// bed_mesh
float auto_level_dist = 0.05;
bool auto_level_finished = false;
bool auto_level_enabled = false;
float manual_level_dist = 0.05;
int manual_level_count = 15;
bool manual_level_finished = false;
// bool manual_level_enabled = false;
float printer_bed_mesh_mesh_min[2] = {0.0, 0.0};
float printer_bed_mesh_mesh_max[2] = {0.0, 0.0};
float printer_bed_mesh_profiles_mks_points[5][5] = {0.0};
float printer_bed_mesh_profiles_mks_mesh_params_tension = 0.0;
float printer_bed_mesh_profiles_mks_mesh_params_mesh_x_pps = 0;
std::string printer_bed_mesh_profiles_mks_mesh_params_algo = "";
float printer_bed_mesh_profiles_mks_mesh_params_min_x = 0;
float printer_bed_mesh_profiles_mks_mesh_params_min_y = 0;
float printer_bed_mesh_profiles_mks_mesh_params_x_count = 0;
float printer_bed_mesh_profiles_mks_mesh_params_y_count = 0;
float printer_bed_mesh_profiles_mks_mesh_params_mesh_y_pps = 0;
float printer_bed_mesh_profiles_mks_mesh_params_max_x = 0;
float printer_bed_mesh_profiles_mks_mesh_params_max_y = 0;
float page_set_zoffset_x_y_position[16][2] = {
{30, 30}, // 1
{30, 93.33}, // 2
{30, 156.66}, // 3
{30, 219.99}, // 4
{93.33, 30}, // 5
{93.33, 93.33}, // 6
{93.33, 156.66}, // 7
{93.33, 219.99}, // 8
{156.66, 30}, // 9
{156.66, 93.33}, // 10
{156.66, 156.66}, // 11
{156.66, 219.99}, // 12
{219.99, 30}, // 13
{219.99, 93.33}, // 14
{219.99, 156.66}, // 15
{219.99, 219.99} // 16
};
float page_set_zoffset_z_position[16] = {0};
bool fresh_page_set_zoffset_data = false;
bool refresh_page_auto_finish_data = false;
int page_set_zoffset_index;
// pause resume
int printer_pause_taget;
bool printer_pause_resume_is_paused;
float printer_set_offset = 0.01;
float printer_z_offset = 0.0;
float printer_intern_z_offset = 0.0;
float printer_extern_z_offset = 0.0;
float printer_move_dist = 10.0;
int printer_filament_extruder_target = 0;
int printer_filament_extruedr_dist = 50;
// filament switch sensor fila
bool filament_switch_sensor_fila_filament_detected = false;
bool filament_switch_sensor_fila_enabled = false;
// output_pin caselight
float printer_caselight_value = 0;
// probe
float printer_probe_x_zoffset = 0.0;
float printer_probe_y_zoffset = 0.0;
float printer_probe_z_zoffset = 0.0;
// printer info software version
std::string printer_info_software_version;
// server history totals
int total_jobs = 0;
double total_time = 0.0;
double total_print_time = 0.0;
double total_filament_used = 0.0;
// oobe
float oobe_printer_set_offset = 0.05;
void parse_server_history_totals(nlohmann::json totals) {
/*
if (totals["total_time"] != nlohmann::detail::value_t::null) {
total_time = totals["total_time"];
}
*/
if (totals["total_print_time"] != nlohmann::detail::value_t::null) {
total_print_time = totals["total_print_time"];
}
std::cout << "total_print_time = " << (int)(total_print_time) << std::endl;
}
void parse_printer_probe(nlohmann::json probe) {
if (probe["x_offset"] != nlohmann::detail::value_t::null) {
printer_probe_x_zoffset = probe["x_offset"];
}
if (probe["y_offset"] != nlohmann::detail::value_t::null) {
printer_probe_y_zoffset = probe["y_offset"];
}
if (probe["z_offset"] != nlohmann::detail::value_t::null) {
printer_probe_z_zoffset = probe["z_offset"];
}
}
void parse_printer_beep(nlohmann::json beep) {
if (beep["value"] != nlohmann::detail::value_t::null) {
printer_out_pin_beep_value = beep["value"];
MKSLOG_BLUE("printer_out_pin_beep_value = %f", printer_out_pin_beep_value);
}
}
void parse_printer_caselight(nlohmann::json caselight) {
if (caselight["value"] != nlohmann::detail::value_t::null) {
printer_caselight_value = caselight["value"];
MKSLOG_BLUE("printer_caselight_value = %f", printer_caselight_value);
}
}
void parse_printer_heater_fan_my_nozzle_fan1(nlohmann::json heater_fan_my_nozzle_fan1) {
if (heater_fan_my_nozzle_fan1["speed"] != nlohmann::detail::value_t::null) {
printer_heater_fan_my_nozzle_fan1_speed = heater_fan_my_nozzle_fan1["speed"];
}
}
void parse_printer_out_pin_fan0(nlohmann::json out_pin_fan0) {
if (out_pin_fan0["speed"] != nlohmann::detail::value_t::null) {
printer_out_pin_fan0_value = out_pin_fan0["speed"];
}
std::cout << "printer_out_pin_fan0_value " << printer_out_pin_fan0_value << std::endl;
};
void parse_printer_out_pin_fan2(nlohmann::json out_pin_fan2) {
if (out_pin_fan2["speed"] != nlohmann::detail::value_t::null) {
printer_out_pin_fan2_value = out_pin_fan2["speed"];
}
std::cout << "printer_out_pin_fan2_value " << printer_out_pin_fan2_value << std::endl;
};
void parse_printer_out_pin_fan3(nlohmann::json out_pin_fan3) {
if (out_pin_fan3["speed"] != nlohmann::detail::value_t::null) {
printer_out_pin_fan3_value = out_pin_fan3["speed"];
}
std::cout << "printer_out_pin_fan3_value " << printer_out_pin_fan3_value << std::endl;
};
void parse_filament_switch_sensor_fila(nlohmann::json filament_switch_sensor) {
if (filament_switch_sensor["filament_detected"] != nlohmann::detail::value_t::null) {
filament_switch_sensor_fila_filament_detected = filament_switch_sensor["filament_detected"];
std::cout << "!!!! filament_detected: " << filament_switch_sensor_fila_filament_detected << std::endl;
}
if (filament_switch_sensor["enabled"] != nlohmann::detail::value_t::null) {
filament_switch_sensor_fila_enabled = filament_switch_sensor["enabled"];
std::cout << "!!!! enabled: " << filament_switch_sensor_fila_enabled << std::endl;
}
}
void parse_idle_timeout(nlohmann::json idle_timeout) {
if (idle_timeout["state"] != nlohmann::detail::value_t::null) {
printer_idle_timeout_state = idle_timeout["state"];
std::cout << "idle_timeout: " << printer_idle_timeout_state << std::endl;
MKSLOG_RED("idle_timeout 发生变化: %s", printer_idle_timeout_state.c_str());
}
}
void parse_bed_mesh(nlohmann::json bed_mesh) {
if (bed_mesh["mesh_min"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_mesh_min[0] = bed_mesh["mesh_min"][0];
printer_bed_mesh_mesh_min[1] = bed_mesh["mesh_min"][1];
}
if (bed_mesh["mesh_max"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_mesh_max[0] = bed_mesh["mesh_max"][0];
printer_bed_mesh_mesh_max[1] = bed_mesh["mesh_max"][1];
}
if (bed_mesh["profiles"] != nlohmann::detail::value_t::null) {
if (bed_mesh["profiles"]["default"] != nlohmann::detail::value_t::null) {
if (bed_mesh["profiles"]["default"]["mesh_params"] != nlohmann::detail::value_t::null) {
if (bed_mesh["profiles"]["default"]["mesh_params"]["tension"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_tension = bed_mesh["profiles"]["default"]["mesh_params"]["tension"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["mesh_x_pps"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_mesh_x_pps = bed_mesh["profiles"]["default"]["mesh_params"]["mesh_x_pps"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["algo"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_algo = bed_mesh["profiles"]["default"]["mesh_params"]["algo"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["min_x"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_min_x = bed_mesh["profiles"]["default"]["mesh_params"]["min_x"];
std::cout << "printer_bed_mesh_profiles_mks_mesh_params_min_x = " << printer_bed_mesh_profiles_mks_mesh_params_min_x << std::endl;
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["min_y"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_min_y = bed_mesh["profiles"]["default"]["mesh_params"]["min_y"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["y_count"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_y_count = bed_mesh["profiles"]["default"]["mesh_params"]["y_count"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["mesh_y_pps"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_mesh_y_pps = bed_mesh["profiles"]["default"]["mesh_params"]["mesh_y_pps"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["x_count"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_x_count = bed_mesh["profiles"]["default"]["mesh_params"]["x_count"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["max_x"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_max_x = bed_mesh["profiles"]["default"]["mesh_params"]["max_x"];
}
if (bed_mesh["profiles"]["default"]["mesh_params"]["max_y"] != nlohmann::detail::value_t::null) {
printer_bed_mesh_profiles_mks_mesh_params_max_y = bed_mesh["profiles"]["default"]["mesh_params"]["max_y"];
}
}
if (bed_mesh["profiles"]["default"]["points"] != nlohmann::detail::value_t::null) {
for (int i = 0; i < printer_bed_mesh_profiles_mks_mesh_params_y_count; i++) {
if (i == 5) {
break;
}
for (int j = 0; j < printer_bed_mesh_profiles_mks_mesh_params_x_count; j++) {
if (j == 5) {
break;
}
printer_bed_mesh_profiles_mks_points[i][j] = bed_mesh["profiles"]["default"]["points"][i][j];
}
}
}
}
}
}
void parse_webhooks(nlohmann::json webhooks) {
if (webhooks["state"] != nlohmann::detail::value_t::null) {
printer_webhooks_state = webhooks["state"];
}
// MKSLOG_RED("Webhooks state: %s", printer_webhooks_state);
if (webhooks["state_message"] != nlohmann::detail::value_t::null) {
printer_webhooks_state_message = webhooks["state_message"];
}
MKSLOG_RED("State message: %s", printer_webhooks_state_message.c_str());
}
void parse_gcode_move(nlohmann::json gcode_move) {
if (gcode_move["speed_factor"] != nlohmann::detail::value_t::null) {
printer_gcode_move_speed_factor = gcode_move["speed_factor"];
}
if (gcode_move["speed"] != nlohmann::detail::value_t::null) {
printer_gcode_move_speed = gcode_move["speed"];
}
if (gcode_move["extrude_factor"] != nlohmann::detail::value_t::null) {
printer_gcode_move_extrude_factor = gcode_move["extrude_factor"];
}
if (gcode_move["homing_origin"] != nlohmann::detail::value_t::null) {
printer_gcode_move_homing_origin[0] = gcode_move["homing_origin"][0];
printer_gcode_move_homing_origin[1] = gcode_move["homing_origin"][1];
printer_gcode_move_homing_origin[2] = gcode_move["homing_origin"][2];
printer_gcode_move_homing_origin[3] = gcode_move["homing_origin"][3];
}
if (gcode_move["gcode_position"] != nlohmann::detail::value_t::null) {
// printer_gcode_move_gcode_position[0] = gcode_move["gcode_position"][0];
// printer_gcode_move_gcode_position[1] = gcode_move["gcode_position"][1];
printer_gcode_move_gcode_position[2] = gcode_move["gcode_position"][2];
// printer_gcode_move_gcode_position[3] = gcode_move["gcode_position"][3];
// std::cout << "printer_gcode_move_gcode_position[2] " << printer_gcode_move_gcode_position[2] << std::endl;
gcode_z_position = round(printer_gcode_move_gcode_position[2] * 1000) / 1000;
}
}
void parse_toolhead(nlohmann::json toolhead) {
if (toolhead["position"] != nlohmann::detail::value_t::null) {
printer_toolhead_position[0] = toolhead["position"][0];
x_position = round(printer_toolhead_position[0] * 10) / 10;
printer_toolhead_position[1] = toolhead["position"][1];
y_position = round(printer_toolhead_position[1] * 10) / 10;
printer_toolhead_position[2] = toolhead["position"][2];
// std::cout << "printer_toolhead_position[2] " << printer_toolhead_position[2] << std::endl;
// std::cout << "printer_toolhead_position[2] " << std::to_string(printer_toolhead_position[2]) << std::endl;
z_position = round(printer_toolhead_position[2] * 10) / 10;
// std::cout << "z_position: " << z_position << std::endl;
printer_toolhead_position[3] = toolhead["position"][3];
// std::cout << "printer_toolhead_position z == " << printer_toolhead_position << std::endl;
}
if (toolhead["axis_minimum"] != nlohmann::detail::value_t::null) {
printer_toolhead_axis_minimum[0] = toolhead["axis_minimum"][0];
printer_toolhead_axis_minimum[1] = toolhead["axis_minimum"][1];
printer_toolhead_axis_minimum[2] = toolhead["axis_minimum"][2];
printer_toolhead_axis_minimum[3] = toolhead["axis_minimum"][3];
}
if (toolhead["axis_maximum"] != nlohmann::detail::value_t::null) {
printer_toolhead_axis_maximum[0] = toolhead["axis_maximum"][0];
printer_toolhead_axis_maximum[1] = toolhead["axis_maximum"][1];
printer_toolhead_axis_maximum[2] = toolhead["axis_maximum"][2];
printer_toolhead_axis_maximum[3] = toolhead["axis_maximum"][3];
}
}
void parse_extruder(nlohmann::json extruder) {
float temp;
if (extruder["temperature"] != nlohmann::detail::value_t::null) {
temp = extruder["temperature"];
printer_extruder_temperature = (int)(temp + 0.5);
// printer_extruder_temperature = extruder["temperature"];
}
if (extruder["target"] != nlohmann::detail::value_t::null) {
temp = extruder["target"];
printer_extruder_target = (int)(temp + 0.5);
// printer_extruder_target = extruder["target"];
}
}
void parse_heater_bed(nlohmann::json heater_bed) {
float temp;
if (heater_bed["temperature"] != nlohmann::detail::value_t::null) {
temp = heater_bed["temperature"];
printer_heater_bed_temperature = (int)(temp + 0.5);
}
if (heater_bed["target"] != nlohmann::detail::value_t::null) {
temp = heater_bed["target"];
printer_heater_bed_target = (int)(temp + 0.5);
}
}
void parse_heater_generic_hot(nlohmann::json heater_generic_hot) {
float temp;
if (heater_generic_hot["temperature"] != nlohmann::detail::value_t::null) {
temp = heater_generic_hot["temperature"];
printer_hot_temperature = (int)(temp + 0.5);
}
if (heater_generic_hot["target"] != nlohmann::detail::value_t::null) {
temp = heater_generic_hot["target"];
printer_hot_target = (int)(temp + 0.5);
}
}
void parse_fan(nlohmann::json fan) {
if (fan["speed"] != nlohmann::detail::value_t::null) {
printer_fan_speed = fan["speed"];
}
}
void parse_heater_fan(nlohmann::json heater_fan) {
if (heater_fan["speed"] != nlohmann::detail::value_t::null) {
printer_heater_fan_speed = heater_fan["speed"];
}
}
void parse_print_stats(nlohmann::json print_stats) {
if (print_stats["state"] != nlohmann::detail::value_t::null) {
printer_print_stats_state = print_stats["state"];
std::cout << "\033[31;1m" << "printer_print_stats_state = " << printer_print_stats_state << "\033[0m" << std::endl;
}
if (print_stats["filename"] != nlohmann::detail::value_t::null) {
printer_print_stats_filename = print_stats["filename"];
std::cout << "\033[31;1m" << "printer_print_stats_filename = " << printer_print_stats_filename << "\033[0m" << std::endl;
}
if (print_stats["print_duration"] != nlohmann::detail::value_t::null) {
printer_print_stats_print_duration = print_stats["print_duration"];
}
if (print_stats["total_duration"] != nlohmann::detail::value_t::null) {
printer_print_stats_total_duration = print_stats["total_duration"];
}
}
void parse_display_status(nlohmann::json display_status) {
double temp = 0.0;
if (display_status["progress"] != nlohmann::detail::value_t::null) {
temp = display_status["progress"];
printer_display_status_progress = (int)(temp * 100);
}
}
void parse_pause_resume(nlohmann::json pause_resume) {
std::cout << pause_resume << std::endl;
if (pause_resume["is_paused"] != nlohmann::detail::value_t::null) {
printer_pause_resume_is_paused = pause_resume["is_paused"];
}
}
// 解析订阅对象状态
void parse_subscribe_objects_status(nlohmann::json status) {
if (status["idle_timeout"] != nlohmann::detail::value_t::null) {
parse_idle_timeout(status["idle_timeout"]);
}
if (status["bed_mesh"] != nlohmann::detail::value_t::null) {
std::cout << status["bed_mesh"] << std::endl;
parse_bed_mesh(status["bed_mesh"]);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
std::cout << "############# Points :" << i << ", " << j << " " << printer_bed_mesh_profiles_mks_points[i][j] << std::endl;
}
}
}
if (status["webhooks"] != nlohmann::detail::value_t::null) {
// MKSLOG("Webhooks update");
parse_webhooks(status["webhooks"]);
}
if (status["gcode_move"] != nlohmann::detail::value_t::null) {
// MKSLOG("Gcode move update");
parse_gcode_move(status["gcode_move"]);
}
if (status["toolhead"] != nlohmann::detail::value_t::null) {
// MKSLOG("toolhead update");
parse_toolhead(status["toolhead"]);
}
if (status["extruder"] != nlohmann::detail::value_t::null) {
// MKSLOG("Extruder update");
parse_extruder(status["extruder"]);
}
if (status["heater_bed"] != nlohmann::detail::value_t::null) {
// MKSLOG("Heater bed update");
parse_heater_bed(status["heater_bed"]);
}
if (status["heater_generic chamber"] != nlohmann::detail::value_t::null) {
parse_heater_generic_hot(status["heater_generic chamber"]);
}
if (status["fan"] != nlohmann::detail::value_t::null) {
// MKSLOG("Fan update");
parse_fan(status["fan"]);
}
if (status["heater_fan fan1"] != nlohmann::detail::value_t::null) {
parse_heater_fan(status["heater_fan fan1"]);
}
if (status["pause_resume"] != nlohmann::detail::value_t::null) {
parse_pause_resume(status["pause_resume"]);
}
if (status["print_stats"] != nlohmann::detail::value_t::null) {
// MKSLOG("Print stats update");
parse_print_stats(status["print_stats"]);
}
if (status["display_status"] != nlohmann::detail::value_t::null) {
// MKSLOG("Display status update");
parse_display_status(status["display_status"]);
}
if (status["heater_fan my_nozzle_fan1"] != nlohmann::detail::value_t::null) {
parse_printer_heater_fan_my_nozzle_fan1(status["heater_fan my_nozzle_fan1"]);
}
if (status["fan_generic cooling_fan"] != nlohmann::detail::value_t::null) {
parse_printer_out_pin_fan0(status["fan_generic cooling_fan"]);
}
if (status["fan_generic auxiliary_cooling_fan"] != nlohmann::detail::value_t::null) {
parse_printer_out_pin_fan2(status["fan_generic auxiliary_cooling_fan"]);
}
if (status["fan_generic chamber_circulation_fan"] != nlohmann::detail::value_t::null) {
parse_printer_out_pin_fan3(status["fan_generic chamber_circulation_fan"]);
}
if (status["filament_switch_sensor fila"] != nlohmann::detail::value_t::null) {
parse_filament_switch_sensor_fila(status["filament_switch_sensor fila"]);
}
if (status["output_pin caselight"] != nlohmann::detail::value_t::null) {
parse_printer_caselight(status["output_pin caselight"]);
}
if (status["output_pin sound"] != nlohmann::detail::value_t::null) {
parse_printer_beep(status["output_pin sound"]);
}
if (status["probe"] != nlohmann::detail::value_t::null) {
parse_printer_probe(status["probe"]);
}
}
nlohmann::json subscribe_objects_status() {
nlohmann::json objects;
objects["extruder"];
objects["heater_generic chamber"];
objects["heater_bed"];
objects["gcode_move"];
objects["fan"] = {"speed"};
objects["heater_fan fan1"] = {"speed"};
objects["toolhead"];
objects["print_stats"] = {"print_duration", "total_duration", "filament_used", "filename", "state", "message"};
objects["display_status"] = {"progress", "message"};
objects["idle_timeout"] = {"state"};
objects["pause_resume"] = {"is_paused"};
objects["webhooks"] = {"state", "state_message"};
// objects["webhooks"];
objects["firmware_retraction"] = {"retract_length", "retract_speed", "unretract_extra_length",
"unretract_speed"};
objects["bed_mesh"];
objects["heater_fan my_nozzle_fan1"];
objects["filament_switch_sensor fila"] = {"filament_detected", "enabled"};
objects["fan_generic cooling_fan"] = {"speed", "rpm"};
objects["fan_generic auxiliary_cooling_fan"] = {"speed", "rpm"};
objects["fan_generic chamber_circulation_fan"] = {"speed", "rpm"};
objects["output_pin caselight"];
objects["output_pin sound"];
objects["probe"];
return objects;
}
int get_cal_printing_time(int print_time, int estimated_time, int progress) {
int left_time;
int total_time = 0;
if (progress <= 10) {
total_time = estimated_time;
left_time = total_time - print_time;
} else if (progress > 10) {
total_time = (print_time) * 100 / (progress);
left_time = total_time - print_time;
}
return left_time;
}
void parse_printer_info(nlohmann::json result) {
if (result["software_version"] != nlohmann::detail::value_t::null) {
// std::cout << result["software_version"] << std::endl;
printer_info_software_version = result["software_version"];
MKSLOG_RED("Version: %s", printer_info_software_version.c_str());
}
}

4
src/mks_system.cpp Normal file
View File

@@ -0,0 +1,4 @@
#include "../include/mks_system.h"

120
src/mks_test.cpp Normal file
View File

@@ -0,0 +1,120 @@
#include "../include/mks_test.h"
#include "../include/ui.h"
#include "../include/send_msg.h"
#include "../include/event.h"
extern int tty_fd;
extern int current_page_id;
// void *mks_test(void *arg) {
// while (1) {
// if (current_page_id == TJC_PAGE_MKS_TEST) {
// if (true == testUSB()) {
// send_cmd_txt(tty_fd, "t2", "Okay");
// send_cmd_pco(tty_fd, "t2", "2047");
// sleep(2);
// } else {
// send_cmd_txt(tty_fd, "t2", "fail");
// send_cmd_pco(tty_fd, "t2", "63488");
// }
// if (true == moko_test_func()) {
// send_cmd_txt(tty_fd, "t2", "okay");
// send_cmd_pco(tty_fd, "t2", "1024");
// sleep(2);
// } else {
// send_cmd_txt(tty_fd, "t2", "fail");
// send_cmd_pco(tty_fd, "t2", "63488");
// }
// if (true == network_test_func()) {
// send_cmd_txt(tty_fd, "t3", "Okay");
// send_cmd_pco(tty_fd, "t3", "2047");
// } else {
// send_cmd_txt(tty_fd, "t3", "fail");
// send_cmd_pco(tty_fd, "t3", "63488");
// }
// }
// refresh_page_mks_test();
// usleep(50000);
// }
// }
bool testUSB()
{
FILE *fp;
char buffer[1024];
static int last_style = 0;
fp=popen("lsusb | grep \"QinHeng Electronics\"", "r");
fgets(buffer,sizeof(buffer),fp);
//printf("%s",buffer);
if(strstr(buffer, "QinHeng Electronics") != 0)
{
pclose(fp);
return true;
}
else
{
pclose(fp);
return false;
}
}
bool moko_test_func()
{
FILE *fp;
char buffer[1024];
static int last_style = 0;
fp = popen("lsusb | grep \"OpenMoko\"", "r");
fgets(buffer, sizeof(buffer), fp);
if (strstr(buffer, "OpenMoko") != 0) {
pclose(fp);
return true;
} else {
pclose(fp);
return false;
}
}
bool network_test_func()
{
FILE *fp;
char buffer[1024];
static int last_style = 0;
try
{
fp=popen("ifconfig | grep \"inet 192.168.\"", "r");
fgets(buffer,sizeof(buffer),fp);
if(strstr(buffer, "inet 192.168.") != 0)
{
pclose(fp);
return true;
}
else
{
pclose(fp);
return false;
}
}
catch (char *str)
{ pclose(fp);
std::cout << "Standard exception: " << str << std::endl;
}
return 0;
}

536
src/mks_update.cpp Normal file
View File

@@ -0,0 +1,536 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <memory>
#include <dirent.h>
#include <cstring>
#include <cstdlib>
#include "../include/event.h"
#include "../include/send_msg.h"
#include "../include/MakerbaseSerial.h"
extern int tty_fd; // main.cpp 里面的变量
extern bool is_download_to_screen; // main.cpp 里面的变量
int copy_fd;
bool detected_soc_data;
bool detected_mcu_data;
bool detected_ui_data;
// CLL 新增检测Q1的SOC和UI更新
bool detected_q1_soc_data;
bool detected_q1_ui_data;
// CCW 4.4.14 新增Q1补丁包检测更新
bool detected_q1_patch_data = false;
DIR *dir;
struct dirent *entry;
std::string base_path = "/home/mks/gcode_files/sda1/QD_Update/";
bool detected_printer_cfg;
bool detected_gcode_cfg;
bool detected_MKS_THR_cfg;
bool detected_gcode;
// 4.4.3 CLL 修改deb文件也能更新
bool detected_soc_deb;
std::ifstream tftfile;
int tft_buff = 4096;
int tft_start;
int tft_end;
std::string tft_s;
std::string tft_data;
int tft_len;
int filesize;
int tft_index;
char tft_buffer[4096] = {0};
int u_disk_update()
{
int fd = 1;
char PATH[64];
char cmd[64];
char chOrder[50];
char chOrder1[50];
int i = 0;
int j = 0;
char ch[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
for (j = 0; j < 4; j++)
{
for (i = 0; i < 8; i++)
{
sprintf(PATH, "/home/mks/gcode_files/sd%c%d/QD_Update/QD_Mates3_SOC", ch[i], j);
fd = access(PATH, F_OK);
if (fd == 0)
{
printf("检测到U盘下存在目录%s正在检测更新文件\n", PATH);
sprintf(cmd, "dpkg -i %s; rm %s -f", PATH, PATH);
system(cmd);
break;
}
else
{
// printf("没有检测到U盘相关的内容\n");
continue;
}
}
if (fd == 0)
{
break;
}
}
if (fd == -1)
{
printf("无法打开u盘\n");
}
else
{
close(fd);
}
return 0;
}
bool detect_update()
{
int fd_soc_data;
int fd_mcu_data;
int fd_ui_data;
int fd_printer_cfg;
int fd_gcode_cfg;
int fd_mks_thr_cfg;
int fd_gcode;
// 4.4.3 CLL 新增deb文件也能更新
int fd_soc_deb;
fd_soc_data = access("/home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC", F_OK);
if (fd_soc_data == 0)
{
detected_soc_data = true;
}
else
{
detected_soc_data = false;
fd_soc_data = access("/home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC", F_OK);
if (fd_soc_data == 0)
{
detected_q1_soc_data = true;
}
else
{
detected_q1_soc_data = false;
}
}
if ((dir = opendir(base_path.c_str())) != nullptr)
{
while ((entry = readdir(dir)) != nullptr)
{
std::string filename = entry->d_name;
if (filename.find("QD_Q1_PATCH") == 0)
{
detected_q1_patch_data = true; // 找到 QD_Q1_PATCH 开头文件
break;
}
}
closedir(dir);
}
fd_mcu_data = access("/home/mks/gcode_files/sda1/QD_MCU/MCU", F_OK);
if (fd_mcu_data == 0)
{
detected_mcu_data = true;
}
else
{
detected_mcu_data = false;
}
fd_ui_data = access("/home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI", F_OK);
if (fd_ui_data == 0)
{
detected_ui_data = true;
}
else
{
detected_ui_data = false;
fd_ui_data = access("/home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI", F_OK);
if (fd_ui_data == 0)
{
detected_q1_ui_data = true;
}
else
{
detected_q1_ui_data = false;
}
}
fd_gcode_cfg = access("/home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg", F_OK);
if (fd_gcode_cfg == 0)
{
detected_gcode_cfg = true;
}
else
{
detected_gcode_cfg = false;
}
fd_printer_cfg = access("/home/mks/gcode_files/sda1/QD_Update/printer.cfg", F_OK);
if (fd_printer_cfg == 0)
{
detected_printer_cfg = true;
}
else
{
detected_printer_cfg = false;
}
fd_mks_thr_cfg = access("/home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg", F_OK);
if (fd_mks_thr_cfg == 0)
{
detected_MKS_THR_cfg = true;
}
else
{
detected_MKS_THR_cfg = false;
}
fd_gcode = access("/home/mks/gcode_files/sda1/QD_Update/QD_Gcode", F_OK);
if (fd_gcode == 0)
{
detected_gcode = true;
}
else
{
detected_gcode = false;
}
// 4.4.3 CLL 新增deb文件也能更新
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
fd_soc_deb = access("/home/mks/gcode_files/sda1/QD_Update/mks.deb", F_OK);
if (fd_soc_deb == 0)
{
detected_soc_deb = true;
}
else
{
detected_soc_deb = false;
}
}
return (detected_soc_data | detected_q1_soc_data | detected_mcu_data | detected_ui_data | detected_q1_ui_data | detected_printer_cfg | detected_MKS_THR_cfg | detected_gcode | detected_soc_deb | detected_gcode_cfg | detected_q1_patch_data);
}
void start_update()
{
system("rm /home/mks/gcode_files/.cache/*");
if (detected_mcu_data == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
// std::cout << "检测到qidi文件" << std::endl;
system("cp /home/mks/gcode_files/sda1/QD_MCU/MCU /root/klipper.bin;");
// reset_firmware();
close_mcu_port();
// sleep(1);
// system("service klipper stop; /root/hid-flash /root/klipper.bin ttyS0;");
system("service klipper stop; /root/hid-flash /root/klipper.bin ttyS0; systemctl start klipper; ");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
// std::cout << "检测到qidi文件" << std::endl;
system("cp /home/mks/gcode_files/sda1/QD_MCU/MCU /root/klipper.bin;");
// reset_firmware();
close_mcu_port();
// sleep(1);
// system("service klipper stop; /root/hid-flash /root/klipper.bin ttyS0;");
system("service klipper stop; /root/hid-flash /root/klipper.bin ttyS0; systemctl start klipper; ");
}
else
{
// std::cout << "没有检测到qidi文件" << std::endl;
system("cp /home/mks/gcode_files/sda1/QD_MCU/MCU /root/klipper.bin;");
// reset_firmware();
close_mcu_port();
// sleep(2);
system("service klipper stop; /root/hid-flash /root/klipper.bin ttyS0; systemctl start klipper; mv /home/mks/gcode_files/sda1/QD_MCU/MCU /home/mks/gcode_files/sda1/QD_MCU/MCU.bak");
}
}
}
if (detected_ui_data == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI /root/800_480.tft; sync");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI /root/800_480.tft; sync");
}
else
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI /root/800_480.tft; mv /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_UI.bak; sync");
}
}
}
else if (detected_q1_ui_data == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI /root/800_480.tft; sync");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI /root/800_480.tft; sync");
}
else
{
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI /root/800_480.tft; mv /home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI /home/mks/gcode_files/sda1/QD_Update/QD_Q1_UI.bak; sync");
}
}
}
if (detected_gcode_cfg == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg /home/mks/klipper_config/gcode_macro.cfg; chmod 777 /home/mks/klipper_config/gcode_macro.cfg; sync");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg /home/mks/klipper_config/gcode_macro.cfg; chmod 777 /home/mks/klipper_config/gcode_macro.cfg; sync");
}
else
{
system("cp /home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg /home/mks/klipper_config/gcode_macro.cfg; chmod 777 /home/mks/klipper_config/gcode_macro.cfg; mv /home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg /home/mks/gcode_files/sda1/QD_Update/gcode_macro.cfg.bak; sync");
}
}
}
if (detected_printer_cfg == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/printer.cfg /home/mks/klipper_config/printer.cfg; chmod 777 /home/mks/klipper_config/printer.cfg; sync");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/printer.cfg /home/mks/klipper_config/printer.cfg; chmod 777 /home/mks/klipper_config/printer.cfg; sync");
}
else
{
system("cp /home/mks/gcode_files/sda1/QD_Update/printer.cfg /home/mks/klipper_config/printer.cfg; chmod 777 /home/mks/klipper_config/printer.cfg; mv /home/mks/gcode_files/sda1/QD_Update/printer.cfg /home/mks/gcode_files/sda1/QD_Update/printer.cfg.bak; sync");
}
}
}
if (detected_MKS_THR_cfg == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg /home/mks/klipper_config/MKS_THR.cfg; chmod 777 /home/mks/klipper_config/MKS_THR.cfg; sync");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
system("cp /home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg /home/mks/klipper_config/MKS_THR.cfg; chmod 777 /home/mks/klipper_config/MKS_THR.cfg; sync");
}
else
{
system("cp /home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg /home/mks/klipper_config/MKS_THR.cfg; chmod 777 /home/mks/klipper_config/MKS_THR.cfg; mv /home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg /home/mks/gcode_files/sda1/QD_Update/MKS_THR.cfg.bak; sync");
}
}
}
if (detected_gcode == true)
{
// 先清空gcode_files文件夹中的所有其他文件,会保留下sda1目录和其中的文件使用-rf指令更改路径需要谨慎
system("rm /home/mks/gcode_files/*\n");
system("rm /home/mks/gcode_files/.thumbs/*\n");
system("systemctl stop moonraker.service\n");
system("find /home/mks/gcode_files -maxdepth 1 -type d ! -name sd* -a ! -name '.*' | grep gcode_files/ | xargs rm -rf");
system("cp /home/mks/gcode_files/sda1/QD_Update/QD_gcode/*.gcode /home/mks/gcode_files; chmod 777 /home/mks/gcode_files/*.gcode; sync");
}
// 检测到补丁文件
if (detected_q1_patch_data)
{
bool factory_mode = (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) != -1);
if ((dir = opendir(base_path.c_str())) != nullptr)
{
while ((entry = readdir(dir)) != nullptr)
{
std::string filename = entry->d_name;
if (filename.find("QD_Q1_PATCH") == 0)
{
std::string file_path = base_path + filename;
std::string command = "mv " + file_path + " " + base_path + "mks.deb; dpkg -i --force-overwrite " + base_path + "mks.deb;";
system(command.c_str());
std::string new_file_name = file_path;
if (!factory_mode)
{
new_file_name += ".bak";
}
command = "mv " + base_path + "mks.deb " + new_file_name + "; sync";
system(command.c_str());
}
}
closedir(dir);
}
}
if (detected_soc_data == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
std::cout << "检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC; sync;");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
std::cout << "检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC; sync;");
}
else
{
std::cout << "没有检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Mates3_SOC.bak; sync;");
}
}
}
else if (detected_soc_deb == true)
{ // 4.4.3 CLL 修改deb文件可以更新
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
system("dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb;sync");
}
}
else if (detected_q1_soc_data == true)
{
if (access("/home/mks/gcode_files/sda1/QD_factory_mode.txt", F_OK) == 0)
{
std::cout << "检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC; sync;");
}
else
{
if (access("/home/mks/gcode_files/sda1/QD_Update/QD_factory_mode.txt", F_OK) == 0)
{
std::cout << "检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC; sync;");
}
else
{
std::cout << "没有检测到qidi文件" << std::endl;
system("mv /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC /home/mks/gcode_files/sda1/QD_Update/mks.deb; dpkg -i --force-overwrite /home/mks/gcode_files/sda1/QD_Update/mks.deb; mv /home/mks/gcode_files/sda1/QD_Update/mks.deb /home/mks/gcode_files/sda1/QD_Update/QD_Q1_SOC.bak; sync;");
}
}
}
update_finished_tips();
}
void download_to_screen()
{
std::cout << "tft_start == " << tft_start << std::endl;
if (tft_start < tft_len)
{
if (tft_end > tft_len)
{
tft_s = tft_data.substr(tft_start, tft_len - tft_start);
std::cout << "发送下载数据 == " << tft_start << "/" << filesize << std::endl;
send_cmd_download_data(tty_fd, tft_s);
}
tft_s = tft_data.substr(tft_start, tft_buff);
std::cout << tft_s.length() << " 发送下载数据 == " << tft_start << "/" << filesize << std::endl;
tft_start = tft_end;
tft_end = tft_end + tft_buff;
send_cmd_download_data(tty_fd, tft_s);
}
}
void init_download_to_screen()
{
if (access("/root/800_480.tft", F_OK) == 0)
{
tft_data.clear();
tftfile.open("/root/800_480.tft");
struct stat tft_stat;
stat("/root/800_480.tft", &tft_stat);
filesize = tft_stat.st_size;
std::cout << "文件大小为: " << filesize << std::endl;
std::ostringstream temp;
temp << tftfile.rdbuf();
tft_data = temp.str();
std::cout << "读取的字符串长度为:" << tft_data.length() << std::endl;
tft_len = tft_data.length();
tft_end = tft_buff;
tftfile.close();
}
}
void back_to_screen_old()
{
if (access("/root/800_480.tft.bak", F_OK) == 0)
{
tft_data.clear();
tftfile.open("/root/800_480.tft.bak");
struct stat tft_stat;
stat("/root/800_480.tft.bak", &tft_stat);
filesize = tft_stat.st_size;
std::cout << "文件大小为: " << filesize << std::endl;
send_cmd_download(tty_fd, filesize);
std::ostringstream temp;
temp << tftfile.rdbuf();
tft_data = temp.str();
tft_len = tft_data.length();
tft_end = tft_buff;
tftfile.close();
}
}

1028
src/mks_wpa_cli.cpp Normal file

File diff suppressed because it is too large Load Diff

610
src/send_jpg.cpp Normal file
View File

@@ -0,0 +1,610 @@
#include "../include/mks_log.h"
#include "../include/send_msg.h"
#include "../include/MakerbaseSerial.h"
#include "../include/send_jpg.h"
#include "../include/mks_file.h"
// #define BLOCK_SIZE 2048
// #define HEADER_SIZE 12
extern int tty_fd;
bool get_0xfe = false;
bool get_0x06 = false;
bool get_0x05 = false;
bool get_0xfd = false;
bool get_0x04 = false;
bool get_0x24 = false;
bool have_64_jpg[6];
std::string have_64_png_path[6];
bool begin_show_64_jpg;
bool begin_show_160_jpg;
bool begin_show_192_jpg;
bool show_192_jpg_complete = true;
std::string jpg_160_path;
int time_differ(int duration, int start_time) {
int tmp;
tmp = time(NULL);
tmp = tmp - start_time;
if (tmp > duration) {
return 1;
} else {
return 0;
}
}
int time_differ_ms(long duration, long start_time) {
struct timeval tv1;
gettimeofday(&tv1, NULL);
long tmp;
tmp = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
tmp = tmp - start_time;
if (tmp > duration) {
return 1;
} else {
return 0;
}
}
extern std::string input_path;
extern int input_size;
extern bool start_path;
// 刷预览图线程
void *sent_jpg_thread_handle(void *arg)
{
std::string png_path = "";
std::string ram_path = "";
std::string jpg_path = "";
while (1)
{
// 刷新小预览图
if (begin_show_64_jpg)
{
begin_show_64_jpg = false;
for (uint i = 0; i < 6; i++)
{
if (have_64_jpg[i] == true)
{
send_cmd_tsw(tty_fd, "255", "0"); // 禁止屏幕触摸
MKSLOG_BLUE("不能触摸屏幕");
usleep(50500 + i * 500);
ram_path = std::string("ram/") + std::string("file") + std::to_string(i) + std::string(".jpg");
// jpg_path = page_files_root_path + std::string("/") + page_files_path + std::string("/.thumbs/") + page_files_list_show_name[i].substr(0, page_files_list_show_name[i].find(".gcode")) + std::string("-64x64.jpg");
// output_jpg(have_64_png_path[i], input_size);
// std::cout << extractFileName(have_64_png_path[i]) << std::endl;
// if (i < 4) {
// output_jpg(have_64_png_path[i], 112);
// } else {
// output_jpg(have_64_png_path[i], 160);
// }
// jpg_path = "/home/mks/tjc.jpg";
jpg_path = "/home/mks/gcode_files/" + have_64_png_path[i] ;
// send_cmd_baud(tty_fd, 230400);
std::cout << jpg_path << std::endl;
// usleep(50000);
// set_option(tty_fd, 230400, 8, 'N', 1);
// if (sent_jpg_to_tjc(ram_path, jpg_path) != true)
// {
sent_jpg_to_tjc(ram_path, jpg_path);
// }
// send_cmd_baud(tty_fd, 115200);
// usleep(50000);
// set_option(tty_fd, 115200, 8, 'N', 1);
have_64_jpg[i] = false;
// system("rm /home/mks/tjc.jpg");
send_cmd_tsw(tty_fd, "255", "1"); // 使能屏幕触摸
MKSLOG_BLUE("可以触摸屏幕");
}
}
}
// 刷新预览界面预览图
// if (begin_show_192_jpg)
// {
// // jpg_path = page_files_root_path + std::string("/") + page_files_path + std::string("/.thumbs/") + current_select_file.substr(0, current_select_file.find(".gcode")) + std::string("-192x192.jpg");
// jpg_path = "/root/tjc.jpg";
// while (1)
// {
// if (sent_jpg_to_tjc("ram/file0.jpg", jpg_path) == true)
// {
// break;
// }
// delet_pic("ram/file0.jpg");
// usleep(500000);
// }
// begin_show_192_jpg = false;
// show_192_jpg_complete = true;
// }
// 刷新打印界面预览图
// if (begin_show_160_jpg)
// {
// while (1)
// {
// if (sent_jpg_to_tjc("ram/160.jpg", jpg_160_path) == true)
// {
// break;
// }
// delet_pic("ram/160.jpg");
// usleep(500000);
// }
// begin_show_160_jpg = false;
// }
// 提前删除预览界面的预览图,防止进入预览页面时闪一下
// if (current_page_id != TJC_PAGE_PREVIEW)
// {
// if (show_192_jpg_complete)
// {
// delet_pic("ram/192.jpg");
// show_192_jpg_complete = false;
// }
// }
usleep(60000);
}
}
// 删除图片
void delet_pic(std::string ram_path)
{
send_cmd_delfile(tty_fd, ram_path);
}
// 获取文件大小
long getFileSize(FILE *file)
{
long fileSize = -1;
if (file != NULL)
{
if (fseek(file, 0L, SEEK_END) == 0)
{
fileSize = ftell(file);
}
rewind(file);
}
return fileSize;
}
// 计算单个数据的校验码
unsigned int calccrc(unsigned char crcbuf, unsigned int crc)
{
unsigned char i;
crc = crc ^ crcbuf;
for (i = 0; i < 8; i++)
{
unsigned char chk;
chk = crc & 1;
crc = crc >> 1;
crc = crc & 0x7fff;
if (chk == 1)
crc = crc ^ 0xa001;
crc = crc & 0xffff;
}
return crc;
}
// 计算一串数据的校验码
unsigned int check_crc(unsigned char *buf, unsigned int len)
{
unsigned char hi, lo;
unsigned int i;
unsigned int crc;
crc = 0xFFFF;
for (i = 0; i < len; i++)
{
crc = calccrc(*buf, crc);
buf++;
}
hi = crc % 256;
lo = crc / 256;
crc = (hi << 8) | lo;
return crc;
}
// 删除所有小预览图
void delete_small_jpg()
{
delet_pic("ram/file0.jpg");
usleep(56000);
delet_pic("ram/file1.jpg");
usleep(56000);
delet_pic("ram/file2.jpg");
usleep(56000);
delet_pic("ram/file3.jpg");
usleep(56000);
}
// 发送图片
bool sent_jpg_to_tjc(std::string ram_path, std::string jpg_path)
{
FILE *file;
long filesize;
int file_res = 0;
static int start_time;
struct timeval tv1;
long resent_time;
uint16_t head_id = 0;
uint8_t head_buf[12] = {0x3A, 0xA1, 0xBB, 0x44, 0x7F, 0xFF, 0xFE, 0x01, 0x00, 0x00, 0xDC, 0x07};
uint8_t exit_buf[12] = {0x3A, 0xA1, 0xBB, 0x44, 0x7F, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0x00, 0x00};
uint8_t read_buf[BLOCK_SIZE - sizeof(head_buf)] = {0}; // 最大4096 - 帧头
// MKSLOG_BLUE("图片路径为:%s", jpg_path.c_str());
file = fopen(jpg_path.c_str(), "r");
if (file == NULL)
{
MKSLOG_BLUE("文件打开失败");
return true;
}
filesize = getFileSize(file);
// MKSLOG_BLUE("文件大小为: %ld字节", filesize);
// 发送透传指令
send_cmd_twfile(tty_fd, ram_path, std::to_string(filesize));
// 延时等待收到0xfe+结束符
usleep(105000);
// 循环发送包头+4096个数据直到文件结尾
start_time = time(NULL);
while (1)
{
memset(read_buf, 0x00, sizeof(read_buf));
file_res = fread(read_buf, 1, (sizeof(read_buf) - 2), file); // 留两字节存放校验码
// MKSLOG_BLUE("读取大小为: %ld字节", file_res);
if (file_res <= 0)
{
break;
}
// 发送包头
head_buf[8] = head_id & 0xff;
head_buf[9] = head_id >> 8;
head_buf[10] = (file_res+2) & 0xff;
head_buf[11] = (file_res+2) >> 8;
write(tty_fd, head_buf, sizeof(head_buf));
// 打印头数据
// for (int i = 0; i < sizeof(head_buf); i++)
// {
// printf("%02X", head_buf[i]);
// }
// printf("\n");
// 获取校验码,存放在最后两字节
uint16_t crc_val = check_crc(read_buf, file_res);
read_buf[file_res] = crc_val >> 8;
read_buf[file_res + 1] = crc_val & 0xff;
// MKSLOG_BLUE("校验码为: %02X, %02X", crc_val >> 8, crc_val & 0xff);
// tcdrain(tty_fd);
// 发送数据
write(tty_fd, read_buf, file_res+2);
// tcdrain(tty_fd);
// 打印数据
// for (int i = 0; i < file_res+2; i++)
// {
// printf("%02X", read_buf[i]);
// }
// printf("\n");
// 返回0x05表示这一帧写入成功
start_time = time(NULL);
gettimeofday(&tv1, NULL);
resent_time = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
get_0x05 = false;
get_0xfd = false;
get_0x04 = false;
while (!get_0x05 && !get_0xfd)
{
usleep(80000);
// 返回0x04表示这一帧写入失败
if (get_0x04)
{
// 打印退出透传模式
// tcdrain(tty_fd);
write(tty_fd, exit_buf, sizeof(exit_buf));
// tcdrain(tty_fd);
for (int i = 0; i < sizeof(exit_buf); i++)
{
printf("%02X", exit_buf[i]);
}
printf("\n");
write(tty_fd, exit_buf, sizeof(exit_buf));
// tcdrain(tty_fd);
MKSLOG_GREEN("返回0x04失败");
fclose(file);
return false;
}
// 超时重发机制
gettimeofday(&tv1, NULL);
if (time_differ_ms(800, resent_time) && get_0x24 == false)
{
gettimeofday(&tv1, NULL);
resent_time = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
// 重发数据帧
write(tty_fd, head_buf, sizeof(head_buf));
// tcdrain(tty_fd);
write(tty_fd, read_buf, file_res+2);
MKSLOG_GREEN("返回超时,重发数据包");
}
// 超时机制
if (time_differ(4, start_time))
{
write(tty_fd, exit_buf, sizeof(exit_buf));
for (int i = 0; i < sizeof(exit_buf); i++)
{
printf("%02X", exit_buf[i]);
}
printf("\n");
write(tty_fd, exit_buf, sizeof(exit_buf));
// tcdrain(tty_fd);
write(tty_fd, exit_buf, sizeof(exit_buf));
// tcdrain(tty_fd);
MKSLOG_GREEN("写数据帧超时,失败");
fclose(file);
return false;
}
// CLL 缓冲区溢出时停止发送
if (get_0x24 == true) {
sleep(4);
get_0x24 = false;
return false;
}
}
// 修改包头ID
head_id++;
// 超时机制
if (time_differ(6, start_time))
{
write(tty_fd, exit_buf, sizeof(exit_buf));
for (int i = 0; i < sizeof(exit_buf); i++)
{
printf("%02X", exit_buf[i]);
}
printf("\n");
write(tty_fd, exit_buf, sizeof(exit_buf));
write(tty_fd, exit_buf, sizeof(exit_buf));
MKSLOG_GREEN("写图片超时,失败");
fclose(file);
break;
}
}
MKSLOG_GREEN("成功写入图片到内存");
fclose(file);
return true;
}
void printHex(const uint8_t *data, size_t size) {
for (size_t i = 0; i < size; ++i) {
printf("%02X", data[i]);
}
// printf("\n");
}
// bool mks_send_jpg(char *path, int fd, int index) {
// // FILE *input_file, *output_file;
// FILE *input_file;
// uint8_t head_buf[HEADER_SIZE] = {0x3A, 0xA1, 0xBB, 0x44, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xDC, 0x07};
// uint8_t exit_buf[12] = {0x3A, 0xA1, 0xBB, 0x44, 0x7F, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0x00, 0x00};
// uint8_t buffer[BLOCK_SIZE - HEADER_SIZE]; // 数据块的大小减去帧头的大小
// size_t bytes_read;
// long file_size;
// uint16_t head_id = 0;
// input_file = fopen(path, "rb");
// if (input_file == NULL) {
// perror("Error opening input file");
// return false;
// }
// // 获取文件大小
// fseek(input_file, 0, SEEK_END);
// file_size = ftell(input_file);
// fseek(input_file, 0, SEEK_SET);
// // char cmd[32];
// // sprintf(cmd, "twfile \"ram/file%d.jpg\",%ld\xff\xff\xff", index, file_size);
// // write(fd, cmd, sizeof(cmd));
// // usleep(100000);
// char ram_path[32];
// sprintf(ram_path, "ram/file%d.jpg", index);
// std::string to_out = ram_path;
// send_cmd_twfile(fd, to_out, std::to_string(file_size));
/*
sleep(5);
// 逐块读取输入文件,动态拼接帧头和数据,然后写入输出文件
while ((bytes_read = fread(buffer, 1, sizeof(buffer), input_file)) > 0) {
head_buf[8] = head_id & 0xff;
head_buf[9] = head_id >> 8;
head_buf[10] = bytes_read & 0xff;
head_buf[11] = bytes_read >> 8;
// 写入帧头
write(fd, head_buf, sizeof(head_buf));
tcdrain(fd);
// 写入读取的数据块
write(fd, buffer, bytes_read);
// 写入帧头
// fwrite(head_buf, 1, sizeof(head_buf), output_file);
// 写入读取的数据块
// fwrite(buffer, 1, bytes_read, output_file);
printf("Hexadecimal content written:\n");
printHex(head_buf, sizeof(head_buf));
printHex(buffer, bytes_read);
printf("\n");
head_id++;
usleep(2000000);
}
*/
// static int start_time;
// struct timeval tv1;
// long resent_time;
// start_time = time(NULL);
// while (1) {
// bytes_read = fread(buffer, 1, sizeof(buffer), input_file);
// head_buf[8] = head_id & 0xff;
// head_buf[9] = head_id >> 8;
// head_buf[10] = bytes_read & 0xff;
// head_buf[11] = bytes_read >> 8;
// write(fd, head_buf, sizeof(head_buf));
// tcdrain(fd);
// write(fd, buffer, bytes_read);
// printf("Hexadecimal content written:\n");
// printHex(head_buf, sizeof(head_buf));
// printHex(buffer, bytes_read);
// printf("\n");
// // 返回0x05表示这一帧写入成功
// start_time = time(NULL);
// gettimeofday(&tv1, NULL);
// resent_time = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
// get_0x05 = false;
// get_0xfd = false;
// get_0x04 = false;
// while (!get_0x05 && !get_0xfd)
// {
// usleep(100000);
// // 返回0x04表示这一帧写入失败
// if (get_0x04)
// {
// // 打印退出透传模式
// write(fd, exit_buf, sizeof(exit_buf));
// for (int i = 0; i < sizeof(exit_buf); i++)
// {
// printf("%02X", exit_buf[i]);
// }
// printf("\n");
// write(fd, exit_buf, sizeof(exit_buf));
// MKSLOG_YELLOW("返回0x04失败");
// fclose(input_file);
// return false;
// }
// // 超时重发机制
// gettimeofday(&tv1, NULL);
// if (time_differ_ms(6000, resent_time))
// {
// gettimeofday(&tv1, NULL);
// resent_time = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
// // 重发数据帧
// write(fd, head_buf, sizeof(head_buf));
// write(fd, buffer, bytes_read);
// MKSLOG_YELLOW("返回超时,重发数据包");
// }
// // 超时机制
// if (time_differ(3, start_time))
// {
// write(fd, exit_buf, sizeof(exit_buf));
// for (int i = 0; i < sizeof(exit_buf); i++)
// {
// printf("%02X", exit_buf[i]);
// }
// printf("\n");
// write(fd, exit_buf, sizeof(exit_buf));
// write(fd, exit_buf, sizeof(exit_buf));
// MKSLOG_YELLOW("写数据帧超时,失败");
// fclose(input_file);
// return false;
// }
// }
// head_id++;
// // 超时机制
// if (time_differ(10, start_time))
// {
// write(fd, exit_buf, sizeof(exit_buf));
// for (int i = 0; i < sizeof(exit_buf); i++)
// {
// printf("%02X", exit_buf[i]);
// }
// printf("\n");
// write(fd, exit_buf, sizeof(exit_buf));
// write(fd, exit_buf, sizeof(exit_buf));
// MKSLOG_YELLOW("写图片超时,失败");
// fclose(input_file);
// break;
// }
// }
// // 关闭文件
// fclose(input_file);
// MKSLOG_YELLOW("成功写入图片到内存");
// printf("File processing complete.\n");
// return true;
// }
// bool begin_show_64_jpg;
// bool begin_show_160_jpg;
// bool begin_show_192_jpg;
// bool show_192_jpg_complete = true;
// bool have_64_jpg[4];
// void *sent_jpg_thread_handle(void *arg) {
// std::string png_path = "";
// std::string ram_path = "";
// std::string jpg_path = "";
// while (1) {
// // 刷新小预览图
// if (begin_show_64_jpg) {
// begin_show_64_jpg = false;
// for (uint i = 0; i < 4; i++) {
// if (have_64_jpg[i] == true) {
// /*
// if (mks_send_jpg(jpg_path.c_str(), tty_fd, i) != false) {
// }
// */
// }
// }
// }
// usleep(50000);
// }
// }

644
src/send_msg.cpp Normal file
View File

@@ -0,0 +1,644 @@
#include "../include/mks_log.h"
#include "../include/send_msg.h"
#include "../include/MakerbaseSerial.h"
extern int copy_fd;
// 刷新页面
void send_cmd_page(int fd, std::string pageid) {
std::string cmd = "page " + pageid + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 重绘控件
void send_cmd_ref(int fd, std::string obj) {
std::string cmd = "ref " + obj + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 激活控件按下/弹起事件
void send_cmd_click(int fd, std::string obj, std::string event) {
std::string cmd = "click " + obj + "," + event + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), sizeof(cmd));
}
// 带格式获取变量值/常量值
void send_cmd_get(int fd, std::string att) {
std::string cmd = "get " + att + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 从串口打印一个变量/常量
void send_cmd_prints(int fd, std::string att, int lenth = 0) {
std::string cmd = "prints " + att + "," + std::to_string(lenth) + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 隐藏/显示控件
void send_cmd_vis(int fd, std::string obj, std::string state) {
std::string cmd = "vis " + obj + "," + state + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 控件触摸使能
void send_cmd_tsw(int fd, std::string obj, std::string state) {
std::string cmd = "tsw " + obj + "," + state + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 随机数范围设置
void send_cmd_randset(int fd, std::string minval, std::string maxval) {
std::string cmd = "randset " + minval + "," + maxval + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 往曲线控件添加数据
void send_cmd_add(int fd, std::string objid, std::string ch, std::string val) {
std::string cmd = "add " + objid + "," + ch + "," + val + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 清除曲线控件中的数据
void send_cmd_cle(int fd, std::string objid, std::string ch) {
std::string cmd = "cle " + objid + "," + ch + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 曲线数据透传指令
void send_cmd_addt(int fd, std::string objid, std::string ch, std::string qyt) {
std::string cmd = "addt " + objid + "," + ch + "," + qyt + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 转让系统控制权给屏幕刷新
void send_cmd_doevents(int fd) {
std::string cmd = "doevents\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 发送当前页面ID号到串口
void send_cmd_sendme(int fd) {
std::string cmd = "sendme\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 变量类型转换
void send_cmd_covx(int fd, std::string att1, std::string att2, std::string lenth) {
std::string cmd = "covx " + att1 + "," + att2 + "," + lenth + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 字符串变量字符长度测试
void send_cmd_strlen(int fd, std::string att0, std::string att1) {
std::string cmd = "strlen " + att0 + "," + att1 + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 字符串变量字节长度测试
void send_cmd_btlen(int fd, std::string att0, std::string att1) {
std::string cmd = "btlen " + att0 + "," + att1 + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 字符串截取
void send_cmd_substr(int fd, std::string att0, std::string att1, std::string star, std::string lenth) {
std::string cmd = "substr " + att0 + "," + att1 + "," + star + "," + lenth + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 字符串分割
void send_cmd_spstr(int fd, std::string src, std::string dec, std::string key, std::string indec) {
std::string cmd = "spstr " + src + "," + dec + "," + key + "," + indec + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 触摸校准
void send_cmd_touch_j(int fd) {
std::string cmd = "touch_j\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 暂停屏幕刷新
void send_cmd_ref_stop(int fd) {
std::string cmd = "ref_stop\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 恢复屏幕刷新
void send_cmd_ref_star(int fd) {
std::string cmd = "ref_star\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 暂停串口指令执行
void send_cmd_com_stop(int fd) {
std::string cmd = "com_stop\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 恢复串口指令执行
void send_cmd_com_star(int fd) {
std::string cmd = "com_star\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 清空串口指令缓冲区
void send_cmd_code_c(int fd) {
std::string cmd = "code_c\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 复位
void send_cmd_rest(int fd) {
std::string cmd = "rest\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 写入一个变量到用户存储区
void send_cmd_wepo(int fd, std::string att, std::string add) {
std::string cmd = "wepo " + att + "," + add + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 从用户存储区读数据到变量
void send_cmd_repo(int fd, std::string att, std::string add) {
std::string cmd = "repo " + att + "," + add + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 透传数据写入用户存储区
void send_cmd_wept(int fd, std::string add, std::string lenth) {
std::string cmd = "wept " + add + "," + lenth + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 从用户存储区透传数据到串口
void send_cmd_rept(int fd, std::string add, std::string lenth) {
std::string cmd = "rept " + add + "," + lenth + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 扩展IO模式配置
void send_cmd_cfgpio(int fd, std::string id, std::string state, std::string obj) {
std::string cmd = "cfgpio " + id + "," + state + "," + obj + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 复位crc初始值
void send_cmd_crcrest(int fd, std::string crctype, std::string initval) {
std::string cmd = "crcrest " + crctype + "," + initval + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// crc校验一个变量/常量
void send_cmd_crcputs(int fd, std::string att, std::string length) {
std::string cmd = "crcputs " + att + "," + length + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// crc校验一组Hex
void send_cmd_crcputh(int fd, std::string hex) {
std::string cmd = "crcputh " + hex + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// crc校验一段串口缓冲区数据(recmod=1时有效)
void send_cmd_crcputu(int fd, std::string star, std::string length) {
std::string cmd = "crcputu " + star + "," + length + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 运行中改变控件图层顺序(仅X3,X5系列支持)
void send_cmd_setlayer(int fd, std::string obj0, std::string obj1) {
std::string cmd = "setplayer " + obj0 + "," + obj1 + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 控件移动 (仅X3,X5系列支持)
void send_cmd_move(int fd, std::string obj, std::string startx, std::string starty, std::string endx, std::string endy, std::string first, std::string time) {
std::string cmd = "move " + obj + "," + startx + "," + starty + "," + endx + "," + endy + "," + first + "," + time + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 音频播放 (仅X3,X5系列支持)
void send_cmd_play(int fd, std::string ch, std::string audio, std::string loop) {
std::string cmd = "play " + ch + "," + audio + "," + loop + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 串口透传文件 (仅X3,X5系列支持)
void send_cmd_twfile(int fd, std::string filepath, std::string filesize) {
std::string cmd = "twfile \"" + filepath + "\"," + filesize + "\xff\xff\xff";
MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 删除文件 (仅X3,X5系列支持)
void send_cmd_delfile(int fd, std::string filepath) {
std::string cmd = "delfile \"" + filepath + "\"\xff\xff\xff";
MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 重命名文件 (仅X3,X5系列支持)
void send_cmd_refile(int fd, std::string srcfilepath, std::string decfilepath) {
std::string cmd = "refile " + srcfilepath + "," + decfilepath + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 查找文件 (仅X3,X5系列支持)
void send_cmd_findfile(int fd, std::string filepath, std::string att) {
std::string cmd = "findfile " + filepath + "," + att + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 透传读文件 (仅X3,X5系列支持)
void send_cmd_rdfile(int fd, std::string filepath, std::string addr, std::string size, std::string crc) {
std::string cmd = "rdfile " + filepath + "," + addr + "," + size + "," + crc + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 创建文件 (仅X3,X5系列支持)
void send_cmd_newfile(int fd, std::string filepath, std::string size) {
std::string cmd = "newfile " + filepath + "," + size + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 创建文件夹 (仅X3,X5系列支持)
void send_cmd_newdir(int fd, std::string dir) {
std::string cmd = "newdir " + dir + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 删除文件夹 (仅X3,X5系列支持)
void send_cmd_deldir(int fd, std::string dir) {
std::string cmd = "deldir " + dir + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 重命名文件夹 (仅X3,X5系列支持)
void send_cmd_redir(int fd, std::string srcdir, std::string decdir) {
std::string cmd = "redir " + srcdir + "," + decdir + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 查找文件夹 (仅X3,X5系列支持)
void send_cmd_finddir(int fd, std::string dir, std::string att) {
std::string cmd = "finddir " + dir + "," + att + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 蜂鸣器 (仅X2系列支持)
void send_cmd_beep(int fd, std::string time) {
std::string cmd = "beep " + time + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 更改控件显示文本
void send_cmd_txt(int fd, std::string obj, std::string txt) {
std::string cmd = obj + ".txt=" + "\"" + txt + "\"" + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 更改控件显示图片
void send_cmd_pic(int fd, std::string obj, std::string pic) {
std::string cmd = obj + ".pic=" + pic + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_picc(int fd, std::string obj, std::string picc) {
std::string cmd = obj + ".picc=" + picc + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_picc2(int fd, std::string obj, std::string picc) {
std::string cmd = obj + ".picc2=" + picc + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 修改变量的值
void send_cmd_val(int fd, std::string obj, std::string val) {
std::string cmd = obj + ".val=" + val + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 修改颜色
void send_cmd_pco(int fd, std::string obj, std::string poc) {
std::string cmd = obj + ".pco=" + poc + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_pco2(int fd, std::string obj, std::string poc2) {
std::string cmd = obj + ".pco2=" + poc2 + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
// 修改背景图片
void send_cmd_bpic(int fd, std::string obj, std::string bpic) {
std::string cmd = obj + ".bpic=" + bpic + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_cp(int fd, std::string obj) {
std::string cp0 = obj + ".write(\"";
tcdrain(fd);
write(fd, cp0.data(), cp0.length());
}
void send_cmd_vid(int fd, std::string obj, std::string vid) {
std::string cmd = obj + ".vid=" + vid + "\xff\xff\xff";
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_cp_write(int fd, std::string obj, std::string data) {
// std::string cmd = obj + ".write(\"" + data + "\")\xff\xff\xff";
// std::string cp0 = obj + ".write(\"";
// std::string end = "\")\xff\xff\xff";
// write(fd, cp0.data(), cp0.length());
tcdrain(fd);
write(fd, data.data(), data.length());
// write(fd, end.data(), end.length());
// write(fd, cmd.data(), cmd.length());
}
void send_cmd_cp_end(int fd) {
std::string end = "\")\xff\xff\xff";
tcdrain(fd);
write(fd, end.data(), end.length());
}
void send_cmd_cp_close(int fd, std::string obj) {
std::string cmd = obj + ".close()\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_byte_data(int fd, char data) {
char buff[1];
buff[0] = data;
tcdrain(fd);
write(fd, buff, 1);
}
void send_cmd_write(int fd, std::string obj) {
std::string cmd = obj + ".write(\"";
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_write_end(int fd) {
std::string cmd = "\")\xff\xff\xff";
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_cp_image(int fd, std::string obj, std::string image) {
send_cmd_write(fd, obj);
tcdrain(fd);
write(fd, image.data(), image.length());
// MKSLOG_RED("写入图片");
/*
for (int i = 0; i < image.length(); i++) {
send_cmd_byte_data(fd, static_cast<char>(image[i]));
}
*/
send_cmd_write_end(fd);
}
void send_cmd_txt_start(int fd, std::string obj) {
std::string cmd = obj + ".txt=\"";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_txt_data(int fd, std::string txt) {
tcdrain(fd);
write(fd, txt.data(), txt.length());
}
void send_cmd_txt_end(int fd) {
std::string cmd = "\"\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_txt_plus(int fd, std::string obj1, std::string obj2, std::string obj3) {
std::string cmd = obj1 + ".txt=" + obj2 + ".txt+" + obj3 + ".txt\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_download(int fd, int filesize) {
std::string cmd = "whmi-wri " + std::to_string(filesize) + ",115200,0\xff\xff\xff";
// std::string cmd = "whmi-wri " + std::to_string(filesize) + ",9600,0\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
// set_option(fd, 230400, 8, 'N', 1);
}
void send_cmd_download_data(int fd, std::string data) {
// write(fd, data.data(), data.length());
// write(copy_fd, data.data(), data.length());
// int num = 1024;
int num = 512;
int len = data.length();
int end = num;
std::string sub_data;
for (int start = 0; start < len; ) {
if (end > len) {
sub_data = data.substr(start, len - start);
write(fd, sub_data.data(), sub_data.length());
// write(copy_fd, sub_data.data(), sub_data.length());
// set_option(fd, 115200, 8, 'N', 1);
break;
}
sub_data = data.substr(start, num);
write(fd, sub_data.data(), sub_data.length());
start = end;
end = end + num;
MKSLOG_BLUE("发送下载数据");
// usleep(45000);
// usleep(25000);
}
// write(fd, data.data(), data.length());
// usleep(5000);
/*
std::string data_1 = data.substr(0, 512);
std::string data_2 = data.substr(512, 1024);
std::string data_3 = data.substr(1024, 1536);
std::string data_4 = data.substr(1536, 2048);
std::string data_5 = data.substr(2048, 2560);
std::string data_6 = data.substr(2560, 3072);
std::string data_7 = data.substr(3072, 3584);
std::string data_8 = data.substr(3584, 4096);
*/
// write(fd, data.data(), data.length());
// usleep(500);
// write(fd, data_1.data(), data.length());
// usleep(50000);
// write(fd, data_2.data(), data.length());
// usleep(50000);
// write(fd, data_3.data(), data.length());
// usleep(50000);
// write(fd, data_4.data(), data.length());
// usleep(50000);
// write(fd, data_5.data(), data.length());
// usleep(50000);
// write(fd, data_6.data(), data.length());
// usleep(50000);
// write(fd, data_7.data(), data.length());
// usleep(50000);
// write(fd, data_8.data(), data.length());
// usleep(50000);
}
void send_cmd_vid_en(int fd, std::string obj, int value) {
std::string cmd = obj + ".en=" + std::to_string(value) + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_bauds(int fd, int bauds) {
std::string cmd = "bauds=" + std::to_string(bauds) + "\xff\xff\xff";
// MKSLOG_YELLOW("%s", cmd.data());
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_cmd_baud(int fd, int baud) {
std::string cmd = "baud=" + std::to_string(baud) + "\xff\xff\xff";
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}
void send_var_value(int fd, std::string var, int value) {
std::string cmd = var + "=" + std::to_string(value) + "\xff\xff\xff";
tcdrain(fd);
write(fd, cmd.data(), cmd.length());
}

2543
src/ui.cpp Normal file

File diff suppressed because it is too large Load Diff