2.8.0 • Published 8 months ago

e-smartmeter-echonet-lite v2.8.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

Overview, e-smartmeter-echonet-lite

このドキュメントは日英併記です.

This document is Japanese and English written together.

このモジュールは日本向け電力スマートメーターとのECHONET Liteプロトコル通信をサポートします. ECHONET Liteプロトコルはスマートハウス機器の通信プロトコルで,正確には低圧スマート電力量メーターをサポートします. 通信モジュールとしてWi-SUNモジュール(TESSERA RL7023またはROHM BP35C2)が必須です.

This module provides ECHONET Lite protocol for Low-voltage smart electric energy meter in Japan. The ECHONET Lite protocol is a communication protocol for smart home devices. This module requires USB Wi-SUN module (TESSERA RL7023 or ROHM BP35C2) for communication.

Menu

TOC

Install

下記コマンドでモジュールをインストールできます.

You can install the module as following command.

npm i e-smartmeter-echonet-lite

Demos

デモプログラムはこんな感じです。 動作させるためには電力会社のBルートサービスの利用申し込みが必要です。 電力会社に申請をすると,Bルート認証ID設定Bルート認証パスワード設定をもらえます.

Here is a demonstration script. Your ID and password for B route service is required.

//////////////////////////////////////////////////////////////////////
//	Copyright (C) Hiroshi SUGIMURA 2021.09.13 - above.
//////////////////////////////////////////////////////////////////////
'use strict'

//////////////////////////////////////////////////////////////////////
let eSM = require('e-smartmeter-echonet-lite');
const cron = require('node-cron');


////////////////////////////////////////////////////////////////////////////
// config
let config = {
  dongleType: 'ROHM',  // 'ROHM' or 'TESSERA', default:TESSERA
  id:'01234567890QWERTYUIOPASDFGHJKLZX',   // Bルート認証ID設定, Your B route ID.
  password:'123456789ABC',   // Bルート認証パスワード設定, Your B route password.
  EPANDESC : {},
  debug: true,
}


// 接続管理フラグ
let connected = false;


cron.schedule('*/30 * * * * *', () => {
	// 既に接続していたら機器情報の変化をみる。接続していなかったら接続する
	// 30秒に1回、ポートの状況を監視して、ついでに定期的にメーターからgetする
	if( connected ) {
		eSM.getMeasuredValues();		// 機器情報の変化の監視
		console.log( '## == facilities', (new Date()).toLocaleString(), '== ##' );
		console.dir( eSM.facilities );

	}else{
		// 初期化
		eSM.initialize( config, ( sm, rinfo, els, err) => {
			console.log( '## user function', (new Date()).toLocaleString(), '##' );

			if( err ) {
				console.error( err );
				return;
			}

			console.log( 'eSM:', sm);

			// 切断された
			if( sm.state == 'close' ) {
				connected = false;
				return;
			}

			// console.log( JSON.stringify(sm) );
			// rinfo ? console.dir( rinfo ):0;
			els ? console.dir( els ):0;

			try{
				// 初回接続時
				if( !connected && sm.state == 'available' ) {
					connected = true;
					console.log('## start observation.');
					eSM.getStatic();
				}
			}catch(e){
				console.error(e);
			}
		});
	}

});

process.on('SIGINT', () => {
	console.log('Ctrl + cのときは明示的にreleaseしないと、Windows/Node.jsがserialportを握ることがある');
	eSM.release();
	process.exit(0);
});

Data stracture

コンフィグ (config)

{
  dongleType: String,  // 'ROHM' or 'TESSERA', default:TESSERA
  id: String,   // Bルート認証ID設定, Your B route ID. **Required**.
  password:String,   // Bルート認証パスワード設定, Your B route password. **Required**.
  observationEPCs: array, element is string,  // Optional.
  debug: Boolean,  // debug mode , Optional. default false.
  EPANDESC: Strunct {  // Connection info for smart meter, Optional. (for resume connection)
  	path: String,
	channel: String,
	channelPage: String,
	panID: String,
	address: String,
	lqi: String,
	pairID: String'
  }
}

スマートメーターとの通信状態 (sm)

sm (smart meter)はスマートメーターとの通信シーケンスの状態や受信データそのものを格納します.

