diff --git a/labs/LCDAUE800DDebug/Properties/PublishProfiles/FolderProfile.pubxml b/labs/LCDAUE800DDebug/Properties/PublishProfiles/FolderProfile.pubxml new file mode 100644 index 00000000..0b51a17d --- /dev/null +++ b/labs/LCDAUE800DDebug/Properties/PublishProfiles/FolderProfile.pubxml @@ -0,0 +1,18 @@ + + + + + Release + Any CPU + bin\Release\net5.0\publish\ + FileSystem + net5.0 + win-x64 + true + True + False + False + + \ No newline at end of file diff --git a/projects/IoT.Shared/IoTSharedDbConfig.cs b/projects/IoT.Shared/IoTSharedDbConfig.cs index 28e98232..cededd06 100644 --- a/projects/IoT.Shared/IoTSharedDbConfig.cs +++ b/projects/IoT.Shared/IoTSharedDbConfig.cs @@ -48,27 +48,6 @@ namespace IoT.Shared modelBuilder.Entity().HasOne(o => o.Scene).WithMany(o => o.SceneTimers).HasForeignKey(o => o.SceneId); modelBuilder.Entity().HasOne(o => o.Scene).WithMany(o => o.SceneTiggers).HasForeignKey(o => o.SceneId); modelBuilder.Entity().HasOne(o => o.Data).WithMany(o => o.Tiggers).HasForeignKey(o => o.DataId); - // - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - ; - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); - modelBuilder.Ignore(); } public static void Seed(DbContext db) diff --git a/projects/IoTCenter/Api/ApiController.cs b/projects/IoTCenter/Api/ApiController.cs index a76cc20e..3f95a145 100644 --- a/projects/IoTCenter/Api/ApiController.cs +++ b/projects/IoTCenter/Api/ApiController.cs @@ -1,11 +1,15 @@ using Application.Domain.Entities; using Application.Models; +using Hangfire; +using Hangfire.Storage; using Infrastructure.Application.Services.Settings; using Infrastructure.Data; +using Infrastructure.Extensions; using IoTCenter.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using System; using System.ComponentModel.DataAnnotations; @@ -19,18 +23,19 @@ namespace IoTCenter.Api.Controllers [ApiController] public class ApiController : ControllerBase { + private readonly IConfiguration _cfg; private readonly ISettingService _settingService; private readonly ILogger _logger; private readonly IRepository _sceneRepo; private readonly IRepository _sceneCommandRepo; private readonly IRepository _organSceneRepo; private readonly IRepository _organSceneCommandRepo; - private readonly IRepository _sceneTimerRepo; + private readonly IRepository _organSceneTimerRepo; private readonly IRepository _commandRepo; private readonly IRepository _deviceRepo; private readonly IHubContext _hub; - public ApiController( + public ApiController(IConfiguration cfg, ISettingService settingService, ILogger logger, IRepository sceneRepo, @@ -42,12 +47,13 @@ namespace IoTCenter.Api.Controllers IRepository deviceRepo, IHubContext hub) { + this._cfg = cfg; this._settingService = settingService; this._logger = logger; this._sceneRepo = sceneRepo; this._organSceneRepo = organSceneRepo; this._organSceneCommandRepo = organSceneCommandRepo; - this._sceneTimerRepo = sceneTimerRepo; + this._organSceneTimerRepo = sceneTimerRepo; this._sceneCommandRepo = sceneCommandRepo; this._commandRepo = commandRepo; this._deviceRepo = deviceRepo; @@ -162,47 +168,35 @@ namespace IoTCenter.Api.Controllers } } - /// - /// job server call back - /// - /// - /// [HttpPost] - [Route("{id}")] - public ActionResult ExecTimer([Required(ErrorMessage = nameof(RequiredAttribute))] Guid id) + public IActionResult UpdateTimer() { - try + using var conn = JobStorage.Current.GetConnection(); + var jobs = conn.GetRecurringJobs(); + foreach (var job in jobs) + { + RecurringJob.RemoveIfExists(job.Id); + } + var timers = this._organSceneTimerRepo.ReadOnlyTable().ToList(); + foreach (var timer in timers) { - this._logger.LogDebug($"global timer exec:{id}"); - var timer = this._sceneTimerRepo.ReadOnlyTable() - .Include(o => o.OrganScene).ThenInclude(o => o.OrganSceneCommands).ThenInclude(o => o.Command).ThenInclude(o => o.Device).ThenInclude(o => o.Node) - .FirstOrDefault(o => o.Id == id); - if (timer != null) + try { - foreach (var sceneCommand in timer.OrganScene.OrganSceneCommands.OrderBy(o => o.Command.DisplayOrder)) - { - try - { - this._hub.ServerToClient(Methods.ExecCommand, sceneCommand.CommandId, sceneCommand.Command.Device.Node.Number, null); - Delay(sceneCommand.Command.Delay); - } - catch (Exception ex) - { - this._logger.LogError(ex.ToString()); - } - } + RecurringJob.AddOrUpdate(timer.Id.ToString(), () => Handle(timer.Id), timer.Cron, TimeZoneInfo.Local); } - else + catch (Exception ex) { - this._logger.LogError($"timer {id} does not exist"); + ex.PrintStack(); + this._logger.LogError(ex.ToString()); } - return Ok(); - } - catch (Exception ex) - { - this._logger.LogError(ex.ToString()); - return Problem(ex.Message); } + return Ok(); + } + + [ApiExplorerSettings(IgnoreApi = true)] + public void Handle(Guid id) + { + IoTCenterEventHandler.GlobalTimerExec(_logger, _settingService, _organSceneTimerRepo, _hub, id); } private void CallApi(string connectionId, string number, string method, string query) diff --git a/projects/IoTCenter/Api/ProductController.cs b/projects/IoTCenter/Api/ProductController.cs index e32335ec..f0c2038e 100644 --- a/projects/IoTCenter/Api/ProductController.cs +++ b/projects/IoTCenter/Api/ProductController.cs @@ -43,6 +43,7 @@ namespace IoTCenter.Api.Controllers o.Product.Id, o.Product.Name, o.Product.Number, + o.Product.Image, o.Product.DisplayOrder }) .Select(o => new @@ -50,6 +51,7 @@ namespace IoTCenter.Api.Controllers o.Key.Id, o.Key.Name, o.Key.Number, + o.Key.Image, o.Key.DisplayOrder, Count = o.Count() }) diff --git a/projects/IoTCenter/Api/SiteController.cs b/projects/IoTCenter/Api/SiteController.cs index 44892abd..92ba9acb 100644 --- a/projects/IoTCenter/Api/SiteController.cs +++ b/projects/IoTCenter/Api/SiteController.cs @@ -1,18 +1,14 @@ using Application.Domain.Entities; -using Hangfire; -using Hangfire.Storage; using Infrastructure.Application.Services.Settings; using Infrastructure.Data; using Infrastructure.Extensions; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Text; namespace IoTCenter.Api.Controllers { @@ -85,50 +81,5 @@ namespace IoTCenter.Api.Controllers return Problem(ex.Message); } } - - [HttpPost] - public IActionResult UpdateTimer() - { - using var conn = JobStorage.Current.GetConnection(); - var jobs = conn.GetRecurringJobs(); - foreach (var job in jobs) - { - RecurringJob.RemoveIfExists(job.Id); - } - var timers = this._organSceneTimerRepo.ReadOnlyTable().ToList(); - foreach (var timer in timers) - { - var url = _cfg.GetConnectionString("JobServer") + $"/RecurringJob/AddOrUpdate"; - var data = new - { - timer.Id, - url = $"{_cfg.GetConnectionString("JobCallBack")}/{timer.Id}", - cron = timer.Cron - }; - try - { - this._logger.LogDebug($"update job server"); - var client = _httpClientFactory.CreateClient(); - using var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"); - var result = client.PostAsync(url, content).Result; - this._logger.LogDebug($"{result.StatusCode}:{result.Content.ReadAsStringAsync().Result}"); - } - catch (Exception ex) - { - ex.PrintStack(); - this._logger.LogError(ex.ToString()); - } - } - return Ok(); - } - - private void RemoveJobs() - { - var client = _httpClientFactory.CreateClient(); - var url = _cfg.GetConnectionString("JobServer") + $"/RecurringJob/RemoveAll"; - using var content = new StringContent("", Encoding.UTF8, "application/json"); - var result = client.PostAsync(url, content).Result; - this._logger.LogDebug($"{result.StatusCode}:{result.Content.ReadAsStringAsync().Result}"); - } } } \ No newline at end of file diff --git a/projects/IoTCenter/IoTCenter.csproj b/projects/IoTCenter/IoTCenter.csproj index 28cda419..61d486ff 100644 --- a/projects/IoTCenter/IoTCenter.csproj +++ b/projects/IoTCenter/IoTCenter.csproj @@ -4,7 +4,7 @@ Zh-CN true true - 1.0.0.2 + 1.0.0.3 ..\docker-compose.dcproj Linux diff --git a/projects/IoTCenter/Services/IoTCenterEventHandler.cs b/projects/IoTCenter/Services/IoTCenterEventHandler.cs index 3eb84964..a9d343d7 100644 --- a/projects/IoTCenter/Services/IoTCenterEventHandler.cs +++ b/projects/IoTCenter/Services/IoTCenterEventHandler.cs @@ -1,5 +1,6 @@ using Application.Domain.Entities; using Application.Models; +using Hangfire; using Infrastructure.Application.Services.Settings; using Infrastructure.Data; using Infrastructure.Events; @@ -11,12 +12,10 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; using Vibrant.InfluxDB.Client; @@ -62,6 +61,7 @@ namespace IoTCenter.Services private readonly IRepository _organRepo; private readonly IRepository _organNodeRepo; private readonly IRepository _deviceRepo; + private readonly IRepository _organSceneTimerRepo; private readonly IRepository _sceneTiggerRepo; private readonly ISceneTiggerService _sceneTiggerService; private readonly IHubContext _hub; @@ -76,6 +76,7 @@ namespace IoTCenter.Services IRepository organRepo, IRepository organNodeRepo, IRepository deviceRepo, + IRepository organSceneTimerRepo, IRepository sceneTiggerRepo, ISceneTiggerService sceneTiggerService, IHubContext hub, @@ -90,6 +91,7 @@ namespace IoTCenter.Services this._organRepo = organRepo; this._organNodeRepo = organNodeRepo; this._deviceRepo = deviceRepo; + this._organSceneTimerRepo = organSceneTimerRepo; this._sceneTiggerRepo = sceneTiggerRepo; this._sceneTiggerService = sceneTiggerService; this._hub = hub; @@ -101,34 +103,19 @@ namespace IoTCenter.Services public void Handle(EntityInsertedEvent message) { var timer = message.Data; - var url = _cfg.GetConnectionString("JobServer") + "/RecurringJob/AddOrUpdate"; - var id = timer.Id.ToString(); - this.UpdateJobServer(url, new - { - id, - url = $"{_cfg.GetConnectionString("JobCallBack")}/{id}", - cron = timer.Cron - }); + RecurringJob.AddOrUpdate(timer.Id.ToString(), () => Handle(timer.Id), timer.Cron, TimeZoneInfo.Local); } public void Handle(EntityUpdatedEvent message) { var timer = message.Data; - var url = _cfg.GetConnectionString("JobServer") + "/RecurringJob/AddOrUpdate"; - var id = timer.Id.ToString(); - this.UpdateJobServer(url, new - { - id, - url = $"{_cfg.GetConnectionString("JobCallBack")}/{id}", - cron = timer.Cron - }); + RecurringJob.AddOrUpdate(timer.Id.ToString(), () => Handle(timer.Id), timer.Cron, TimeZoneInfo.Local); } public void Handle(EntityDeletedEvent message) { var timer = message.Data; - var url = _cfg.GetConnectionString("JobServer") + $"/RecurringJob/Remove/{timer.Id}"; - this.UpdateJobServer(url); + RecurringJob.RemoveIfExists(timer.Id.ToString()); } #endregion timer @@ -290,23 +277,6 @@ namespace IoTCenter.Services #endregion Scene - private void UpdateJobServer(string url, object data = null) - { - try - { - this._logger.LogDebug($"update job server"); - var client = _httpClientFactory.CreateClient(); - using var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"); - var result = client.PostAsync(url, content).Result; - this._logger.LogDebug($"{result.StatusCode}:{result.Content.ReadAsStringAsync().Result}"); - } - catch (Exception ex) - { - ex.PrintStack(); - this._logger.LogError(ex.ToString()); - } - } - private void TiggerHandle(BaseEvent message) { try @@ -366,7 +336,7 @@ namespace IoTCenter.Services try { this._hub.ServerToClient(Methods.ExecCommand, sceneCommand.CommandId, sceneCommand.Command.Device.Node.Number, null); - Delay(sceneCommand.Command.Delay); + Delay(_settingService, sceneCommand.Command.Delay); } catch (Exception ex) { @@ -444,27 +414,6 @@ namespace IoTCenter.Services }; } - private void Delay(int commandDelay) - { - var delay = 0; - try - { - delay = Convert.ToInt32(this._settingService.GetSetting("delay").Value); - } - catch (Exception ex) - { - this._logger.LogError(ex.ToString()); - } - if (commandDelay > 0) - { - delay += commandDelay; - } - if (delay > 0) - { - Thread.Sleep(delay); - } - } - public void Handle(NodeClientConnectedEvent message) { var organ = this._organRepo.Table().FirstOrDefault(o => o.Number == message.OrganNumber); @@ -489,5 +438,59 @@ namespace IoTCenter.Services } } } + + public void Handle(Guid id) + { + GlobalTimerExec(_logger, _settingService, _organSceneTimerRepo, _hub, id); + } + + public static void GlobalTimerExec(ILogger _logger, ISettingService _settingService, IRepository _organSceneTimerRepo, IHubContext _hub, Guid id) + { + try + { + _logger.LogInformation($"global timer exec at {DateTime.Now.ToString("G")}:{id}"); + var timer = _organSceneTimerRepo.ReadOnlyTable() + .Include(o => o.OrganScene).ThenInclude(o => o.OrganSceneCommands).ThenInclude(o => o.Command).ThenInclude(o => o.Device).ThenInclude(o => o.Node) + .FirstOrDefault(o => o.Id == id); + if (timer != null) + { + foreach (var sceneCommand in timer.OrganScene.OrganSceneCommands.OrderBy(o => o.Command.DisplayOrder)) + { + try + { + _hub.ServerToClient(Methods.ExecCommand, sceneCommand.CommandId, sceneCommand.Command.Device.Node.Number, null); + Delay(_settingService, sceneCommand.Command.Delay); + } + catch (Exception ex) + { + _logger.LogError(ex.ToString()); + } + } + } + else + { + _logger.LogError($"timer {id} does not exist"); + } + } + catch (Exception ex) + { + _logger.LogError(ex.ToString()); + } + } + + public static void Delay(ISettingService _settingService, int delay) + { + if (int.TryParse(_settingService.GetSetting("delay").Value, out int commandDelay)) + { + if (commandDelay > 0) + { + delay += commandDelay; + } + } + if (delay > 0) + { + Thread.Sleep(delay); + } + } } } \ No newline at end of file diff --git a/projects/IoTCenter/appsettings.Development.json b/projects/IoTCenter/appsettings.Development.json index 89be7064..5a3c896b 100644 --- a/projects/IoTCenter/appsettings.Development.json +++ b/projects/IoTCenter/appsettings.Development.json @@ -12,8 +12,6 @@ "mysql": "Server=localhost;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;", "HangfireConnection": "Server=localhost;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;", "redis": "localhost:6379,password=aA123456!,allowAdmin=true", - "srs": "http://localhost:1985", - "JobServer": "http://localhost/JobServer", - "JobCallBack": "http://localhost/IoTCenter/api/v1/Api/ExecTimer" + "srs": "http://localhost:1985" } } \ No newline at end of file diff --git a/projects/IoTCenter/appsettings.Docker.json b/projects/IoTCenter/appsettings.Docker.json index 5c32a172..e2790d8a 100644 --- a/projects/IoTCenter/appsettings.Docker.json +++ b/projects/IoTCenter/appsettings.Docker.json @@ -7,9 +7,7 @@ "mysql": "Server=172.172.0.30;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;", "HangfireConnection": "Server=172.172.0.30;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;", "redis": "172.172.0.40:6379,password=aA123456!,allowAdmin=true", - "srs": "http://172.172.0.60:1985", - "JobServer": "http://172.172.0.12/JobServer", - "JobCallBack": "http://172.172.0.12/IoTCenter/api/v1/Api/ExecTimer" + "srs": "http://172.172.0.60:1985" }, "influxdb": { "url": "http://172.172.0.50:8086", diff --git a/projects/IoTCenter/appsettings.json b/projects/IoTCenter/appsettings.json index a39048a0..71469c01 100644 --- a/projects/IoTCenter/appsettings.json +++ b/projects/IoTCenter/appsettings.json @@ -61,9 +61,7 @@ "mysql": "Server=mysql;Port=3306;Database=iotcenter;Uid=root;Pwd=aA123456!;", "HangfireConnection": "Server=mysql;Port=3306;Database=jobserver;Uid=root;Pwd=aA123456!;Allow User Variables=True;", "redis": "redis:6379,password=aA123456!,allowAdmin=true", - "srs": "http://srs:1985", - "JobServer": "http://jobserver/JobServer", - "JobCallBack": "http://iotcenter/IoTCenter/api/v1/Api/ExecTimer" + "srs": "http://srs:1985" }, "AppSettings": { "database": "mysql", diff --git a/projects/IoTNode/DbConfig.cs b/projects/IoTNode/DbConfig.cs index 4fa998df..2d25b3c6 100644 --- a/projects/IoTNode/DbConfig.cs +++ b/projects/IoTNode/DbConfig.cs @@ -34,6 +34,25 @@ namespace IoTNode public void OnModelCreating(ModelBuilder modelBuilder) { IoTSharedDbConfig.OnModelCreating(modelBuilder); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); + modelBuilder.Ignore(); } public void Seed(DbContext db) diff --git a/projects/WebMVC/wwwroot/routes/admin/index.html b/projects/WebMVC/wwwroot/routes/admin/index.html index 33638f15..046bfc4a 100644 --- a/projects/WebMVC/wwwroot/routes/admin/index.html +++ b/projects/WebMVC/wwwroot/routes/admin/index.html @@ -61,7 +61,7 @@ }); }, updateTimer: function () { - axios.post(this.baseUrl + '/IoTCenter/api/v1/site/UpdateTimer') + axios.post(this.baseUrl + '/IoTCenter/api/v1/api/UpdateTimer') .then(function (response) { Swal.fire({ title: '操作完成', timer: 1500 }); }) diff --git a/projects/WebMVC/wwwroot/routes/admin/system.html b/projects/WebMVC/wwwroot/routes/admin/system.html index 44492be4..3137b7fd 100644 --- a/projects/WebMVC/wwwroot/routes/admin/system.html +++ b/projects/WebMVC/wwwroot/routes/admin/system.html @@ -20,7 +20,7 @@ }, methods: { updateTimer: function () { - axios.post(this.baseUrl + '/IoTCenter/api/v1/site/UpdateTimer') + axios.post(this.baseUrl + '/IoTCenter/api/v1/api/UpdateTimer') .then(function (response) { Swal.fire({ title: '操作完成', timer: 1500 }); }) diff --git a/projects/docker-compose.yml b/projects/docker-compose.yml index 0ca70194..acf715a7 100644 --- a/projects/docker-compose.yml +++ b/projects/docker-compose.yml @@ -125,15 +125,6 @@ services: - mysql - redis - #定时任务 - jobserver: - image: ${DOCKER_REGISTRY-}jobserver - build: - context: . - dockerfile: JobServer/Dockerfile - depends_on: - - mysql - #docker管理 portainer: image: portainer/portainer:1.24.1 diff --git a/publish/build.ps1 b/publish/build.ps1 index 9849febf..34174c06 100644 --- a/publish/build.ps1 +++ b/publish/build.ps1 @@ -29,7 +29,6 @@ Copy-Item ../projects/WebMVC/wwwroot/* ./dist/linux-x64/publish/apps/WebMVC/www Copy-Item ../projects/WebSPA/wwwroot/* ./dist/linux-x64/publish/apps/WebSPA/wwwroot -recurse dotnet publish ../projects/UserCenter/UserCenter.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -o ../publish/dist/linux-x64/publish/apps/UserCenter -dotnet publish ../projects/JobServer/JobServer.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -o ../publish/dist/linux-x64/publish/apps/JobServer dotnet publish ../projects/IoTCenter/IoTCenter.csproj -c Release -r linux-x64 -p:PublishSingleFile=true -o ../publish/dist/linux-x64/publish/apps/IoTCenter diff --git a/publish/src/linux-x64/publish/docker-compose.prod.yml b/publish/src/linux-x64/publish/docker-compose.prod.yml index 9bbb32bd..ddb4768c 100644 --- a/publish/src/linux-x64/publish/docker-compose.prod.yml +++ b/publish/src/linux-x64/publish/docker-compose.prod.yml @@ -38,20 +38,3 @@ services: networks: default: ipv4_address: 172.172.0.80 - jobserver: - image: mcr.microsoft.com/dotnet/core/runtime-deps:3.1-focal - restart: always - environment: - - TZ=Asia/Shanghai - - ASPNETCORE_ENVIRONMENT=Docker - command: bash -c "sleep 3 && chmod +x /JobServer/JobServer && cd /JobServer && ./JobServer" - depends_on: - - mysql - ports: - - 8013:80 - volumes: - - ./apps/JobServer:/JobServer - - ./docker/log/JobServer:/JobServer/logs - networks: - default: - ipv4_address: 172.172.0.90