S7Sharp.Watch 1.1.2

dotnet add package S7Sharp.Watch --version 1.1.2
                    
NuGet\Install-Package S7Sharp.Watch -Version 1.1.2
                    
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="S7Sharp.Watch" Version="1.1.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="S7Sharp.Watch" Version="1.1.2" />
                    
Directory.Packages.props
<PackageReference Include="S7Sharp.Watch" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add S7Sharp.Watch --version 1.1.2
                    
#r "nuget: S7Sharp.Watch, 1.1.2"
                    
#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.
#:package S7Sharp.Watch@1.1.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=S7Sharp.Watch&version=1.1.2
                    
Install as a Cake Addin
#tool nuget:?package=S7Sharp.Watch&version=1.1.2
                    
Install as a Cake Tool

S7Sharp.Watch — 数据变化监控

按每个定义自己的间隔周期读一块数据 → 与缓存按字节比 → 变了才通知(event);没变什么都不做。

  • 只读:从不写设备(写面仍归调用方与既有工具)。
  • 进程内:缓存与通知槽都在内存,进程退出即丢。
  • 零第三方依赖:唯一依赖是 S7Sharp(版本锁步)。
  • 不动产品库:本库只消费 S7Sharp 的公开面(ReadStructBytes / TryGetLayout / S7StructLayout),不重算地址与宽度。
  • 通知与读解耦:读只把事件放进"每定义的最新未消费槽"(覆盖式 ⇒ 不丢变化、只丢中间态),由独立的通知步投递 ⇒ 慢订阅者拖不住轮询。

本质边界(先知道再看代码):漏报是本质的 —— 两次读之间"变了又变回去"永远检测不到(不做去抖、不做变化历史、不做趋势)。

用法(一):C# 类定义

using S7Sharp.Siemens;
using S7Sharp.Watch;

var plc = new SiemensS7Net("192.168.0.1", 102) { Rack = 0, Slot = 1 };
// 连接由库在每次请求前保证(含既有的"自动重连一次")—— 这里也可以先 ConnectServerAsync 一次

using var watch = new S7WatchService(plc, new S7WatchOptions { IncludeBytes = false });

watch.Changed += e =>
{
    if (e.Kind == S7WatchEventKind.Initial)
        Console.WriteLine($"[{e.Id}] 基线已建立({e.Timestamp:HH:mm:ss})");
    else
        Console.WriteLine($"[{e.Id}] 变了:{string.Join(", ", e.ChangedFields)}(差异字节 {e.ChangedBytes.Count} 个)");
};
watch.Failed += e => Console.WriteLine($"[{e.Id}] 读失败:{e.Failure.Message}(缓存未动)");

// 1 秒看一次;只关心 Temp 与 Head1.Temp 两个字段
watch.Add(new S7WatchDefinition(
    id: "job1",
    type: typeof(JobData),
    interval: TimeSpan.FromSeconds(1),
    fields: ["Temp", "Head1.Temp"]));

watch.Start();

// 随时取当前值(**不触网**)
if (watch.TryGetSnapshot("job1", out S7WatchSnapshot snapshot))
    Console.WriteLine($"当前 {snapshot.Bytes.Length} 字节,取于 {snapshot.ReadAt:HH:mm:ss}");

// 运行期调优:先密后疏(**保留基线、不重发 Initial**)
watch.Update(new S7WatchDefinition("job1", typeof(JobData), TimeSpan.FromSeconds(10), fields: ["Temp"]));

watch.Stop();     // 暂停(保留基线);再 Start() 沿用

用法(二):JSON 配置(动态类型)

JSON 配置与类定义在监控这一层合一 —— 注册后拿到 Type 即可:

using S7Sharp.Siemens;
using S7Sharp.Watch;

string json = File.ReadAllText("dynamic-types.json");   // R-5 的同一份 schema
using S7DynTypeSet set = S7DynTypes.Register(json);     // 运行期生成类型
if (!set.TryGetType("JobData", out Type jobType))
    throw new InvalidOperationException("配置里没有 JobData");

using var watch = new S7WatchService(plc);
watch.Add(new S7WatchDefinition("job1", jobType, TimeSpan.FromMilliseconds(500)));
watch.Start();

注意:S7DynTypeSet 的生命周期要盖住监控期(Dispose 会丢引用、类型随之可被卸载)。

事件与队列语义(重要)

项 语义
事件种类 Initial(建立基线,不是"变了")/ Changed(数据变了,缓存已更新)/ Failed(读失败,缓存未动)
载荷 ChangedBytes(差异字节下标)· ChangedFields(字段名,含嵌套路径如 Head1.Temp)· Coalesced(本条合并掉几条中间变化)· AfterFailure(上一次读失败过)
IncludeBytes 默认 false(事件轻);打开则附整块变化前后字节
队列 每定义只留最新一条未消费事件(覆盖式):不丢变化、只丢中间态;Coalesced 计数可见
顺序 同一定义保序;跨定义无全序(各自到期 + 覆盖式槽)⇒ 别按"全局时间线"读
线程 事件在通知步的线程上抛(不是读数据的线程)⇒ 订阅者慢不拖轮询;回调抛异常被吞掉并计数(S7WatchStatus.NotifyErrors)

失败与基线

  • 读失败:不动缓存、不发 Changed,发 Failed(ErrorCode / Message 原样透出,不翻译)+ 计数。
  • 失败后首次成功读:照常比较并报(期间真的变了就是真事实),事件带 AfterFailure = true。
  • 首读:Add 时同步完成(顺序确定)并发一条 Initial。
  • Update:只改 Interval / Fields(保留基线);换 Type / ByteOffset / Id 请 Remove + Add(那等于换了监控对象)。

刻意不做

工具侧"监控页签"(要改写配置工具"不点不连 / 不加轮询"的既有契约,须另立)· 语义等价比对(float -0.0 / NaN、string 填充:字节不同即现场真变了,如实报)· 变化历史 / 趋势 / 去抖 · 事件持久化 · 监控定义的 JSON 化 · 连接池 / 并行读。

设计与判据见 docs/03-P7-1-数据变化监控设计.md;需求见 docs/01-需求规格说明书.md R-7。

Product Compatible and additional computed target framework versions.
.NET 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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows 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
1.1.2 87 10/21/2026
1.1.1 149 9/29/2026