Skip to content

Commit fe7af3a

Browse files
authored
Upgrade to .NET 10. Rewrite SML Parser for new SmartMeter. Use Cake build. Add installer script. (#8)
* Refactor project and build configuration: remove nuke files, introduce centralized package management, update to .NET 10. Adjust dependencies and descriptions across projects. * Refactor `MqttValuePublisher` to use `ReadOnlySequence` for payloads; upgrade to .NET 10 and centralize test package versions. * Update test package versions and fix balance value sign logic in `SmlValueProcessor`. * Refactor `SmartMeterServer` constructor to leverage parameterized properties and streamline initialization logic. Simplify subscription disposal and improve logging. * Add SmartMeter CLI project with reactive data producer and basic CLI functionality. * Add debug logging for serial port data reception in `SmartMeterDataProducer` * Add CRC-16/X-25 implementation, SML message framing, parsing, and unit tests. - Introduced `Crc16X25` class for calculating CRC-16/X-25 checksums. - Added `SmlFrame`, `SmlMessageDetector`, and related classes for framing and detecting SML transport v1 messages. - Implemented parsing logic with `ObisValue` to support SML GetListResponse payloads. - Created unit tests for framing, parsing, and end-to-end workflows. - Added utilities for OBIS code parsing and smart meter unlocking strategies with comprehensive options and result enums. * Refactor `SmartMeterReactiveDataPipeline` to use `Subject` for reactive value streams, improve OBIS code filtering logic, and simplify logging to debug level. * Add `SmartMeterOptions` to inject configurable energy offsets and refactor `SmartMeterReactiveDataPipeline` to apply these offsets. Adjust log levels to debug and fix power balance sign logic in `SmlValueProcessor`. * Adjust logging levels in SmlMessageDetectorLoggingTests and SmlParserLoggingTests to use Debug consistently. * Refactor exception logging and initialization logic, and improve cancellation token handling for `SmartMeterDataProducer`, `ValueHistoryDataSet`, and `SmartMeterValue`. * Refactor `SmartMeterDataProducer` to implement `IDisposable`, improve resource management, and replace custom subscription handling in `SmartMeterServer` with `ISmartMeterDataProducer`. * Move SmartMeter-related classes to `SmlData` namespace for clearer organization and improved code structure. * Extract unlock functionality into `ISmartMeterUnlocker` and `SmartMeterUnlocker`; refactor `SmartMeterDataProducer` to remove redundant unlock logic and simplify interface. * Refactor `SmlValueType` to `SmlMessageValueType` for improved clarity and consistency; update references across parsing, reactive data pipeline, and testing layers. * Move `ValueHistory`-related classes to `History` namespace for better organization and consistency with project structure. * Remove obsolete SML-related classes (`ISmlValueReader`, `SmlDataReader`, `SmlMessage`, `SmlReadDataMode`, `SmlValueReader`, and reactive extensions) to clean up and streamline the codebase. * Migrate SML-related components from `CreativeCoders.SmartMeter.Sml` to `CreativeCoders.SmartMeter.Core`; remove obsolete references, update namespaces, and streamline project structure. * Refactor `SmartMeterReactiveDataPipeline` to handle observer completion and error logging properly; fix test assertion syntax; replace `lock(this)` with dedicated sync object in `ValueHistory`; minor cleanup in CLI entry point. * Add unit tests for SmartMeter core, server, and data processing components; introduce test fixtures and streamline test project organization. * Dispose resources properly in `MqttValuePublisher` and update related tests; suppress false-positive analyzer warnings in test fixtures and parsing logic; improve `SmartMeterServer` shutdown sequence. * Introduce Cake build system and GitHub Actions workflows; add `BuildContext` and related CI/CD scripts. * Rename `HomeMatic` to `SmartMeter` across build scripts, workflows, and project files; remove redundant Windows-specific steps in CI pipelines. * Add .NET SDK detection to `build.sh` and include `scripts` folder in solution file * Update .NET SDK version in `global.json` and remove redundant SDK listing in `build.sh` * Refactor `GitVersion.yml` for consistent branch configuration and improved versioning flexibility. * Fix flaky test in `SmartMeterDataProducerTests` by adding polling mechanism for asynchronous `Subscribe` assertions. * Update GitHub Actions workflows to use newer versions of `checkout`, `cache`, and `upload-artifact` actions. * Bump `CreativeCoders.*` package versions to `6.7.2`. * Rename `HomeMatic.Cli` to `SmartMeter.Cli` in GitHub Actions workflow and remove redundant Windows-specific steps. * Add support for building and publishing `SmartMeter.Server.Linux` package in CI/CD pipelines. * Add `install-smartmeter.sh` script for automating SmartMeter server installation and include it in the solution file. * Update `install.sh` to create a backup of the existing installation instead of deleting files * Refactor SML parser and related tests for consistent formatting and improved readability. Apply minor code cleanups across projects. * Refactor `Crc16X25` table usage for clarity
1 parent a8e8f86 commit fe7af3a

110 files changed

Lines changed: 6207 additions & 825 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/integration.yml

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,60 @@
1-
# ------------------------------------------------------------------------------
2-
# <auto-generated>
3-
#
4-
# This code was generated.
5-
#
6-
# - To turn off auto-generation set:
7-
#
8-
# [GitHubActions (AutoGenerate = false)]
9-
#
10-
# - To trigger manual generation invoke:
11-
#
12-
# nuke --generate-configuration GitHubActions_integration --host GitHubActions
13-
#
14-
# </auto-generated>
15-
# ------------------------------------------------------------------------------
16-
171
name: integration
182

193
on:
204
push:
215
branches:
226
- 'feature/**'
23-
pull_request:
24-
branches:
25-
- main
267

278
jobs:
289
ubuntu-latest:
2910
name: ubuntu-latest
3011
runs-on: ubuntu-latest
3112
steps:
32-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v6
3314
with:
3415
fetch-depth: 0
35-
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
36-
uses: actions/cache@v4
16+
- name: 'Cache: ~/.nuget/packages'
17+
uses: actions/cache@v5
3718
with:
3819
path: |
39-
.nuke/temp
4020
~/.nuget/packages
4121
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
42-
- name: 'Run: clean, restore, build, publish'
43-
run: ./build.cmd clean restore build publish
22+
- name: 'Build with target: NuGetPush'
23+
run: ./build.cmd -t nugetpush -t publish -t createdistpackages
4424
env:
45-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26+
- name: 'Publish: coverage_report'
27+
uses: actions/upload-artifact@v7
28+
with:
29+
name: coverage-report-linux
30+
path: .tests/coverage-report
31+
- name: 'Publish: cli dist package'
32+
uses: actions/upload-artifact@v7
33+
with:
34+
name: SmartMeter.Cli
35+
path: .artifacts/dist/SmartMeter.Cli.tar.gz
36+
- name: 'Publish: server Linux dist package'
37+
uses: actions/upload-artifact@v7
38+
with:
39+
name: SmartMeter.Server.Linux
40+
path: .artifacts/dist/SmartMeter.Server.Linux.tar.gz
41+
macos-latest:
42+
name: macos-latest
43+
runs-on: macos-latest
44+
steps:
45+
- uses: actions/checkout@v6
46+
with:
47+
fetch-depth: 0
48+
- name: 'Cache: ~/.nuget/packages'
49+
uses: actions/cache@v5
50+
with:
51+
path: |
52+
~/.nuget/packages
53+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
54+
- name: 'Build with target: Pack'
55+
run: ./build.cmd -t pack
56+
- name: 'Publish: coverage_report'
57+
uses: actions/upload-artifact@v7
58+
with:
59+
name: coverage-report-macos
60+
path: .tests/coverage-report

.github/workflows/main.yml

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,3 @@
1-
# ------------------------------------------------------------------------------
2-
# <auto-generated>
3-
#
4-
# This code was generated.
5-
#
6-
# - To turn off auto-generation set:
7-
#
8-
# [GitHubActions (AutoGenerate = false)]
9-
#
10-
# - To trigger manual generation invoke:
11-
#
12-
# nuke --generate-configuration GitHubActions_main --host GitHubActions
13-
#
14-
# </auto-generated>
15-
# ------------------------------------------------------------------------------
16-
171
name: main
182

193
on:
@@ -26,17 +10,52 @@ jobs:
2610
name: ubuntu-latest
2711
runs-on: ubuntu-latest
2812
steps:
29-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v6
3014
with:
3115
fetch-depth: 0
32-
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
33-
uses: actions/cache@v4
16+
- name: 'Cache: ~/.nuget/packages'
17+
uses: actions/cache@v5
3418
with:
3519
path: |
36-
.nuke/temp
3720
~/.nuget/packages
3821
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
39-
- name: 'Run: clean, restore, build, publish'
40-
run: ./build.cmd clean restore build publish
22+
- name: 'Build with target: NuGetPush'
23+
run: ./build.cmd -t nugetpush -t publish -t createdistpackages -t creategithubrelease
4124
env:
25+
NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4226
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27+
- name: 'Publish: coverage_report'
28+
uses: actions/upload-artifact@v7
29+
with:
30+
name: coverage-report-linux
31+
path: .tests/coverage-report
32+
- name: 'Publish: cli dist package'
33+
uses: actions/upload-artifact@v7
34+
with:
35+
name: SmartMeter.Cli
36+
path: .artifacts/dist/SmartMeter.Cli.tar.gz
37+
- name: 'Publish: server Linux dist package'
38+
uses: actions/upload-artifact@v7
39+
with:
40+
name: SmartMeter.Server.Linux
41+
path: .artifacts/dist/SmartMeter.Server.Linux.tar.gz
42+
macos-latest:
43+
name: macos-latest
44+
runs-on: macos-latest
45+
steps:
46+
- uses: actions/checkout@v6
47+
with:
48+
fetch-depth: 0
49+
- name: 'Cache: ~/.nuget/packages'
50+
uses: actions/cache@v5
51+
with:
52+
path: |
53+
~/.nuget/packages
54+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
55+
- name: 'Build with target: Pack'
56+
run: ./build.cmd -t pack
57+
- name: 'Publish: coverage_report'
58+
uses: actions/upload-artifact@v7
59+
with:
60+
name: coverage-report-macos
61+
path: .tests/coverage-report

.github/workflows/pull-request.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: pull-request
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
8+
jobs:
9+
ubuntu-latest:
10+
name: ubuntu-latest
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v6
14+
with:
15+
fetch-depth: 0
16+
- name: 'Cache: ~/.nuget/packages'
17+
uses: actions/cache@v5
18+
with:
19+
path: |
20+
~/.nuget/packages
21+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
22+
- name: 'Build with target: Pack'
23+
run: ./build.cmd -t pack
24+
- name: 'Publish: coverage_report'
25+
uses: actions/upload-artifact@v7
26+
with:
27+
name: coverage-report-linux
28+
path: .tests/coverage-report
29+
macos-latest:
30+
name: macos-latest
31+
runs-on: macos-latest
32+
steps:
33+
- uses: actions/checkout@v6
34+
with:
35+
fetch-depth: 0
36+
- name: 'Cache: ~/.nuget/packages'
37+
uses: actions/cache@v5
38+
with:
39+
path: |
40+
~/.nuget/packages
41+
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
42+
- name: 'Build with target: Pack'
43+
run: ./build.cmd -t pack
44+
- name: 'Publish: coverage_report'
45+
uses: actions/upload-artifact@v7
46+
with:
47+
name: coverage-report-macos
48+
path: .tests/coverage-report

.github/workflows/release.yml

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,9 @@
1-
# ------------------------------------------------------------------------------
2-
# <auto-generated>
3-
#
4-
# This code was generated.
5-
#
6-
# - To turn off auto-generation set:
7-
#
8-
# [GitHubActions (AutoGenerate = false)]
9-
#
10-
# - To trigger manual generation invoke:
11-
#
12-
# nuke --generate-configuration GitHubActions_release --host GitHubActions
13-
#
14-
# </auto-generated>
15-
# ------------------------------------------------------------------------------
16-
171
name: release
182

3+
concurrency:
4+
group: release-${{ github.ref }}
5+
cancel-in-progress: false
6+
197
on:
208
push:
219
tags:
@@ -26,17 +14,32 @@ jobs:
2614
name: ubuntu-latest
2715
runs-on: ubuntu-latest
2816
steps:
29-
- uses: actions/checkout@v4
17+
- uses: actions/checkout@v6
3018
with:
3119
fetch-depth: 0
32-
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
33-
uses: actions/cache@v4
20+
- name: 'Cache: ~/.nuget/packages'
21+
uses: actions/cache@v5
3422
with:
3523
path: |
36-
.nuke/temp
3724
~/.nuget/packages
3825
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
39-
- name: 'Run: clean, restore, build, publish, CreateDistPackages, CreateGithubRelease'
40-
run: ./build.cmd clean restore build publish CreateDistPackages CreateGithubRelease
26+
- name: 'Build with target: NuGetPush'
27+
run: ./build.cmd -t pack -t nugetpush -t publish -t createdistpackages -t creategithubrelease
4128
env:
29+
NUGET_TOKEN: ${{ secrets.NUGET_ORG_TOKEN }}
4230
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
- name: 'Publish: coverage_report'
32+
uses: actions/upload-artifact@v7
33+
with:
34+
name: coverage-report-linux
35+
path: .tests/coverage-report
36+
- name: 'Publish: cli dist package'
37+
uses: actions/upload-artifact@v7
38+
with:
39+
name: SmartMeter.Cli
40+
path: .artifacts/dist/SmartMeter.Cli.tar.gz
41+
- name: 'Publish: server Linux dist package'
42+
uses: actions/upload-artifact@v7
43+
with:
44+
name: SmartMeter.Server.Linux
45+
path: .artifacts/dist/SmartMeter.Server.Linux.tar.gz

Directory.Build.props

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project>
2+
<PropertyGroup>
3+
<TargetFramework>net10.0</TargetFramework>
4+
<Authors>CreativeCoders</Authors>
5+
<NoWarn>$(NoWarn);IDE0079</NoWarn>
6+
<RepositoryUrl>https://github.com/CreativeCodersTeam/SmartMeter</RepositoryUrl>
7+
<Nullable>enable</Nullable>
8+
<ImplicitUsings>enable</ImplicitUsings>
9+
<IsPackable>false</IsPackable>
10+
</PropertyGroup>
11+
</Project>

Directory.Packages.props

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project>
2+
<PropertyGroup>
3+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4+
</PropertyGroup>
5+
<ItemGroup>
6+
<PackageVersion Include="CreativeCoders.CakeBuild" Version="6.7.2" />
7+
<PackageVersion Include="CreativeCoders.Core" Version="6.7.2" />
8+
<PackageVersion Include="CreativeCoders.Daemon" Version="6.7.2" />
9+
<PackageVersion Include="CreativeCoders.Daemon.Linux" Version="6.7.2" />
10+
<PackageVersion Include="CreativeCoders.Net" Version="6.7.2" />
11+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.6" />
12+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.6" />
13+
<PackageVersion Include="MQTTnet" Version="5.1.0.1559" />
14+
<PackageVersion Include="Serilog.Extensions.Hosting" Version="10.0.0" />
15+
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
16+
<PackageVersion Include="Spectre.Console" Version="0.55.2" />
17+
<PackageVersion Include="System.IO.Ports" Version="10.0.6" />
18+
<PackageVersion Include="System.Reactive" Version="6.1.0" />
19+
<!-- Test packages -->
20+
<PackageVersion Include="AwesomeAssertions" Version="9.4.0" />
21+
<PackageVersion Include="coverlet.collector" Version="8.0.1" />
22+
<PackageVersion Include="FakeItEasy" Version="9.0.1" />
23+
<PackageVersion Include="JetBrains.Annotations" Version="2025.2.4" />
24+
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="10.5.0" />
25+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.4.0" />
26+
<PackageVersion Include="xunit" Version="2.9.3" />
27+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
28+
<PackageVersion Include="XunitXml.TestLogger" Version="8.0.0" />
29+
</ItemGroup>
30+
</Project>

0 commit comments

Comments
 (0)