0.0.18 • Published 6 months ago
casdonsdk v0.0.18
面板SDK
注意⚠️ 1. 安装依赖 (1)登录私仓,设置镜像源,拉镜像
npm config set registry https://nexus.casdon.com.cn:30443/repository/npm-public/
(2)登录 (账号:casdon_nexus 密码:Casdon@240723)
npm login
- 发包
npm config set registry https://nexus.casdon.com.cn:30443/repository/npm-casdon/
1.类型声明文件
生成ciotindex.d.ts
参考代码如下,还需根据实际接口请求修改逻辑(PS:如果是需要单独下发dp,那还需要单独下发的函数)
- 已修改一版本,如文件addNew.ts
- node addNew.ts 生成测试文件testindex.d.ts
const fs = require("fs");
const prettier = require("prettier");
// DP定义和command-msg的JSON数据
const dpJson = {
switchMode: {
name: "开关",
id: 0,
type: 1,
limit: 6,
filter: 6,
list: ["off", "on"],
dict: { off: "关机", on: "开机" },
comment: "设备开关状态",
},
working_mode: {
name: "工作模式",
id: 1,
type: 4,
limit: 4,
filter: 0,
list: ["idle", "microwave", "steam", "bake", "clean"],
dict: { idle: "待机", microwave: "微波", steam: "蒸", bake: "烤" },
comment: "设备的工作模式,未工作时工作模式属于待机(idle)",
},
working_duration: {
name: "工作时长",
id: 2,
type: 2,
limit: 6,
filter: 0,
comment: "工作时长单位 秒",
},
temperature_top: {
name: "温度-上",
id: 3,
type: 2,
limit: 6,
filter: 0,
comment: "上腔体温度 0-250 单位摄氏度",
},
temperature_bottom: {
name: "温度-下",
id: 4,
type: 2,
limit: 6,
filter: 0,
comment: "下腔体温度 0-250 单位摄氏度",
},
assit_microwave_level: {
name: "微波辅助",
id: 5,
type: 4,
limit: 6,
filter: 0,
list: ["off", "low", "mid", "high"],
dict: { off: "关闭", low: "低", mid: "中", high: "高" },
comment: "使用微波辅助烹饪",
},
assit_steam_level: {
name: "蒸汽辅助",
id: 6,
type: 4,
limit: 6,
filter: 0,
list: ["off", "low", "mid", "high", "max"],
dict: { off: "关闭", low: "低", mid: "中", high: "高", max: "最大" },
comment: "使用蒸汽辅助烹饪",
},
assit_fan_level: {
name: "风扇辅助",
id: 7,
type: 4,
limit: 6,
filter: 0,
list: ["off", "low", "mid", "high", "max"],
dict: { off: "关闭", low: "低", mid: "中", high: "高", max: "最大" },
comment: "使用风扇辅助烹饪",
},
error_code: {
name: "故障代码",
id: 8,
type: 4,
limit: 4,
filter: 0,
list: ["e01", "e02", "e03", "e04"],
dict: {
e01: "缺水",
e02: "腔体温度过高",
e03: "温度传感器短路",
e04: "温度传感器开路",
},
comment: "设备的故障",
},
};
const commandJson = {
power_set: { args: ["switchMode"], title: "设定开关机" },
power_on: { title: "开机" },
power_off: { title: "关机" },
cook_start: { title: "开始烹饪" },
cook_pause: { title: "暂停烹饪" },
cook_stop: { title: "停止烹饪" },
set_cook_mode: { args: ["working_mode"], title: "设定烹饪模式" },
set_steam_param: {
args: [
"temperature_top",
"temperature_bottom",
"working_duration",
"assit_microwave_level",
"assit_fan_level",
],
title: "设定蒸功能参数",
},
set_bake_param: {
args: [
"temperature_top",
"temperature_bottom",
"working_duration",
"assit_microwave_level",
"assit_steam_level",
],
title: "设定烤功能参数",
},
};
//前缀常量,用于命名空间。
const namespace = "Ciot";
// DP类型映射表。
const dpTypeMapping = {
1: "Bool",
2: "Int",
3: "Float",
5: "Bits",
6: "String",
7: "Raw",
};
// 类型到定义的映射表
const typeToDefinitions = {
Bool: "boolean",
Int: "number",
Float: "number",
Bits: "Uint8Array",
String: "string",
Raw: "Uint8Array",
// dp_type_enum: "enum",
};
//获取所有命令的参数集合。
function getCommandAllArgs(dpJson, commandJson) {
return Array.from(
new Set(Object.values(commandJson).flatMap((cmd) => cmd.args || []))
);
}
//根据DP信息生成TS类型定义。
function getDpTsType(key, dp) {
const type = dp.type + "";
let output = "";
// 当前仅枚举需要定义,其他直接取baseType
if (type == 4) {
if (dp && dp.list) {
output += `/**\n * 枚举-${dp.name} 描述: ${dp.comment}\n */\n`;
output += `export enum ${namedEnumType(underscoreToPascalCase(key))} {\n`;
dp.list.forEach((item, index) => {
// 生成枚举成员及其注释
output += ` /**\n * ${dp.dict[item]} - ${item}\n */\n`;
output += ` ${underscoreToPascalCase(item)} = ${index},\n`;
});
output += `}`;
}
}
return output;
}
// 生成DP类型的定义。
function generateDpDefinitions(dpJson, commandJson) {
// 获取指令的dp参数列表
const dpItems = getCommandAllArgs(dpJson, commandJson);
// 遍历dp定义,生成类型指令
const tsTypeItems = Array.from(new Set(dpItems))
.map((dp) => {
if (dpJson[dp]) {
return getDpTsType(dp, dpJson[dp]);
} else {
console.warn(`Unsupported type for ${dp}`);
return null;
}
})
.filter((item) => item);
return tsTypeItems.join("\n");
}
// 首字母大写
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function underscoreToPascalCase(str) {
return str
.split("_")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join("");
}
//生成命名的基础类型。
function namedBaseType(key) {
return `${capitalizeFirstLetter(key)}`;
}
//生成命名的枚举类型。
function namedEnumType(key) {
return `${capitalizeFirstLetter(key)}`;
}
//生成命名的指令回调
function namedCommandCallbackType(key) {
return `ActCallback${capitalizeFirstLetter(underscoreToPascalCase(key))}`;
}
//输出基础类型定义。
function outputBaseType() {
return Object.entries(typeToDefinitions)
.map(([key, type]) => {
return `export type ${namedBaseType(key)} = ${type};`;
})
.join("\n");
}
//生成动作枚举定义
function generateActionsEnumDefinitions(commandJson) {
let output = "";
const commands = Object.keys(commandJson);
if (commands.length > 0) {
output += `\n export enum Action {\n`;
commands.forEach((command) => {
const item = commandJson[command];
output += `/**\n * ${item.title}\n */\n`;
output += `${underscoreToPascalCase(command)} = "${command}",\n`;
});
output += "}\n";
}
return output;
}
//生成命令接口定义。
function generateCommands(dpJson, commandJson) {
let output = "";
const commands = Object.keys(commandJson);
const getArgTypeName = (key) => {
const dp = dpJson[key];
if (dp.type == 4) {
return namedEnumType(underscoreToPascalCase(key));
} else {
return namedBaseType(dpTypeMapping[dp.type]);
}
};
if (commands.length > 0) {
commands.forEach((command) => {
const cmd = commandJson[command];
output += `/**\n * 回调方法 ${cmd.title}\n */\n`;
output += `export interface ${namedCommandCallbackType(command)} {\n`;
if (cmd.args) {
const argsType = cmd.args.map((arg) => {
return `${arg}: ${getArgTypeName(arg)}`;
});
output += `(${argsType.join(",")}):void \n`;
} else {
output += `():void \n`;
}
output += `}\n`;
});
}
return output;
}
// 生成TypeScript类型声明文件
function generateTypeScriptDefinitions(dpJson, commandJson) {
let output = "";
output += `export namespace ${namespace} {`;
// 基本类型定义
output += outputBaseType();
// 参数定义
output += generateDpDefinitions(dpJson, commandJson);
output += generateActionsEnumDefinitions(commandJson);
// Command 类型定义
output += generateCommands(dpJson, commandJson);
output += `}`;
return output;
}
async function generateAndFormatDefinitions() {
const tsDefinitions = generateTypeScriptDefinitions(dpJson, commandJson);
const formattedTsDefinitions = await prettier.format(tsDefinitions, {
parser: "typescript",
semi: true,
singleQuote: true,
printWidth: 100,
tabWidth: 2,
trailingComma: "all",
});
fs.writeFileSync(`${namespace}index.d.ts`, formattedTsDefinitions);
}
generateAndFormatDefinitions();
使用ciotindex.d.ts文件
- 在tsconfig.json文件中定义
tsconfig.json的include数组中添加ciotindex.d.ts文件的路径。由于文件位于根目录,可以直接使用文件名。
{
"compilerOptions": {
// ... 你的其他编译选项
},
// 确保包含根目录下的 ciotindex.d.ts 文件
"include": ["src/**/*", "ciotindex.d.ts"]
}
编写CiotPanelSDK
data
mqttClient
所有dp项以及类型
init初始化
监听
使用
- 新建文件ciotindex.d.ts
- 新建文件ciot.ts
- 引入并使用类型文件:import {Ciot} from '../ciotindex.d.ts'
- 面板初始化
- mqtt连接(mqtt,clientId,deviceId)
- mqtt上报=>根据指令上报,掉指令的方法 传值=》方法里面整理下发到mqttPublic
- mqtt上报=》单独DP上报,ciotindex.d.ts要增加设置每个dp的方法,比如setPower(true)=> 整理下发值到mqtt
- mqtt监听=》根据mqtt