meoser
Version:
meos protocol engine
287 lines (263 loc) • 9.24 kB
JavaScript
import {
calcFileCheckSum,
calcFrameCheckSum,
stringToAsciiCode,
longToBytes,
float32ToBytes,
convertLen2Byte
} from './util';
import {
MEOS_FRAME_HEAD,
MEOS_FRAME_END,
POTOCOL_ID,
FILE_CMD_ID,
HANDSHAKE_DTR,
READY_CMD,
CHANNEL_INDEX,
WORKING_MODE,
WORKING_MODE_CMD,
CORRECTION_MODE,
DO_CORRECT
} from './setting';
/**
* 负责发送协议的编码
*/
// FILE_TYPE = 0x01; // 0x00表示.txt,0x01表示.py
const FRAME_NECK = [0x00, 0x5e];
class Encodebytes {
constructor() {
}
/**
* 协议组装器:文件头
*/
fileHeaderBytes(path, contentBytes) {
//cmd_id
let cmdId = FILE_CMD_ID.HEAD;
//file_type
let fileType = 0x00; // 0x01表示.txt,0x00表示.py;
//file_size
let fileSizeBytes = longToBytes(contentBytes.length).reverse();
//file_check_sum
let fileCheckSumBytes = calcFileCheckSum(contentBytes);
//file_name
let fileNameBytes = stringToAsciiCode(path);
//cmd_data
let cmdData = [fileType, ...fileSizeBytes, ...fileCheckSumBytes, ...fileNameBytes];
//cmd_length
let cmdLength = convertLen2Byte(cmdData.length);
// frame data content
let frameDataContent = [POTOCOL_ID.FILE, ...FRAME_NECK, cmdId, cmdLength[0], cmdLength[1], ...cmdData];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:文件体
* @param {Number} startIndex 切片首位的在整个文件体中的索引位
* @param {Array} sliceData 文件内容切片
* @return {Array} 文件内容切片转成协议
*/
fileBodyBytes(startIndex, sliceData) {
//cmd_id
let cmdId = FILE_CMD_ID.BODY;
//offset_byte
let offsetBytes = longToBytes(startIndex).reverse();
//cmd_len
let cmdLen = offsetBytes.length + sliceData.length;
//cmd_length
let cmdLength = convertLen2Byte(cmdLen);
// frame data content
let frameDataContent = [POTOCOL_ID.FILE, ...FRAME_NECK, cmdId, cmdLength[0], cmdLength[1], ...offsetBytes, ...sliceData];
return this.wrapperDataContent(frameDataContent);
}
wrapperDataContent(frameDataContent){
let frameLength = convertLen2Byte(frameDataContent.length);
// check head sum
let checkHeadSum = calcFrameCheckSum([MEOS_FRAME_HEAD, frameLength[0], frameLength[1]]);
// check_sum
let checkSum = calcFrameCheckSum(frameDataContent);
return [MEOS_FRAME_HEAD, checkHeadSum, frameLength[0], frameLength[1], ...frameDataContent, checkSum, MEOS_FRAME_END];
}
/**
* 将协议片段组装
* @param {String} path [description]
* @param {Array} contentBytes [description]
* @param {Number} limitLength [description]
* @return {[type]} [description]
*/
composer(path, contentBytes, limitLength = 100) {
let protocol = [];
let contentLength = contentBytes.length;
//文件头
let fileHeaderBytes = this.fileHeaderBytes(path, contentBytes);
protocol.push(fileHeaderBytes);
//对文件体进行切片
let blockCount = Math.ceil(contentLength / limitLength);
for (let i = 0; i < blockCount; i++) {
let sliceData = [];
let startIndex = i * limitLength;
let endIndex = (i + 1) * limitLength;
//不足规定长度
if (contentLength - startIndex < limitLength) {
sliceData = contentBytes.slice(startIndex, contentLength);
} else {
sliceData = contentBytes.slice(startIndex, endIndex);
}
let fileBodyBytes = this.fileBodyBytes(startIndex, sliceData);
protocol.push(fileBodyBytes);
}
return protocol;
}
/**
* 协议组装器:删除文件
* @param {String} path 文件路径(含文件名)
*/
deleteFileBytes(path) {
//file_id
let cmdId = FILE_CMD_ID.DELETE;
//file_name
let fileNameBytes = stringToAsciiCode(path);
//cmd_length
let cmdLength = convertLen2Byte(fileNameBytes.length);
// frame data content
let frameDataContent = [POTOCOL_ID.FILE, ...FRAME_NECK, cmdId, cmdLength[0], cmdLength[1]];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:通信变量
* @param {String} name 变量名
* @param {Boolean|Number|String} value 变量值
* @return {[type]} [description]
*/
commVarBytes(name, value) {
const teminal = 0x00; // name 终止符
let type, valueBytes;
// 数据类型判断
switch (typeof value) {
case 'number':
if(value.toString().includes('.')) {
// float 4byte
type = 0x09;
valueBytes = float32ToBytes(value);
}else {
// int 4byte
type = 0x05;
valueBytes = longToBytes(value).reverse();
}
break;
case 'boolean':
type = 0x0b;
// boolean 1byte
valueBytes = [value ? 1 : 0];
break;
case 'string':
type = 0x0c;
valueBytes = stringToAsciiCode(value);
break;
default:
//char 1byte
type = 0x01;
valueBytes = stringToAsciiCode('');
}
let nameBytes = stringToAsciiCode(name);
let frameDataContent = [POTOCOL_ID.COMM_VAR, ...nameBytes, teminal, type, ...valueBytes];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:读取传感器值
* @param {Number} actionID
* @param {Number} sensorID 传感器_属性构成的 id
*/
sensorBytes(actionID, sensorID) {
let frameDataContent = [POTOCOL_ID.SENSOR, actionID, ...convertLen2Byte(sensorID)];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:发送广播
* @param {String} msg 广播内容
* @return {[type]} [description]
*/
broadcastBytes(msg) {
const teminal = 0x00; // 结束符
// 广播:大写全部转成小写
msg = msg.toString().toLowerCase();
let msgBytes = stringToAsciiCode(msg);
let frameDataContent = [POTOCOL_ID.BROADCAST, ...msgBytes, teminal];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:获取 meos mac 地址
* @param {Number} type 0x01: wifi, 0x02: ble
* @return {[type]} [description]
*/
macAddrBytes(type) {
let frameDataContent = [POTOCOL_ID.MAC_ADDR, type];
return this.wrapperDataContent(frameDataContent);
}
/**
* 协议组装器:查询 meos 固件版本
* @return {[type]} [description]
*/
mEosVersionBytes() {
let protoID = POTOCOL_ID.VERSION;
return this.wrapperDataContent([protoID]);
}
/**
* [DTRBytes description]
*/
DTRBytes() {
let protoID = POTOCOL_ID.HANDSHAKE_DTR;
let step = HANDSHAKE_DTR.REQUEST_DTR;
return this.wrapperDataContent([protoID, step]);
}
readyStatusBytes() {
let protoID = POTOCOL_ID.READY;
let CMD = READY_CMD.REQUEST;
return this.wrapperDataContent([protoID, CMD]);
}
/**
* 获取通信信道协议
*/
commChannelBytes() {
let protoID = POTOCOL_ID.COMM_CHANNEL;
let MODE = 0x01; // 读模式
let CMD_ID = 0xF0;
return this.wrapperDataContent([protoID, CHANNEL_INDEX, MODE, CMD_ID]);
}
/**
* 设置/获取工作模式协议:离线模式、在线模式
*/
workingModeBytes(mode) { // WORKING_ONLINE, WORKING_OFFLINE
let commandID;
let protoID = POTOCOL_ID.WORKING_MODE;
if(typeof mode === 'undefined') {// offline
commandID = WORKING_MODE_CMD.GET;
return this.wrapperDataContent([protoID, commandID]);
}
// online
commandID = WORKING_MODE_CMD.SET;
return this.wrapperDataContent([protoID, commandID, mode]);
}
/**
* 获取校正模式协议
* @param {Number} mode 模式,1: enter, 2: quit
*/
correctionModeBytes(mode) {
let protoID = POTOCOL_ID.SENSOR_CORRECTION;
let subID = CORRECTION_MODE.SUB_ID;
let mode_ = CORRECTION_MODE.MODE.ENTER;
if (mode !== mode_) {
mode_ = CORRECTION_MODE.MODE.QUIT;
}
return this.wrapperDataContent([protoID, subID, mode_]);
}
/**
* 开始校正
* @param {[type]} sensorId [description]
* @return {[type]} [description]
*/
doCorrectBytes(sensorId) {
let protoID = POTOCOL_ID.SENSOR_CORRECTION;
let subID = DO_CORRECT.SUB_ID;
return this.wrapperDataContent([protoID, subID, sensorId]);
}
}
export default new Encodebytes();