Files
IOT_SIM/runtime/Sim.Devices/DeviceCtrlLibrary/TrainingBoard.cs
T
xuyueandClaude Opus 5.5 46e0f40cce
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
实训台接线:串口要选对。接线做成数据(BoardState.wiring),默认按教材布局图 COM2 ADAM-4017+、COM3 ADAM-4150、COM4 ZigBee 协调器、COM5 LED 屏,实验可在 meta.json 的 wiring 里改:项目 7 的书上代码在一个串口上打开两个模块,这三个实验把 4150 并到 COM2 的 485 总线上。选错串口时返回值照反编译的真机版 dll(4017 全 null、4150 全 false,4150 的 OnOff 和 LED 推送返回成功但设备不动作,ZigBee 返回 false);串口没打开时照教材仿真版。Open / Close / 没打开就读写报告给服务器,实训台最上方用红字提示("程序在 COM2 上打开 ADAM-4150,它接在 COM3""ADAM-4150 的串口没有打开,程序却在读写它"),评分不通过时也附上。只读接线展示:鼠标移到实训台设备上,标题栏写出线路,对应通道、模块、串口高亮;串口服务器按接线列出设备,程序打开的口亮绿点;程序里串口下拉框的灰字按当前接线。打开实验时浏览器发 experiment 消息换接线,老师看学生提交时按作业的实验接线(提交接口返回 sampleId)。"4017"统一写成 ADAM-4017+
上课前逐个检查 23 个实验后的修改:补上三处评分漏洞(项目 3 任务 1、项目 4 任务 3 的关闭和项目 7 任务 2 的熄灯,程序什么都不做也能通过);评分说明的空格;任务说明按实测补充(项目 2 任务 1–3、项目 3 任务 2、项目 4 任务 2、项目 7 任务 1–3、项目 8 任务 5)。使用说明、设计方案同步,设计方案记下以后可能扩展"物联网设备安装与调试"课

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 17:40:57 +08:00

70 lines
3.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;
namespace DeviceCtrlLibrary;
/// <summary>
/// 学生程序进程里的实训台传感器读数副本。权威状态在 Bun 服务器上(网页滑块和开关控制):
/// 启动时从环境变量 SIM_BOARD 读入,之后服务器每次变化都通过标准输入推送过来。
/// SetData() 直接读这里,不需要等待网络往返。
/// </summary>
public static class TrainingBoard
{
private static readonly object Lock = new();
// ADAM-4017 Vin0–Vin7(温度、湿度、光照、气压、空气质量、CO2、风速、预留)
private static int[] _analog = { 25, 60, 500, 101, 60, 600, 3, 0 };
// ADAM-4150 DI0–DI6(人体红外、火焰、烟雾、红外对射、预留)
private static bool[] _digital = new bool[7];
// 接线:设备 → 串口(教材布局图的接法,随实验而定,见 shared/protocol.ts 的 DEFAULT_WIRING)
private static readonly Dictionary<string, string> Wiring = new()
{
["adam4017"] = "COM2",
["adam4150"] = "COM3",
["zigbee"] = "COM4",
["led"] = "COM5",
};
static TrainingBoard()
{
var initial = Environment.GetEnvironmentVariable("SIM_BOARD");
if (!string.IsNullOrEmpty(initial) && JsonNode.Parse(initial) is JsonObject json) Update(json);
}
/// <summary>平台内部使用:应用服务器推送的 {"analog":[…],"digital":[…],"clock":…,"wiring":{…}}(clock、wiring 不带时表示不变)</summary>
public static void Update(JsonObject json)
{
if (json.ContainsKey("clock")) Sim.Host.SimClock.Update(json["clock"]);
lock (Lock)
{
if (json["analog"] is JsonArray analog)
for (var i = 0; i < analog.Count && i < _analog.Length; i++) _analog[i] = (int?)analog[i] ?? 0;
if (json["digital"] is JsonArray digital)
for (var i = 0; i < digital.Count && i < _digital.Length; i++) _digital[i] = (bool?)digital[i] ?? false;
if (json["wiring"] is JsonObject wiring)
foreach (var (device, port) in wiring)
if (Wiring.ContainsKey(device) && port is not null) Wiring[device] = (string)port!;
}
}
/// <summary>
/// 程序打开的串口上有没有接这台设备。和真机一样,串口打开错了不报错,只是设备收不到命令、也不回应。
/// Windows 的串口名不分大小写
/// </summary>
internal static bool Reaches(string device, string? portName)
{
if (string.IsNullOrWhiteSpace(portName)) return false;
lock (Lock) return Wiring.TryGetValue(device, out var port) && string.Equals(port, portName.Trim(), StringComparison.OrdinalIgnoreCase);
}
internal static int ReadAnalog(int channel)
{
lock (Lock) return channel >= 0 && channel < _analog.Length ? _analog[channel] : 0;
}
internal static bool ReadDigital(int channel)
{
lock (Lock) return channel >= 0 && channel < _digital.Length && _digital[channel];
}
}