6月 09, 2022

ECHONET liteを用いたエアコンの情報取得

node-echonet-liteを用いて対応機器から情報を取得する
公開されているサンプルを参考に、Node.jsで実装

ライブラリのインストール

$ npm install serialport
$ npm install node-echonet-lite

初期化関係

// reference : https://github.com/futomi/node-echonet-lite

// Load the node-echonet-lite module
var EchonetLite = require('node-echonet-lite');
// Create an EchonetLite object
//   The type of network layer must be passed.
var el = new EchonetLite({ 'type': 'lan' });
el.setLang('ja');

// Initialize the EchonetLite object
el.init((err) => {
	if (err) { // An error was occurred
		showErrorExit(err);
	} else { // Start to discover devices
		discoverDevices();
		setTimeout(timeOutExit, 15000);
	}
});

対応機器の特定

startDiscovery()で応答した機器のEOJを確認する
// Start to discover devices
function discoverDevices() {
	// Start to discover Echonet Lite devices
	el.startDiscovery((err, res) => {
		// Error handling
		if (err) {
			showErrorExit(err);
		}
		// Determine the type of the found device
		var device = res['device'];
		var address = device['address'];
		var eoj = device['eoj'][0];
		//console.log(eoj);
		var group_code = eoj[0]; // Class group code
		var class_code = eoj[1]; // Class code
		if (group_code === 0x01 && class_code === 0x30) {
			//el.stopDiscovery();
			getOperationStatus_AirCon(address, eoj);
		}else{
			el.getPropertyMaps(address, eoj, (err, res) => {
				console.log(address + " : " + el.getClassGroupName(group_code) + " / " + el.getClassName(group_code, class_code));
				console.log('- IP address: ' + address);
				console.log('- EOJ: ' + JSON.stringify(eoj));
				console.log('- Property Maps:')
				console.dir(res['message']['data']);
			});
		}
	});
}

情報取得

el.send()を用いて、prop内で指定したEPCに対応するデータの送信を機器に要求する。
受信したresをAPPENDIX ECHONET機器オブジェクト詳細規定に従って読み解く
// Get the operation status
function getOperationStatus_AirCon(address, eoj) {
	var esv = 'Get';
	var prop = [
		{ 'epc': 0x80, 'edt': null }, // ON/OFF
		{ 'epc': 0xB0, 'edt': null }, // Mode
		{ 'epc': 0xB3, 'edt': null }, // Set Temperature
		{ 'epc': 0xBA, 'edt': null }, // Room Humidity
		{ 'epc': 0xBB, 'edt': null }, // Room Temperature
		{ 'epc': 0xBE, 'edt': null }  // outdoor Temperature
	];
	el.send(address, eoj, esv, prop, (err, res) => {
		console.log('[Air conditioner] @' + address);
		console.log('  Err : ' + err);
		console.log('  ESV : ' + res['message']['esv']);
		var vStatus = "";
		var vMode = "";
		var vModeNum = "";
		var vSetTemp = "";
		var vMeasureHumi = "";
		var vMeasureTemp = "";
		var vMeasureOutdoorTemp = "";
		for (let element of res['message']['prop']){
			//console.dir(element);
			var epc = element['epc'];
			var edt = element['edt'];
			if (epc === 0x80) {
				vStatus = (edt['status'] ? 'on' : 'off');
				console.log('  Power : ' + vStatus);
				//saveToFile(dataDIR+"/aircon@"+address+"_Power",desc);
			} else if (epc === 0xB0) {
				vModeNum = edt['mode'];
				vMode = edt['desc'];
				console.log('  Mode : ' + vMode + '(' + vModeNum + ')');
				//saveToFile(dataDIR+"/aircon@"+address+"_Mode",desc);
				//saveToFile(dataDIR+"/aircon@"+address+"_ModeNum",num);
			} else if (epc === 0xB3) {
				vSetTemp = edt['temperature'];
				if(vSetTemp === null ){vSetTemp = 253}
				console.log('  Set temp : ' + vSetTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_setTemp",desc);
			} else if (epc === 0xBA) {
				vMeasureHumi = edt['humidity'];
				//if(vMeasureHumi === 253 ){vMeasureHumi = " "}
				console.log('  Measure Humi : ' + vMeasureHumi + "[%]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureHumi",desc);
			} else if (epc === 0xBB) {
				vMeasureTemp = edt['temperature'];
				console.log('  Measure temp : ' + vMeasureTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureTemp",desc);
			} else if (epc === 0xBE) {
				vMeasureOutdoorTemp = edt['temperature'];
				if(vMeasureOutdoorTemp === 126 ){vMeasureOutdoorTemp = 253}
				console.log('  Measure Outdoor temp : ' + vMeasureOutdoorTemp + "[℃]");
				//saveToFile(dataDIR+"/aircon@"+address+"_measureOutdoorTemp",desc);
			} else{
				console.dir(element)
			}
		}
		
		//el.close();
	});
}

エラー&終了処理定

// Print an error then terminate the process of this script
function showErrorExit(err) {
	console.log('[ERROR] ' + err.toString());
	el.close();
	process.exit();
}
function timeOutExit() {
	console.log('[TimeOut]');
	el.close();
	process.exit();
}

実行結果

[Air conditioner] @192.168.***.***
  Err : null
  ESV : Get_Res
  Power : on
  Mode : 送風(5)
  Set temp : 253[℃]
  Measure Humi : 70[%]
  Measure temp : 24[℃]
  Measure Outdoor temp : 19[℃]

0 comments:

コメントを投稿