Smdn.Net.EchonetLite.RouteB 2.0.0-preview3

Prefix Reserved
This is a prerelease version of Smdn.Net.EchonetLite.RouteB.
dotnet add package Smdn.Net.EchonetLite.RouteB --version 2.0.0-preview3                
NuGet\Install-Package Smdn.Net.EchonetLite.RouteB -Version 2.0.0-preview3                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Smdn.Net.EchonetLite.RouteB" Version="2.0.0-preview3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Smdn.Net.EchonetLite.RouteB --version 2.0.0-preview3                
#r "nuget: Smdn.Net.EchonetLite.RouteB, 2.0.0-preview3"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Smdn.Net.EchonetLite.RouteB as a Cake Addin
#addin nuget:?package=Smdn.Net.EchonetLite.RouteB&version=2.0.0-preview3&prerelease

// Install Smdn.Net.EchonetLite.RouteB as a Cake Tool
#tool nuget:?package=Smdn.Net.EchonetLite.RouteB&version=2.0.0-preview3&prerelease                

Smdn.Net.EchonetLite.RouteB 2.0.0-preview3

Provides an application layer implementation for communication via the route-B, based on the specifications described in the "Interface Specifications for Application Layer Communication between Smart Electric Energy Meters and Controllers".

Provides APIs such as the HemsController class, which implements the "HEMS controller" in the specification, and the LowVoltageSmartElectricEnergyMeter class, which implements the "Requirements for low-voltage smart electric energy meter class".

「低圧スマート電力量メータ・HEMS コントローラ間アプリケーション通信インタフェース仕様書」に記載されている仕様に基づく、「Bルート」を介した通信を行うアプリケーション層の実装を提供します。

同仕様書における「HEMS コントローラ」に相当するHemsControllerクラス、「低圧スマート電力量メータクラス規定」を実装するLowVoltageSmartElectricEnergyMeterクラスなどのAPIを提供します。

Usage

This is an example of connecting to a smart meter and reading the measurement values.

以下のコードでは、スマートメーターに接続し、計測値を読み出します。

// SPDX-FileCopyrightText: 2023 smdn <smdn@smdn.jp>
// SPDX-License-Identifier: MIT
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using Smdn.Devices.BP35XX;
using Smdn.Net.EchonetLite;
using Smdn.Net.EchonetLite.RouteB;
using Smdn.Net.EchonetLite.RouteB.Credentials;
using Smdn.Net.EchonetLite.RouteB.Transport;
using Smdn.Net.EchonetLite.RouteB.Transport.BP35XX;
using Smdn.Net.EchonetLite.RouteB.Transport.SkStackIP;
using Smdn.Net.SkStackIP;

// ServiceCollectionを使用して、Bルート設定値やWi-SUNデバイスの追加を行います
var services = new ServiceCollection();

// Bルート認証情報を追加します
services.AddRouteBCredential(
  id: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", // BルートID(ハイフン・スペースなし)を指定してください
  password: "XXXXXXXXXXXX" // Bルートパスワードを指定してください
);

// Bルート通信を行うWi-SUNデバイスを追加・設定します
services.AddRouteBHandler(
  builder => builder
    // Bルート通信を行うデバイスとしてBP35A1を追加します
    // (PackageReferenceに`Smdn.Net.EchonetLite.RouteB.BP35XX`を追加してください)
    .AddBP35A1(
      static bp35a1 => {
        // BP35A1とのUART通信を行うためのシリアルポート名を指定してください
        // Windowsでは`COM1`、Linux等では`/dev/ttyACM0`, `/dev/ttyUSB0`といった名前を指定してください
        bp35a1.SerialPortName = "/dev/ttyACM0";
      }
    )
    // Bルート通信を行うためのPANAセッションを設定します
    .ConfigureSession(
      // 特に設定しない場合、自動的にアクティブスキャンを行ってスマートメーターを発見し、セッションを開始します
      // ただし、アクティブスキャンには数十秒〜数分程度の時間がかかる場合があります
      // 以下の設定値を設定することで即座にセッションを開始することが可能となるため、
      // 別の手段で既知である場合は設定しておくことを推奨します
      session => {
        // 接続先のIPアドレスまたはMACアドレスを指定してください
        // session.PaaAddress = IPAddress.Parse("2001:0db8:0000:0000:0000:0000:0000:0001");
        // session.PaaMacAddress = PhysicalAddress.Parse("00-00-5E-FF-FE-00-53-00");

        // 接続先のPAN IDを指定してください
        // session.PanId = 0xBEAF;

        // 接続に使用するチャンネルを指定してください
        // session.Channel = SkStackChannel.Channels[0x21];
      }
    )
);

// ログ出力を設定します
services.AddLogging(
  builder => builder
    .AddSimpleConsole(static options => options.SingleLine = true)
    .AddFilter(static level => LogLevel.Information <= level)
);

// CTRL+Cの押下で処理を中断するためのCancellationTokenSourceを作成します
using var cts = new CancellationTokenSource();

