using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using detect.device; using detect.gui.Models.Entities; using detect.gui.Services.Detect; using Serilog; using Splat; namespace detect.gui.Services; public class DeviceClientService { private readonly IDictionary _deviceClients = new Dictionary(); public DeviceClientService() { ConnectAllDevices(); Log.Information("DeviceClientService Initialize Done."); } private static DeviceClientService? _instance; public static DeviceClientService Instance() { return _instance ??= new DeviceClientService(); } /// /// 连接所有设备 /// public void ConnectAllDevices() { var deviceService = Locator.Current.GetService()!; var devices = deviceService.ListAll().Result!; if (devices.Any()) { devices.ForEach(device => { ConnectDevice(device); }); } } /// /// 断开所有连接 /// public void DisConnectAllDevices() { foreach (var (key, client) in _deviceClients) { client.DisConnectAsync(); } } /// /// 根据设备id获取连接客户端 /// /// /// public IDeviceClient? GetDeviceClient(long deviceId) { _deviceClients.TryGetValue(deviceId, out var deviceClient); return deviceClient; } /// /// 刷新连接客户端,设备信息更新后调用 /// /// /// public IDeviceClient? RefreshDeviceClientById(long deviceId) { _deviceClients.TryGetValue(deviceId, out var deviceClient); deviceClient?.DisConnectAsync(); var eventService = Locator.Current.GetService()!; return ConnectDevice(eventService.ListById(deviceId).Result!); } public IDeviceClient? RefreshDeviceClientBySn(string deviceSn) { var device = Locator.Current.GetService()!.ListBySn(deviceSn).Result!; _deviceClients.TryGetValue(device.Id!.Value, out var deviceClient); deviceClient?.DisConnectAsync(); return ConnectDevice(device); } /// /// 刷新连接客户端,设备信息更新后调用 /// /// /// public IDeviceClient? RefreshDeviceClient(DeviceEntity device) { _deviceClients.TryGetValue(device.Id!.Value, out var deviceClient); deviceClient?.DisConnectAsync(); return ConnectDevice(device); } /// /// 断开连接并释放 /// /// /// public void DeleteDeviceClientById(long deviceId) { _deviceClients.TryGetValue(deviceId, out var deviceClient); deviceClient?.DisConnectAsync(); _deviceClients.Remove(deviceId); } /// /// 连接云台设备 /// /// /// public IDeviceClient? ConnectDevice(DeviceEntity device) { if (string.IsNullOrEmpty(device.DeviceIp)) { Log.Warning("设备【{Name}】没有配置ip,不连接", device.Name); return null; } _deviceClients.TryGetValue(device.Id!.Value, out var deviceClient); if (deviceClient == null) { deviceClient = new DeviceClientSocket(device.DeviceIp!, 13000); deviceClient.ConnectAsync(); _deviceClients.Add(device.Id!.Value, deviceClient); } else { if (!deviceClient.Connected()) { deviceClient.ConnectAsync(); } } deviceClient.DeviceEvent += DeviceClientOnDeviceEvent; return deviceClient; } private void DeviceClientOnDeviceEvent(object? sender, DeviceEvent e) { Log.Information("DeviceEvent-[{Name}]-{Address}:{@Result}", e.Name, (sender as DeviceClientSocket)!.Address, e.Result); if (e.Name == DeviceEvent.EventDeviceConnected) { // var sysInfo = GetDeviceInfo(1).GetAwaiter().GetResult(); // Log.Information("device info: {@Info}", sysInfo); // test // AssignTasks(new long[] { 1 }).GetAwaiter(); } // var deviceService = Locator.Current.GetService()!; // var eventService = Locator.Current.GetService()!; // var constantService = Locator.Current.GetService()!; // var deviceClient = sender as DeviceClientSocket; // var device = deviceService.ListByDeviceIp(deviceClient!.Address).Result!; // var eventEntity = new EventEntity // { // RegionId = device.RegionId, // DeviceId = device.Id, // Code = e.Result["alarmType"] as string, // AlarmLevel = "INFO", // ImageUrl = $"http://{device.DeviceIp}:8000/{e.Result["image"] as string}", // EventTime = DateTime.Parse((e.Result["datetime"] as string)!) // }; // if (eventEntity.ImageUrl.StartsWith("http")) // { // var constant = constantService.ListOne(code: VapConstantService.EVENT_DATA_SAVE_PATH).Result; // var savePath = Path.Join(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), // "aivap/event"); // if (constant != null) // { // savePath = constant.Value; // } // savePath = Path.Join(savePath, eventEntity.DeviceId.ToString()); // if (!Directory.Exists(savePath)) // { // Directory.CreateDirectory(savePath!); // } // var filename = eventEntity.ImageUrl.Split("/").Last(); // var filePath = Path.Join(savePath!, filename); // try // { // FileUtil.DownloadFileAsync(eventEntity.ImageUrl, filePath).GetAwaiter().GetResult(); // Log.Information("事件图片下载完成:{path}", filePath); // eventEntity.ImageUrl = new FileInfo(filePath).FullName; // } // catch (Exception ex) // { // Log.Error(ex, "事件图片下载完成:{Error}", ex.Message); // } // } // eventService.AddData(eventEntity); } #region 业务方法 /// /// 查询设备信息 /// /// /// /// public async Task?> GetDeviceInfo(long deviceId) { var deviceClient = GetDeviceClient(deviceId); if (deviceClient == null) { throw new Exception("设备未连接!"); } var req = DeviceClientRequestBuilder.Create().WithType("service").WithComponent("_database") .WithMethod("system_info"); var resp = await deviceClient.RequestAction>(req); if (resp.IsFailed) { throw new Exception(resp.Message); } return resp.Result; } public async Task?> AssignTasks(long[] taskIds) { var taskService = Locator.Current.GetService()!; var deviceService = Locator.Current.GetService()!; var taskList = taskService.ListByIds(taskIds).Result!; if (taskList.Count == 0) { throw new Exception("未选择需要下发的任务!"); } var deviceSn = taskList[0].DeviceSn!; var device = deviceService.ListBySn(deviceSn).Result!; if (device == null) { throw new Exception("未找到设备!"); } var deviceClient = GetDeviceClient(device.Id!.Value); if (deviceClient == null) { throw new Exception("设备未连接!"); } if (!deviceClient.Connected()) { throw new Exception("设备连接失败!"); } var req = DeviceClientRequestBuilder.Create().WithType("service").WithComponent("dat_task") .WithMethod("add_server_tasks").WithParam("tasks", taskList); var resp = await deviceClient.RequestAction>(req); if (resp.IsFailed) { throw new Exception(resp.Message); } return resp.Result; } public async Task SyncTasks(long[] taskIds) { var taskService = Locator.Current.GetService()!; var deviceService = Locator.Current.GetService()!; var taskList = taskService.ListByIds(taskIds).Result!; if (taskList.Count == 0) { throw new Exception("未选择需要同步的任务!"); } var deviceSn = taskList[0].DeviceSn!; var device = deviceService.ListBySn(deviceSn).Result!; if (device == null) { throw new Exception("未找到设备!"); } var deviceClient = GetDeviceClient(device.Id!.Value); if (deviceClient == null) { throw new Exception("设备未连接!"); } if (!deviceClient.Connected()) { throw new Exception("设备连接失败!"); } foreach (var task in taskList) { var req = DeviceClientRequestBuilder.Create().WithType("service").WithComponent("dat_task") .WithMethod("sync_client_tasks").WithParam("device_id", task.Id!.Value) .WithParam("device_sn", task.DeviceSn!); var resp = await deviceClient.RequestAction>(req); if (resp.IsFailed) { throw new Exception(resp.Message); } if (resp.Result is null) continue; task.ResultJson = (string?)resp.Result!["result_json"]; task.StartTime = Convert.ToDateTime(resp.Result!["start_time"]) == DateTime.MinValue ? null : Convert.ToDateTime(resp.Result!["start_time"]); task.EndTime = Convert.ToDateTime(resp.Result!["end_time"]) == DateTime.MinValue ? null : Convert.ToDateTime(resp.Result!["end_time"]); task.State = Convert.ToInt32((long)resp.Result!["state"]); Locator.Current.GetService()!.UpdateData(task); } } public Task?> GetDeviceConnected() { var r = new Dictionary(); var deviceService = Locator.Current.GetService()!; var devices = deviceService.ListAll().Result!; if (devices.Count != 0) { devices.ForEach(device => { _deviceClients.TryGetValue(device.Id!.Value, out var deviceClient); if (device.DeviceSn != null) r.Add(device.DeviceSn, deviceClient != null && deviceClient.Connected()); }); } return Task.FromResult(r.Count == 0 ? null : r); } // public Task RefreshDevice(long deviceId) // { // RefreshDeviceClientById(deviceId); // return Task.FromResult(""); // } #endregion }