Dynamics 365 CRM 在 Connected Field Service 中部署 IoT Central (二)- 匹配设备

本篇博客详细介绍如何在CRM系统中注册IoT设备。通过选择相应设备并赋予其账户和类别,实现IoT设备的有效管理和监控,为物联网应用提供坚实的基础。

上个blog中介绍了我们怎么去部署IoT central和 connected field service做连接。

 

我们这次介绍怎么把IoT设备在CRM中怎么去注册。

 

 

首先我们打开devices,再选中相应的显示的设备。

 

 

我们把相应的account 和 category赋予给设备。

 

Nano-ESG数据资源库的构建基于2023年初至2024年秋季期间采集的逾84万条新闻文本,从中系统提炼出企业环境、社会及治理维度的信息。其构建流程首先依据特定术语在德语与英语新闻平台上检索,初步锁定与德国DAX 40成分股企业相关联的报道。随后借助嵌入技术对文本段落执行去重操作,以降低内容冗余。继而采用GLiNER这一跨语言零样本实体识别系统,排除与目标企业无关的文档。在此基础上,通过GPT-3.5与GPT-4o等大规模语言模型对文本进行双重筛选:一方面判定其与ESG议题的相关性,另一方面生成简明的内容概要。最终环节由GPT-4o模型完成,它对每篇文献进行ESG情感倾向(正面、中性或负面)的判定,并标注所涉及的ESG具体维度,从而形成具备时序特征的ESG情感与维度标注数据集。 该数据集适用于多类企业可持续性研究,例如ESG情感趋势分析、ESG维度细分类别研究,以及企业可持续性事件的时序演变追踪。研究者可利用数据集内提供的新闻摘要、情感标签与维度分类,深入考察企业在不同时期的环境、社会及治理表现。此外,借助Bertopic等主题建模方法,能够从数据中识别出与企业相关的核心ESG议题,并观察这些议题随时间的演进轨迹。该资源以其开放获取特性与连续的时间覆盖,为探究企业可持续性表现的动态变化提供了系统化的数据基础。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
<think> 我们使用Fluxor实现IoT设备离线状态检测和重连机制,主要思路如下: 1. 在状态中记录每个设备的最后活跃时间 2. 定时检查设备状态(通过最后活跃时间判断是否离线) 3. 当检测到设备离线时,触发离线状态更新 4. 对于离线设备,启动重连机制(如定时重连) 我们将扩展之前的IoT状态,添加设备连接状态和最后活跃时间。 同时,我们将创建新的Action和Effect来处理连接状态的更新和重连逻辑。 步骤: 1. 扩展状态,添加设备连接状态(在线/离线)和最后活跃时间 2. 定义新的Action:DeviceOnlineAction, DeviceOfflineAction, CheckDeviceStatusAction, ReconnectDeviceAction 3. 在Reducer中处理设备状态变更 4. 创建定时器Effect来定期检查设备状态 5. 在数据到达时(UpdateSensorDataAction)更新设备的最后活跃时间 6. 实现重连机制(如MQTT断开重连) 注意:对于MQTT客户端本身的连接状态(与服务器的连接),我们单独处理。 代码实现如下: </think> # 在 Fluxor 中实现 IoT 设备离线状态检测和重连机制 以下是使用 Fluxor 实现 IoT 设备离线检测和自动重连的完整解决方案,包含实时状态监控、智能重连策略和故障恢复机制。 ## 核心状态设计 ```csharp [FeatureState] public class IoTConnectionState { // 单个设备连接状态 public record DeviceStatus( string DeviceId, DateTime LastSeen, bool IsOnline, ConnectionStatus Status, int ReconnectAttempts = 0) { // 计算离线时间(分钟) public double OfflineMinutes => IsOnline ? 0 : (DateTime.UtcNow - LastSeen).TotalMinutes; } public enum ConnectionStatus { Connected, Connecting, Disconnected, Error } // 所有设备状态字典 public ImmutableDictionary<string, DeviceStatus> DeviceStatuses { get; init; } = ImmutableDictionary<string, DeviceStatus>.Empty; // 全局连接状态 public ConnectionStatus MqttConnectionStatus { get; init; } = ConnectionStatus.Disconnected; // 最后错误信息 public string? LastError { get; init; } } ``` ## 动作定义 ```csharp public class DeviceConnectedAction { public string DeviceId { get; } public DeviceConnectedAction(string deviceId) => DeviceId = deviceId; } public class DeviceDisconnectedAction { public string DeviceId { get; } public DeviceDisconnectedAction(string deviceId) => DeviceId = deviceId; } public class MqttConnectedAction {} public class MqttDisconnectedAction { public string? Reason { get; init; } } public class MqttConnectingAction {} public class MqttErrorAction { public string Error { get; init; } = string.Empty; } public class CheckDeviceStatusAction {} public class ReconnectDevicesAction {} public class ReconnectMqttAction {} ``` ## Reducer 实现 ```csharp public static class IoTConnectionReducers { // 设备连接状态更新 [ReducerMethod] public static IoTConnectionState OnDeviceConnected( IoTConnectionState state, DeviceConnectedAction action) { var deviceId = action.DeviceId; var newStatus = state.DeviceStatuses.TryGetValue(deviceId, out var current) ? current with { LastSeen = DateTime.UtcNow, IsOnline = true, ReconnectAttempts = 0 } : new DeviceStatus( deviceId, DateTime.UtcNow, true, IoTConnectionState.ConnectionStatus.Connected); return state with { DeviceStatuses = state.DeviceStatuses.SetItem(deviceId, newStatus) }; } // 设备离线状态更新 [ReducerMethod] public static IoTConnectionState OnDeviceDisconnected( IoTConnectionState state, DeviceDisconnectedAction action) { var deviceId = action.DeviceId; if (!state.DeviceStatuses.TryGetValue(deviceId, out var current)) return state; var newStatus = current with { IsOnline = false, Status = IoTConnectionState.ConnectionStatus.Disconnected }; return state with { DeviceStatuses = state.DeviceStatuses.SetItem(deviceId, newStatus) }; } // MQTT连接状态更新 [ReducerMethod] public static IoTConnectionState OnMqttConnected( IoTConnectionState state, MqttConnectedAction action) => state with { MqttConnectionStatus = IoTConnectionState.ConnectionStatus.Connected }; [ReducerMethod] public static IoTConnectionState OnMqttDisconnected( IoTConnectionState state, MqttDisconnectedAction action) => state with { MqttConnectionStatus = IoTConnectionState.ConnectionStatus.Disconnected, LastError = $"MQTT断开: {action.Reason}" }; [ReducerMethod] public static IoTConnectionState OnMqttConnecting( IoTConnectionState state, MqttConnectingAction action) => state with { MqttConnectionStatus = IoTConnectionState.ConnectionStatus.Connecting }; [ReducerMethod] public static IoTConnectionState OnMqttError( IoTConnectionState state, MqttErrorAction action) => state with { MqttConnectionStatus = IoTConnectionState.ConnectionStatus.Error, LastError = action.Error }; // 设备状态检查(定时触发) [ReducerMethod] public static IoTConnectionState OnCheckDeviceStatus( IoTConnectionState state, CheckDeviceStatusAction action) { var now = DateTime.UtcNow; var updatedStatuses = state.DeviceStatuses; foreach (var (deviceId, status) in state.DeviceStatuses) { // 如果是MQTT断开,所有设备标记为离线 if (state.MqttConnectionStatus != IoTConnectionState.ConnectionStatus.Connected) { updatedStatuses = updatedStatuses.SetItem( deviceId, status with { IsOnline = false }); continue; } // 设备超时检测(5分钟无数据视为离线) if (status.IsOnline && (now - status.LastSeen).TotalMinutes > 5) { updatedStatuses = updatedStatuses.SetItem( deviceId, status with { IsOnline = false }); } } return state with { DeviceStatuses = updatedStatuses }; } } ``` ## 智能重连机制实现 ### 1. 设备状态检测定时器 ```csharp public class DeviceStatusCheckerEffect : IDisposable { private readonly IDispatcher _dispatcher; private readonly Timer _checkTimer; public DeviceStatusCheckerEffect(IDispatcher dispatcher) { _dispatcher = dispatcher; // 每分钟检查一次设备状态 _checkTimer = new Timer(_ => _dispatcher.Dispatch(new CheckDeviceStatusAction()), null, TimeSpan.Zero, TimeSpan.FromMinutes(1)); } public void Dispose() => _checkTimer?.Dispose(); } ``` ### 2. MQTT 连接管理服务 ```csharp public class MqttConnectionManager : IMqttManagedClient, IDisposable { private readonly IMqttClient _mqttClient; private readonly IDispatcher _dispatcher; private readonly ILogger<MqttConnectionManager> _logger; private readonly MqttClientOptions _options; private readonly Timer _reconnectTimer; private int _reconnectDelay = 1000; // 初始重连延迟 public MqttConnectionManager( MqttClientOptions options, IDispatcher dispatcher, ILogger<MqttConnectionManager> logger) { _options = options; _dispatcher = dispatcher; _logger = logger; var factory = new MqttFactory(); _mqttClient = factory.CreateMqttClient(); // 设置事件处理 _mqttClient.ConnectedAsync += OnConnected; _mqttClient.DisconnectedAsync += OnDisconnected; // 重连定时器 _reconnectTimer = new Timer(AttemptReconnect); // 初始连接 ConnectAsync().ConfigureAwait(false); } private async Task OnConnected(MqttClientConnectedEventArgs e) { _logger.LogInformation("MQTT连接成功"); _dispatcher.Dispatch(new MqttConnectedAction()); _reconnectDelay = 1000; // 重置重连延迟 } private async Task OnDisconnected(MqttClientDisconnectedEventArgs e) { _logger.LogWarning("MQTT连接断开: {Reason}", e.Reason); _dispatcher.Dispatch(new MqttDisconnectedAction { Reason = e.Reason.ToString() }); // 指数退避重连策略 if (e.Reason != MqttClientDisconnectReason.NormalDisconnection) {
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值