LoginSignup
4
4

More than 5 years have passed since last update.

C#で書いたECHONET Lite の簡単なコントールサンプル

Last updated at Posted at 2018-08-12

 ECHONET Liteのコントローラの制御関連のプログラムをC#で書きたかったのですが、ネット検索してもあまりヒットしなかったので自作しました。
 サンプルコードはGithubのechonetlitecsリポジトリに置いています。

サンプルの説明

pic1.png
 「一覧の取得」ボタンを押すとLAN内のECHONET Liteノード一覧を取得します。ノードが取得できると、下のノード欄に1つ目に取得したノードコードがセットされます。次の欄にインスタンス番号がセットされます。
 「オン」「オフ」ボタンは、スイッチのオンオフを行うボタンです。図の一覧に表示されている0290は一般照明のノードコードですので「オン」「オフ」ボタンを押すと、照明を点けたり消したりできます。

ノード一覧の取得

一覧の取得はUDPマルチキャストすることによって、ノードからの返信を取得します。
ポートは3610、アドレスは224.0.23.0 です。とりあえず、PortとMulticastAddressを設定しています。

ECHONET_Lite.cs
 private static readonly int Port = 3610;
 private static readonly string MulticastAddress = "224.0.23.0";
 private static readonly UInt16 Header = 0x1081;
 private static readonly UInt16 TransactionID = 0x0000;
 private static readonly byte ControllerGrpCd = 0x05;
 private static readonly byte ControllerClsCd = 0xFF;
 private static readonly byte ControllerInsCd = 0x01;

 UDPマルチキャストするとノードの返信はUDPユニキャストで返ってきます。なので、UDPマルチキャストを送信した後にUDPユニキャストで受信します。プログラムは以下です(エラー処理は省いています)。

ECHONET_Lite.cs
//ノード一覧を取得するためにマルチキャストします
using (UdpClient udpClient = new UdpClient(AddressFamily.InterNetwork))
{
  IPAddress address = IPAddress.Parse(MulticastAddress);
  IPEndPoint ipEndPoint = new IPEndPoint(address, Port);
  udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, Port));
  udpClient.JoinMulticastGroup(address, IPAddress.Parse(LocalAddress));
  udpClient.MulticastLoopback = true;
  byte[] frame = CreateSearchFrame();
  udpClient.Send(frame, frame.Length, ipEndPoint);
}
//マルチキャストの返信がユニキャストで来るので取得します
byte[] recvBytes = null;
IPEndPoint remoteEP = null;
using (UdpClient udp = new UdpClient(Port))
{
  udp.Client.ReceiveTimeout = 5000;   //5secでタイムアウト
  recvBytes = udp.Receive(ref remoteEP);
}

 これで、recvBytes[]にノード一覧のフレームデータが入っています。ノードのIPアドレスは remoteEP.Address に入っています。
 listにノードデータを追加しています。

ECHONET_Lite.cs
List<EObject> list = new List<EObject>();
string ipaddress = remoteEP.Address.ToString();
//取得したノードをlistに入れます
for (int i = 0; i < nodeCnt; i++)
{
  EObject eo = new EObject();
  eo.Number = i + 1;
  eo.IPAddress = ipaddress;
  eo.GroupCd = recvBytes[15 + i * 3];
  eo.ClassCd = recvBytes[15 + i * 3 + 1];
  eo.InstanceCd = recvBytes[15 + i * 3 + 2];
  list.Add(eo);
}

ECHONET Liteとは直接関係ないですが、マルチキャストの際に自身のローカルIPアドレスを付加しておかないとUDPユニキャストが返って来ないようです。ローカルIPアドレスのプロパティを追加しました。フォームのソースコードの方に自身のローカルIPアドレスを取得するメソッドも入れています。

スイッチのオンオフ

ECHONET Liteのコントロールサンプルとして、スイッチのオンオフサンプルコードを付けています。スイッチのオンオフ用フレームをUDPユニキャストで送信するだけです。

ECHONET_Lite.cs
public byte[] SwitchSet(EObject eo, bool sw)
{
  byte[] sendFrame = CreateSwitchFrame(eo, sw);   //スイッチ用のフレームを取得します
  byte[] recvBytes = null;

  IPEndPoint remoteEP = null;
  using (UdpClient udp = new UdpClient(Port))
  {
    udp.Client.ReceiveTimeout = 5000;   //5secでタイムアウト
    udp.Send(sendFrame, sendFrame.Length, eo.IPAddress, Port);
    recvBytes = udp.Receive(ref remoteEP);
  }
  return recvBytes;
}

  SwitchSet()は、スイッチ用のフレーム生成するメソッドです。プロパティ番号0x80がスイッチのオンオフプロパティです。

ECHONET_Lite.cs
private byte[] CreateSwitchFrame(EObject eo, bool sw)
{
  byte[] frame = new byte[15];
  frame[0] = (byte)(Header >> 8);         //EHD1 ECHONETLiteヘッダ  1Byte   0x10固定
  frame[1] = (byte)(Header & 0xFF);       //EHD2 ECHONETLiteヘッダ  1Byte   0x81固定
  frame[2] = (byte)(TransactionID >> 8);  //TID  トランザクションID 2Byte   0~65535
  frame[3] = (byte)(TransactionID & 0xFF);//TID  トランザクションID 2Byte   0~65535
  frame[4] = ControllerGrpCd;             //SEOJ 送信元オブジェクト コントローラークラスグループコード
  frame[5] = ControllerClsCd;             //SEOJ 送信元オブジェクト コントローラークラスコード
  frame[6] = ControllerInsCd;             //SEOJ 送信元オブジェクト インスタンスコード
  frame[7] = eo.GroupCd;                  //DEOJ 送信先オブジェクト グループコード
  frame[8] = eo.ClassCd;                  //DEOJ 送信先オブジェクト クラスコード
  frame[9] = eo.InstanceCd;               //DEOJ 送信先オブジェクト インスタンスコード
  frame[10] = (byte)enmESV.SETC;           //ESV  サービスコード     SETC
  frame[11] = (byte)0x01;                 //OPC  プロパティ数
  frame[12] = (byte)0x80;                 //EPC  プロパティ番号     スイッチのオンオフ
  frame[13] = (byte)0x01;                 //PDC  EDTのバイト数
  frame[14] = sw ? (byte)0x30 : (byte)0x31;   //0x30がスイッチオン 0x31がスイッチオフ
  return frame;
}

 簡単ですが、こんな感じでC#から制御できるようになりました。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4