sm (smart meter object) stores state of the connection sequence and received messages.

{
	"state":"available",
	"data":{
		"count":1,
		"msgs": [
			[
				"ERXUDP",
				"FE80:0000:0000:0000:021C:6400:03EF:EDFD",
				"FE80:0000:0000:0000:1207:23FF:FEA0:7831",
				"0E1A",
				"0E1A",
				"001C640003EFEDFD",
				"1",
				"001A",
				"1081000202880105FF0172018D0C413137583037343137350000"
			]
		]
	}
}

受信データ (rinfo)

rinfoはスマートメーターのIP(IPv6)とポートです.

rinfo is the IPv6 and port of smart meter.

{
  address: 'FE80:0000:0000:0000:021C:6400:03EF:EDFD',
  port: '0E1A'
}

受信データ (els)

elsはスマートメーターとのECHONET Lite通信が行われたときに,下記の構造体の形式で解析したオブジェクトが格納されています.

els stores ECHONET Lite data as following when received ECHONET Lite packet from smart meter.

{
  EHD : str,
  TID : str,
  SEOJ : str,
  DEOJ : str,
  EDATA: str,    // EDATA is followings
  ESV : str,
  OPC : str,
  DETAIL: str,
  DETAILs: { epc: edt }
}

オブジェクト内の機器情報リスト (facilities)

受信データの最新値をfacilitiesに記録しています.

The property named facilities stores last receive data.

EL.facilities =
{
  'FE80:0000:0000:0000:0000:0000:XXXX:XXXX': {
    '028801': {
      '80': '30',
      '81': '61',
      '82': '00004600',
      '88': '42',
      '97': '0929',
      '98': '07e50917',
      '8d': '413137583037343137350000',
      '9f': '19808182888a8d97989d9e9fd3d7e0e1e2e3e4e5e7e8eaebeced',
      eb: '07e50917091e000000003e',
      e0: '0007a78d',
      '9e': '0381e5ed',
      e7: '0000009e',
      d7: '06',
      d3: '00000001',
      '8a': '000016',
      ea: '07e50917091e000007a787',
      ed: 'ffffffffffff01',
      e1: '02',
      ec: 'ffffffffffff01fffffffefffffffe',
      e2: '00fffffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffe',
      e5: 'ff',
      e3: '0000003e',
      '9d': '03808188',
      e4: '00fffffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffefffffffe',
      e8: '00147ffe'
    }
  }
}

API

初期化, 受信, 監視, initialize, receriver callback and observation

npm.io

初期化, initialize

通信を開始します.

start connection.

ESmartMeter.initialize = function( config, callback )
  • config is description of your environment to connect smart meter.
  • callback is the your function. callback is described as following.
function( sm, rinfo, els, err ) {
	console.log('==============================');
	if( err ) {
		console.dir(err);
	}else{
		// ToDo
	}
}

ポートリスト取得, renewPortList

利用可能なポートリストを更新する

renew serial port list

ESmartMeter.renewPortList = function()
ESmartMeter.portList: Array(port)

解放, release

通信を終了します.

release connection.

ESmartMeter.release = function()

変換系, converters

npm.io

fromtofunction
serial,Byte[]EPANDESCgetEPANDESC(str)
serial,Byte[]StringgetIPv6(str)
StringELDATA(EDT)parseDetail(opc,str)
Byte[]ELDATAparseBytes(Byte[])
StringELDATAparseString(str)
StringString (like EL)getSeparatedString_String(str)
ELDATAString (like EL)getSeparatedString_ELDATA(eldata)
ELDATABytes(=Integer[])ELDATA2Array(eldata)
Byte16進表現StringtoHexString(byte)
16進表現StringInteger[]toHexArray(str)
Byte[]StringbytesToString(byte[])
serial, Byte[]ObjectparseReceive(streamData)
String(EDT)StringparseMapForm2(bitstr)

スマートメータのチャンネルスキャンの情報を解析する

ESmartMeter.getEPANDESC = function ( str )

スマートメータのIPv6アドレス取得データを解析する

ESmartMeter.getIPv6 = function ( str )