Console.CancelKeyPress += (sender, e) => {
  cts.Cancel();
  e.Cancel = true;
};

// ServiceCollectionの設定を使用してHemsControllerを作成します
using var hemsController = new HemsController(services.BuildServiceProvider());

// 上記の設定でスマートメーターへ接続します (接続確立まで数秒〜数十秒程度かかります)
await hemsController.ConnectAsync(cts.Token);

// スマートメーターを操作するオブジェクトを参照します
var smartMeter = hemsController.SmartMeter;

// スマートメーターからECHONETプロパティの値を読み出します
await smartMeter.ReadPropertiesAsync(
  [
    smartMeter.InstantaneousElectricPower.PropertyCode,
    smartMeter.InstantaneousCurrent.PropertyCode,
    smartMeter.NormalDirectionCumulativeElectricEnergy.PropertyCode,
  ],
  hemsController.Controller,
  cts.Token
);

// 読み出した瞬時電力計測値(R相・T相)の値を表示します
Console.WriteLine($"{smartMeter.InstantaneousElectricPower.Value} [W]");

// 瞬時電流計測値(R相・T相)の値を表示します
var (currentPhaseT, currentPhaseR) = smartMeter.InstantaneousCurrent.Value;

Console.WriteLine($"{currentPhaseT.Amperes} [A] (Phase T)");
Console.WriteLine($"{currentPhaseR.Amperes} [A] (Phase R)");

// 積算電力量計測値(正方向)の値を表示します
// (この値は日別や月別ではなく、スマートメーターの現在の指示値を表します)
var cumulativeEnergy = smartMeter.NormalDirectionCumulativeElectricEnergy.Value;

Console.WriteLine($"{cumulativeEnergy.KiloWattHours} [kWh]");

// 接続を切断します
await hemsController.DisconnectAsync(cts.Token);

More examples can be found on the GitHub repository.

Contributing

This project welcomes contributions, feedbacks and suggestions. You can contribute to this project by submitting Issues or Pull Requests on the GitHub repository.

API List

List of APIs exposed by assembly Smdn.Net.EchonetLite.RouteB-2.0.0-preview3 (net8.0)

// Smdn.Net.EchonetLite.RouteB.dll (Smdn.Net.EchonetLite.RouteB-2.0.0-preview3)
//   Name: Smdn.Net.EchonetLite.RouteB
//   AssemblyVersion: 2.0.0.0
//   InformationalVersion: 2.0.0-preview3+2612dc0eb7dba458048cbe65c5e156d272f8ee87
//   TargetFramework: .NETCoreApp,Version=v8.0
//   Configuration: Release
//   Referenced assemblies:
//     Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
//     Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
//     Smdn.Net.EchonetLite, Version=2.0.0.0, Culture=neutral
//     Smdn.Net.EchonetLite.Primitives, Version=2.0.0.0, Culture=neutral
//     Smdn.Net.EchonetLite.RouteB.Primitives, Version=2.0.0.0, Culture=neutral
//     System.Collections, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
//     System.ComponentModel, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
//     System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
//     System.Memory, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
//     System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
//     System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
#nullable enable annotations

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Smdn.Net.EchonetLite;
using Smdn.Net.EchonetLite.ObjectModel;
using Smdn.Net.EchonetLite.RouteB;
using Smdn.Net.EchonetLite.RouteB.Credentials;
using Smdn.Net.EchonetLite.RouteB.Transport;

namespace Smdn.Net.EchonetLite.RouteB {
  public class HemsController :
    IAsyncDisposable,
    IDisposable,
    IRouteBCredentialIdentity
  {
    public HemsController(IRouteBEchonetLiteHandlerFactory echonetLiteHandlerFactory, IRouteBCredentialProvider routeBCredentialProvider, ILoggerFactory? loggerFactory = null) {}
    public HemsController(IServiceProvider serviceProvider) {}

    protected EchonetClient Client { get; }
    public EchonetObject Controller { get; }
    [MemberNotNullWhen(false, "echonetLiteHandler")]
    protected bool IsDisposed { [MemberNotNullWhen(false, "echonetLiteHandler")] get; }
    public LowVoltageSmartElectricEnergyMeter SmartMeter { get; }
    public TimeSpan TimeoutWaitingProactiveNotification { get; set; }
    public TimeSpan TimeoutWaitingResponse1 { get; set; }
    public TimeSpan TimeoutWaitingResponse2 { get; set; }

    public ValueTask ConnectAsync(CancellationToken cancellationToken = default) {}
    public async ValueTask DisconnectAsync(CancellationToken cancellationToken = default) {}
    protected virtual void Dispose(bool disposing) {}
    public void Dispose() {}
    public async ValueTask DisposeAsync() {}
    protected virtual async ValueTask DisposeAsyncCore() {}
    [MemberNotNull("client")]
    [MemberNotNull("Client")]
    [MemberNotNull("smartMeterObject")]
    [MemberNotNull("controllerObject")]
    protected void ThrowIfDisconnected() {}
  }

