meoser
Version:
meos protocol engine
181 lines (166 loc) • 6.43 kB
JavaScript
// 传感器表依据是神经元引擎
// key: 传感器名, value: 传感器id
const CODEY_ROCKY_SENSOR_MAP = {
"CODEY_BUTTON_PRESSED": 0x01,
"CODEY_LIGHT": 0x02,
"CODEY_SOUND_INTENSITY": 0x03,
"CODEY_POTENTIOMETER": 0x04,
"CODEY_GYRO": 0x05,
"CODEY_LED_PIXEL_STATUS": 0x06,
"CODEY_VOLUME": 0x07, // codey 声音传感器
"CODEY_IS_SHAKING": 0x08,
"CODEY_FORWARD_TILT": 0x09, // 前倾
"CODEY_BACKWARD_TILT": 0x0A, // 后倾
"CODEY_LEFT_LEANING": 0x0B,
"CODEY_RIGHT_LEANING": 0x0C,
"CODEY_BATTERY": 0x0D,
"CODEY_TIMER": 0x0E,
// rocky
"ROCKY_RGB": 0x01, // 获取 rgb 色值
"ROCKY_COLOUR": 0x02,
"ROCKY_ENVIROMENT_LIGHT": 0x03, // 环境光
"ROCKY_GREYSCALE": 0x04,
"ROCKY_LIGHT_REFLECTION": 0x05,
"ROCKY_IR_REFLECTION": 0x06,
"ROCKY_IS_GREYSCALE_IN_RANGE": 0x07,
"ROCKY_IS_OBSTRUCTED": 0x08
}
const CODEY_ROCKY_SENSOR_COMMANDS = {};
// 神经元协议下,传感器名转化成传感器指令,需插入一个 'GET' 标志
Object.keys(CODEY_ROCKY_SENSOR_MAP).forEach( v =>
CODEY_ROCKY_SENSOR_COMMANDS[v] = v.replace('_', '_GET_')
);
class NeuronsAdapter {
/**
* Create a neuronsAdapter.
*/
constructor() {
this.engine = this.createEngine();
this.reportList = {};
this.blocksMap = {};
}
createEngine() {
let neuronsEngine_ = null;
try{
neuronsEngine_ = new window.createNeuronsLogicEngine();
neuronsEngine_.on('blockStatusChanges', this.onBlockStatusChanges_.bind(this));
}catch(e){
// 神经元引擎js打包方式使得只能用script标签引入该引擎
console.warn('Online engine is unavailable, please check the source of "neurons_logic_engine.js"');
}
window.neuronsEngine = neuronsEngine_;
return neuronsEngine_;
}
/**
* [onBlockStatusChanges_ description]
* @param {String} deviceName eg: 'CODEY', 'ROCKEY'
* @param {Number} index 索引
* @param {Object.Array} values {light: [11.23]}
*/
onBlockStatusChanges_(deviceName, index, values) {
for(let name in values) {
// 神经元提供的接口规范,导致blockStatusChanges事件接收到的block名和发送的 command 不一致
// 对于这个差异,已和神经元约定,只有codey,rocky这两个模块,神经元统一通过 'get_' 前缀来定义读值命令
// 因此,此处通过补齐 'get_' 来正确获取command的返回消息
let blockName = deviceName.toLowerCase() + '_' + name;
let fn = this.blocksMap[blockName];
if(typeof fn === 'function') {
fn(name, values[name]);
}
}
}
/**
* 发送上报指令
* @param {[type]} sensorCommandStr [description]
* @param {[type]} reportMode [description]
* @param {Number} interval 上报周期
* @return {[type]} [description]
*/
sendReportCommand(sensorCommandStr, isReport, interval=100) {
/**
* 不应该考虑上层业务需要,只应实现自身接口功能:
* 设置上报则记录它,设置不上报则删除它。而不应该根据记录去阻止它是否被重复设置,也就是不设置障碍。
*/
let reportMode = isReport? 0x01: 0x00;
let result = this.parseSensorName_(sensorCommandStr);
// 无需节流
let isSend = this.engine.sendBlockCommand(result.deviceName, 'SET_REPORT_MODE', [result.sensorId, reportMode, interval]);
if(isSend !== null) {
this.handleRecordReport(sensorCommandStr, isReport);
}
}
/**
* [handleRecordReport description]
* @param {[type]} sensorCommandStr [description]
* @param {Boolean} isReport [description]
* @return {[type]} [description]
*/
handleRecordReport(sensorCommandStr, isReport) {
if(isReport) {
this.reportList[sensorCommandStr] = true;
}else {
delete this.reportList[sensorCommandStr];
}
}
isReported(sensorCommandStr) {
return !!this.reportList[sensorCommandStr];
}
/**
* [bindBlockChangeHandler description]
* @param {[type]} sensorCommandStr [description]
* @param {[type]} handler [description]
* @param {Boolean} isBind [description]
* @return {[type]} [description]
*/
bindBlockChangeHandler(sensorCommandStr, handler) {
let {deviceName, sensorName} = this.parseSensorName_(sensorCommandStr);
this.blocksMap[deviceName.toLowerCase() + '_' + sensorName.toLowerCase()] = handler;
}
unBindBlockChangeHandler(sensorCommandStr) {
let {deviceName, sensorName} = this.parseSensorName_(sensorCommandStr);
delete this.blocksMap[deviceName.toLowerCase() + '_' + sensorName.toLowerCase()];
}
getEngine() {
return this.engine;
}
/**
* 解析传感器名
* @param {String} name 传感器命令字符串,格式为:'CODEY_GET_LIGHT', 'ROCKY_GET_LIGHT'
* @return {Object|Undefined}
*/
parseSensorName_(sensorCommandStr) {
if(typeof sensorCommandStr === 'string') {
let msg = sensorCommandStr.replace(/_/, '-').replace(/_/, '-').split('-');
// CODEY, ROCKY
let deviceName = msg[0];
// GET, SET
let command = msg[1];
let sensorName = msg[2];
let sensorId = CODEY_ROCKY_SENSOR_MAP[deviceName + '_' + sensorName];
if(deviceName && typeof sensorId !== 'undefined') {
return {
deviceName,
sensorName,
command,
sensorId
}
}
}
}
/**
* [getReportValue description]
* @param {[type]} deviceName [description]
* @param {[type]} sensorName [description]
* @return {[type]} [description]
*/
getReportValue(deviceName, sensorName) {
return this.engine.getBlockSubStatus(deviceName, sensorName);
}
get SENSORLIST() {
return Object.keys(CODEY_ROCKY_SENSOR_MAP);
}
get SENSOR_COMMANDS() {
return CODEY_ROCKY_SENSOR_COMMANDS;
}
}
export default new NeuronsAdapter();