ECHONET LiteパケットのDetailだけをParse

  • DetailだけをParseする,内部でよく使うけど外部で使うかわかりません.
  • inner function. Parses only detail (for echonet lite data frame).
ESmartMeter.parseDetail = function( opc, str )

byte dataを入力するとELDATA形式にする

  • bytes -> ELDATA type
ESmartMeter.parseBytes = function( bytes )

HEXで表現されたStringをいれるとELDATA形式にする

  • HEX string -> ELDATA
ESmartMeter.parseString = function( str )

文字列をいれるとELらしい切り方のStringを得る

  • String -> EL-like String
ESmartMeter.getSeparatedString_String = function( str )

ELDATAをいれるとELらしい切り方のStringを得る

    • ELDATA -> EL-like String
ESmartMeter.getSeparatedString_ELDATA = function( eldata )

1バイトを文字列の16進表現へ(1Byteは必ず2文字にする)

  • a byte -> HEX string
ESmartMeter.toHexString = function( byte )

バイト配列を文字列にかえる

ESmartMeter.bytesToString = function (bytes)

ELDATA形式から配列へ

ESmartMeter.ELDATA2Array = function (eldata)

プロパティマップの形式2を形式1のようにわかりやすく

  • 16以上のプロパティ数の時,記述形式2
  • 出力はForm1のようにEPCの列挙う, bitstr = EDT
ESmartMeter.parseMapForm2 = function (bitstr)

Serial portからの受信ストリームデータを解析して構造化

ESmartMeter.parseReceive = function(streamData)

ネットワーク内のEL機器全体情報を検索する

現在モジュールが保持している最新情報を取得する

  • ip: Required.
  • obj: Optional.
  • epc: Optional.
ESmartMeter.searchFacilities( ip, obj, epc )

送信, send

ELの通信は送信の成功失敗に関わらず,TIDをreturnすることにしました。 送信TIDはEL.tid[]で管理しています。 sendOPC1はEL.tidを自動的に+1します。

npm.io

シリアル通知,送信のベース

ESmartMeter.write = function ( str )

EL送信のベース

ESmartMeter.sendBaseR = function (ip, buffer)  // for ROHM
ESmartMeter.sendBaseT = function (ip, buffer)  // for TESSERA

EL送信の基本的なAPI,大体これを使ったらよい

ESmartMeter.sendOPC1 = function (ipv6, seoj, deoj, esv, epc, edt)

監視系

npm.io

監視

node-cronを使います。

ESmartMeter.setObserveFacilities = function ( interval, onChanged ) // interval, millisecond

ネットワーク内のEL機器全体情報を更新(内部処理)

受信したら勝手に実行される.

ESmartMeter.renewFacilities = function (ip, els)

受信データの解析

echonet-lite-conv を使うと簡単に解析できます.

npm i echonet-lite-conv

使い方は下記の様にすれば良いです. この例はデモスクリプトの拡張なので,比較してみてください.

//////////////////////////////////////////////////////////////////////
//	Copyright (C) Hiroshi SUGIMURA 2021.09.13 - above.
//////////////////////////////////////////////////////////////////////
'use strict'

//////////////////////////////////////////////////////////////////////
let eSM = require('e-smartmeter-echonet-lite');
const cron = require('node-cron');


////////////////////////////////////////////////////////////////////////////
// config
let config = {
  dongleType: 'ROHM',  // 'ROHM' or 'TESSERA', default:TESSERA
  id:'01234567890QWERTYUIOPASDFGHJKLZX',   // Bルート認証ID設定, Your B route ID.
  password:'123456789ABC',   // Bルート認証パスワード設定, Your B route password.
  EPANDESC : {},
  debug: true,
}


// 接続管理フラグ
let connected = false;