  public sealed class LowVoltageSmartElectricEnergyMeter : DeviceSuperClass {
    public IEchonetPropertyGetAccessor<int> Coefficient { get; }
    public IEchonetPropertyGetAccessor<IReadOnlyList<(MeasurementValue<ElectricEnergyValue> NormalDirection, MeasurementValue<ElectricEnergyValue> ReverseDirection)>> CumulativeElectricEnergyLog2 { get; }
    public IEchonetPropertySetGetAccessor<DateTime> DayForTheHistoricalDataOfCumulativeElectricEnergy1 { get; }
    public IEchonetPropertySetGetAccessor<(DateTime DateAndTime, int NumberOfItems)> DayForTheHistoricalDataOfCumulativeElectricEnergy2 { get; }
    public IEchonetPropertyGetAccessor<(ElectricCurrentValue RPhase, ElectricCurrentValue TPhase)> InstantaneousCurrent { get; }
    public IEchonetPropertyGetAccessor<int> InstantaneousElectricPower { get; }
    public IEchonetPropertyGetAccessor<ElectricEnergyValue> NormalDirectionCumulativeElectricEnergy { get; }
    public IEchonetPropertyGetAccessor<MeasurementValue<ElectricEnergyValue>> NormalDirectionCumulativeElectricEnergyAtEvery30Min { get; }
    public IEchonetPropertyGetAccessor<IReadOnlyList<MeasurementValue<ElectricEnergyValue>>> NormalDirectionCumulativeElectricEnergyLog1 { get; }
    public IEchonetPropertyGetAccessor<int> NumberOfEffectiveDigitsCumulativeElectricEnergy { get; }
    public IEchonetPropertyGetAccessor<(MeasurementValue<ElectricEnergyValue> NormalDirection, MeasurementValue<ElectricEnergyValue> ReverseDirection)> OneMinuteMeasuredCumulativeAmountsOfElectricEnergy { get; }
    public IEchonetPropertyGetAccessor<ElectricEnergyValue> ReverseDirectionCumulativeElectricEnergy { get; }
    public IEchonetPropertyGetAccessor<MeasurementValue<ElectricEnergyValue>> ReverseDirectionCumulativeElectricEnergyAtEvery30Min { get; }
    public IEchonetPropertyGetAccessor<IReadOnlyList<MeasurementValue<ElectricEnergyValue>>> ReverseDirectionCumulativeElectricEnergyLog1 { get; }
    public IEchonetPropertyGetAccessor<ReadOnlyMemory<byte>> RouteBIdentificationNumber { get; }
    public IEchonetPropertyGetAccessor<decimal> UnitForCumulativeElectricEnergy { get; }
  }

  public static class MeasurementValue {
    public static MeasurementValue<TValue> Create<TValue>(TValue @value, DateTime measuredAt) where TValue : struct {}
  }

  public sealed class RouteBDeviceFactory : IEchonetDeviceFactory {
    public static RouteBDeviceFactory Instance { get; }

    public RouteBDeviceFactory() {}

    public EchonetDevice? Create(byte classGroupCode, byte classCode, byte instanceCode) {}
  }

  public readonly struct ElectricCurrentValue {
    public decimal Amperes { get; }
    public bool IsValid { get; }
    public short RawValue { get; }

    public override string ToString() {}
  }

  public readonly struct ElectricEnergyValue {
    public static readonly ElectricEnergyValue NoMeasurementData; // = "(no data)"
    public static readonly ElectricEnergyValue Zero; // = "0 [kWh]"

    public bool IsValid { get; }
    public decimal KiloWattHours { get; }
    public int RawValue { get; }
    public decimal WattHours { get; }

    public override string ToString() {}
    public bool TryGetValueAsKiloWattHours(out decimal @value) {}
  }

  public readonly struct MeasurementValue<TValue> where TValue : struct {
    public MeasurementValue(TValue @value, DateTime measuredAt) {}

    public DateTime MeasuredAt { get; }
    public TValue Value { get; }

    public void Deconstruct(out TValue @value, out DateTime measuredAt) {}
    public override string ToString() {}
  }
}

namespace Smdn.Net.EchonetLite.RouteB.Credentials {
  public static class RouteBCredentialServiceCollectionExtensions {
    public static IServiceCollection AddRouteBCredential(this IServiceCollection services, string id, string password) {}
    public static IServiceCollection AddRouteBCredentialFromEnvironmentVariable(this IServiceCollection services, string envVarForId, string envVarForPassword) {}
    public static IServiceCollection AddRouteBCredentialProvider(this IServiceCollection services, IRouteBCredentialProvider credentialProvider) {}
  }
}

namespace Smdn.Net.EchonetLite.RouteB.Transport {
  public static class RouteBEchonetLiteHandlerBuilderServiceCollectionExtensions {
    public static IServiceCollection AddRouteBHandler(this IServiceCollection services, Action<IRouteBEchonetLiteHandlerBuilder> configure) {}
  }
}
// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.4.1.0.
// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2.0.0-preview3 68 10/16/2024
2.0.0-preview2 95 6/30/2024
2.0.0-preview1 74 4/4/2024