cron.schedule('*/30 * * * * *', () => {
	// 既に接続していたら機器情報の変化をみる。接続していなかったら接続する
	// 30秒に1回、ポートの状況を監視して、ついでに定期的にメーターからgetする
	if( connected ) {
		eSM.getMeasuredValues();		// 機器情報の変化の監視
		console.log( '## == facilities', (new Date()).toLocaleString(), '== ##' );
		console.dir( eSM.facilities );

	}else{
		// 初期化
		eSM.initialize( config, ( sm, rinfo, els, err) => {
			console.log( '## user function', (new Date()).toLocaleString(), '##' );

			if( err ) {
				console.error( err );
				return;
			}

			console.log( 'eSM:', sm);

			// 切断された
			if( sm.state == 'close' ) {
				connected = false;
				return;
			}

			// console.log( JSON.stringify(sm) );
			// rinfo ? console.dir( rinfo ):0;
			els ? console.dir( els ):0;

			try{
				// 初回接続時
				if( !connected && sm.state == 'available' ) {
					connected = true;
					console.log('## start observation.');
					eSM.getStatic();
				}
			}catch(e){
				console.error(e);
			}
		});
	}

});

process.on('SIGINT', () => {
	console.log('Ctrl + cのときは明示的にreleaseしないと、Windows/Node.jsがserialportを握ることがある');
	eSM.release();
	process.exit(0);
});

meta data

Authors

神奈川工科大学 創造工学部 ホームエレクトロニクス開発学科; Dept. of Home Electronics, Faculty of Creative Engineering, Kanagawa Institute of Technology

杉村 博; SUGIMURA, Hiroshi

thanks

  • Thanks to Github users!
  • Thanks to Qiita users!

License

MIT License

-- License summary --
o Commercial use
o Modification
o Distribution
o Private use
x Liability
x Warranty

Log

  • 2.8.0 安定性向上
  • 2.7.4 port resume やめ。isOpen対応、ECHONET Lite AIFだとOPC6までしか保障されないので、それに合わせた。
  • 2.7.3 port resume
  • 2.7.2 debugもうちょい対応a
  • 2.7.1 callback指定がおかしいときのrelease対応a
  • 2.7.0 serial portのデバッグちょっと追加
  • 2.6.9 serial通信上で問題がでたときにonReceive内部でExceptionされるとプログラムが死ぬのを回避
  • 2.6.8 EA,EBも聞く
  • 2.6.7 errorハンドリングミスの修正
  • 2.6.6 なおした
  • 2.6.5 もう少し丁寧に
  • 2.6.4 EPANDESCがとれてLQIが取れないときのバグとり
  • 2.6.3 無駄なログが残っていたので削除
  • 2.6.2 いらないAPIの削除、リトライで戻ってこないときがあるのを修正、リトライ最大回数が達した場合のエラーでエラー扱いされない場合を修正、リトライエラー終了でリソースが解放されていなかったのを修正、getMeasuredValues追加、debug時にscan後でLQIの評価を出してみる。
  • 2.6.1 getStaticのプロパティが多すぎたので減らした
  • 2.6.0 ドングル挿抜対応、connectingのログを軽く、portのpath自動化、node-serialport ver10以上対応、ドングルぬいた時のコネクションcloseがユーザのコールバックからわかるように、channel scanがたまに失敗するのでリトライ追加、getStatic関数バグ修正、getStaticでプロファイルオブジェクトとメータオブジェクトの両方をとるように
  • 2.5.0 チャンネルスキャン中に邪魔しないように
  • 2.1.4 まだログ残ってた
  • 2.1.3 リトライ調整
  • 2.1.2 ログ消すの忘れた
  • 2.1.1 初期化のバグを修正
  • 2.1.0 method( renewPortList, release )を追加
  • 2.0.0 ROHM BP35C2に対応
  • 1.0.1 READMEだけ修正
  • 1.0.0 とりあえず開発してpublish、TESSERA RL7023のみ対応
2.8.0

8 months ago

2.7.6

1 year ago

2.7.5

1 year ago

2.7.0

2 years ago

2.7.2

2 years ago

2.7.1

2 years ago

2.7.4

2 years ago

2.7.3

2 years ago

2.6.5

2 years ago

2.6.4

2 years ago

2.6.7

2 years ago

2.6.6

2 years ago

2.6.9

2 years ago

2.6.8

2 years ago

2.2.0

2 years ago

2.6.1

2 years ago

2.6.0

2 years ago

2.6.3

2 years ago

2.6.2

2 years ago

2.5.0

2 years ago

2.1.2

2 years ago

2.1.1

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.1.0

2 years ago

2.0.0

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago