diff --git a/Libs/CMS_CORE_Library.dll b/Libs/CMS_CORE_Library.dll index 91175856..73f19ca9 100644 Binary files a/Libs/CMS_CORE_Library.dll and b/Libs/CMS_CORE_Library.dll differ diff --git a/Step.Database/Controllers/FunctionsAccessController.cs b/Step.Database/Controllers/FunctionsAccessController.cs index e668ebb4..af1bdc4c 100644 --- a/Step.Database/Controllers/FunctionsAccessController.cs +++ b/Step.Database/Controllers/FunctionsAccessController.cs @@ -71,10 +71,10 @@ namespace Step.Database.Controllers private bool GetIfFunctionalityIsActive(List functionalityList, int id, bool functionAccessIsEnabled) { // If id is not mapped or function is false by database config return - if (id == 0 || !functionAccessIsEnabled) + if (id == -1 || !functionAccessIsEnabled) return functionAccessIsEnabled; // Return PLC data - return functionalityList[id - 1].IsActive; + return functionalityList[id].IsActive; } } } \ No newline at end of file diff --git a/Step.Database/Migrations/Configuration.cs b/Step.Database/Migrations/Configuration.cs index 65e4ad82..8bef0dec 100644 --- a/Step.Database/Migrations/Configuration.cs +++ b/Step.Database/Migrations/Configuration.cs @@ -23,18 +23,17 @@ namespace Step.Database.Migrations // This method will be called after migrating to the latest version. context.Roles.AddOrUpdate( new RoleModel() { RoleId = 1, Level = 10, Name = "Admin" }, - new RoleModel() { RoleId = 2, Level = 1, Name = "Guest" } + new RoleModel() { RoleId = 2, Level = 0, Name = "Guest" } ); context.FunctionsAccess.AddOrUpdate( // General Function - new FunctionAccessModel() { FunctionAccessId = 1, Name = "test", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 7, ReadLevelMin = 1 }, - new FunctionAccessModel() { FunctionAccessId = 2, Name = "functionAccess", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 100, ReadLevelMin = 1 }, - new FunctionAccessModel() { FunctionAccessId = 3, Name = "logout", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1 }, - - // Production function - new FunctionAccessModel() { FunctionAccessId = 4, Name = "userData", Area = AREAS.PRODUCTION_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1 }, - new FunctionAccessModel() { FunctionAccessId = 5, Name = "ncData", Area = AREAS.PRODUCTION_KEY, Enabled = true, WriteLevelMin = 100, ReadLevelMin = 1 } + new FunctionAccessModel() { FunctionAccessId = 1, Name = "functionAccess", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 100, ReadLevelMin = 1, PlcId = -1 }, + new FunctionAccessModel() { FunctionAccessId = 2, Name = "logout", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1, PlcId = -1 }, + new FunctionAccessModel() { FunctionAccessId = 3, Name = "userData", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1, PlcId = -1 }, + new FunctionAccessModel() { FunctionAccessId = 4, Name = "ncData", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 10, ReadLevelMin = 1, PlcId = -1 }, + new FunctionAccessModel() { FunctionAccessId = 5, Name = "startupIcons", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1, PlcId = 0 }, + new FunctionAccessModel() { FunctionAccessId = 6, Name = "alarmCmd", Area = AREAS.GENERAL_KEY, Enabled = true, WriteLevelMin = 1, ReadLevelMin = 1, PlcId = 1} ); context.SaveChanges(); diff --git a/Step.Model/DTOModels/DTOAlarmsModel.cs b/Step.Model/DTOModels/DTOAlarmsModel.cs index 671965ba..0d881ed7 100644 --- a/Step.Model/DTOModels/DTOAlarmsModel.cs +++ b/Step.Model/DTOModels/DTOAlarmsModel.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Step.Model.DTOModels { @@ -30,22 +28,27 @@ namespace Step.Model.DTOModels { var item = obj as DTOAlarmsModel; - if(item == null) + // Object is not a DTOAlarmsModel instance + if (item == null) return false; + // If the numbers of the list's elemets are different, lists are different if (item.NcAlarms.Count != NcAlarms.Count || item.PlcAlarms.Count != this.PlcAlarms.Count || item.ProcessAlarms.Count != this.ProcessAlarms.Count) return false; - bool isEqual = item.NcAlarms.All(NcAlarms.Contains); - if (!isEqual) + // Check list's elements + bool listAreEquals = item.NcAlarms.All(NcAlarms.Contains); + if (!listAreEquals) return false; - isEqual = item.PlcAlarms.All(PlcAlarms.Contains); - if (!isEqual) + // Check list's elements + listAreEquals = item.PlcAlarms.All(PlcAlarms.Contains); + if (!listAreEquals) return false; - - isEqual = item.ProcessAlarms.All(ProcessAlarms.Contains); - if (!isEqual) + + // Check list's elements + listAreEquals = item.ProcessAlarms.All(ProcessAlarms.Contains); + if (!listAreEquals) return false; return true; @@ -61,7 +64,7 @@ namespace Step.Model.DTOModels newAlarms.NcAlarms.Where(x => !NcAlarms.Contains(x as GenericAlarmModel)).ToList() // Find not contained data in the old list ).ToList(); - // Get common data + // Get common data result.PlcAlarms = PlcAlarms.Where(x => newAlarms.PlcAlarms.Contains(x as GenericAlarmModel)).ToList(); // Concat common data + new data result.PlcAlarms = result.PlcAlarms.Concat( @@ -72,12 +75,17 @@ namespace Step.Model.DTOModels result.ProcessAlarms = ProcessAlarms.Where(x => newAlarms.ProcessAlarms.Contains(x as ProcessAlarmModel)).ToList(); // Concat common data + new data in the list - result.ProcessAlarms = result.ProcessAlarms.Concat( + result.ProcessAlarms = result.ProcessAlarms.Concat( newAlarms.ProcessAlarms.Where(x => !ProcessAlarms.Contains(x as ProcessAlarmModel)).ToList() // Find not contained data in the old list ).ToList(); return result; } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } public class GenericAlarmModel @@ -99,6 +107,11 @@ namespace Step.Model.DTOModels else return false; } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } public class ProcessAlarmModel @@ -116,10 +129,15 @@ namespace Step.Model.DTOModels if (item == null) return false; - if (item.process == process && item.id == id ) + if (item.process == process && item.id == id) return true; else return false; } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } -} +} \ No newline at end of file diff --git a/Step.Model/DTOModels/DTOExpiredMaintenanceModel.cs b/Step.Model/DTOModels/DTOExpiredMaintenanceModel.cs index d0b71a60..b74837d7 100644 --- a/Step.Model/DTOModels/DTOExpiredMaintenanceModel.cs +++ b/Step.Model/DTOModels/DTOExpiredMaintenanceModel.cs @@ -6,5 +6,23 @@ namespace Step.Model.DTOModels { public int Id { get; set; } public DateTime ExpirationDate { get; set; } + + public override bool Equals(object obj) + { + var item = obj as DTOExpiredMaintenanceModel; + // Object is not a DTOExpiredMaintenanceModel instance + if (item == null) + return false; + + if (item.Id != Id) + return false; + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } } \ No newline at end of file diff --git a/Step.Model/DTOModels/DTOPowerOnDataModel.cs b/Step.Model/DTOModels/DTOPowerOnDataModel.cs index 6e75f0a3..94ffb6fe 100644 --- a/Step.Model/DTOModels/DTOPowerOnDataModel.cs +++ b/Step.Model/DTOModels/DTOPowerOnDataModel.cs @@ -1,16 +1,36 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static CMS_CORE_Library.DataStructures; +using static CMS_CORE_Library.DataStructures; namespace Step.Model.DTOModels { public class DTOPowerOnDataModel { - public PrePowerOnModel PrePowerOn; - public PostPowerOnModel PostPowerOn; + public PrePowerOnModel PrePowerOn { get; set; } + public PostPowerOnModel PostPowerOn { get; set; } public AxisResetDataModel AxisReset; + + public DTOPowerOnDataModel() + { + PrePowerOn = new PrePowerOnModel(); + PostPowerOn = new PostPowerOnModel(); + AxisReset = new AxisResetDataModel(); + } + + public override bool Equals(object obj) + { + var item = obj as DTOPowerOnDataModel; + // Object is not a DTOPowerOnDataModel instance + if (item == null) + return false; + // If one field is different, objects are different + if (!PrePowerOn.Equals(item.PrePowerOn) || !PostPowerOn.Equals(item.PostPowerOn) || !AxisReset.Equals(item.AxisReset)) + return false; + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } -} +} \ No newline at end of file diff --git a/Step.Model/DTOModels/DTOProcessDataModel.cs b/Step.Model/DTOModels/DTOProcessDataModel.cs index f885c0b2..2b31b5d5 100644 --- a/Step.Model/DTOModels/DTOProcessDataModel.cs +++ b/Step.Model/DTOModels/DTOProcessDataModel.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using static CMS_CORE_Library.DataStructures; namespace Step.Model.DTOModels @@ -17,5 +14,30 @@ namespace Step.Model.DTOModels isRunning = false; processes = new List(); } + + public override bool Equals(object obj) + { + var item = obj as DTOProcessDataModel; + // Object is not a DTOProcessDataModel instance + if (item == null) + return false; + + if (isRunning != item.isRunning) + return false; + // If the numbers of the list's elemets are different, lists are different + if (item.processes.Count != processes.Count) + return false; + // Check list's elements + bool listAreEquals = item.processes.All(processes.Contains); + if (!listAreEquals) + return false; + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } -} +} \ No newline at end of file diff --git a/Step.Model/DTOModels/DTORuntimeFunctionAccessModel.cs b/Step.Model/DTOModels/DTORuntimeFunctionAccessModel.cs index 59672af0..172e0187 100644 --- a/Step.Model/DTOModels/DTORuntimeFunctionAccessModel.cs +++ b/Step.Model/DTOModels/DTORuntimeFunctionAccessModel.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Step.Model.DTOModels +namespace Step.Model.DTOModels { public class DTORuntimeFunctionalityModel { @@ -15,5 +9,23 @@ namespace Step.Model.DTOModels public string Area { get; set; } public bool Enabled { get; set; } + + public override bool Equals(object obj) + { + var item = obj as DTORuntimeFunctionalityModel; + // Object is not a DTORuntimeFunctionalityModel instance + if (item == null) + return false; + + if (Id == item.Id && Enabled == item.Enabled) // Name Area don't change runtime + return true; + else + return false; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } -} +} \ No newline at end of file diff --git a/Step.Model/DatabaseModels/FunctionAccessModel.cs b/Step.Model/DatabaseModels/FunctionAccessModel.cs index 50609600..2ef0c32f 100644 --- a/Step.Model/DatabaseModels/FunctionAccessModel.cs +++ b/Step.Model/DatabaseModels/FunctionAccessModel.cs @@ -9,7 +9,7 @@ namespace Step.Model.DatabaseModels [Key] [Column("id")] public int FunctionAccessId { get; set; } - + [Column("name")] public string Name { get; set; } @@ -27,5 +27,10 @@ namespace Step.Model.DatabaseModels [Column("plc_id")] public int PlcId { get; set; } + + public FunctionAccessModel() + { + PlcId = -1; + } } } \ No newline at end of file diff --git a/Step.Utils/Constants.cs b/Step.Utils/Constants.cs index d9fcb70b..cd4e6b4b 100644 --- a/Step.Utils/Constants.cs +++ b/Step.Utils/Constants.cs @@ -85,7 +85,7 @@ namespace Step.Utils public const string SEND_PROCESSES_DATA = "SEND_PROCESSES_STATUS"; public const string SEND_FUNCTIONALITY_DATA = "SEND_FUNCTION_DATA"; public const string SEND_EXPIRED_MAINTENANCES_DATA = "SEND_EXPIRED_MAINTENANCES_DATA"; - + public const string BROADCAST_DATA = "BROADCAST_DATA"; // ID prefix public const string MAINTENANCE_PREFIX_ID = "MAINT_"; diff --git a/Step/Controllers/SignalR/NcHub.cs b/Step/Controllers/SignalR/NcHub.cs index df1b462d..29969a6e 100644 --- a/Step/Controllers/SignalR/NcHub.cs +++ b/Step/Controllers/SignalR/NcHub.cs @@ -21,6 +21,9 @@ namespace Step.Controllers.SignalR NewConnectedClients = true; ConnectedClients.Add(Context.ConnectionId); + // Resends data to all the clients + MessageServices.Current.Publish(BROADCAST_DATA); + return base.OnConnected(); } @@ -29,6 +32,9 @@ namespace Step.Controllers.SignalR Groups.Add(Context.ConnectionId, "ncData"); NewConnectedClients = true; ConnectedClients.Add(Context.ConnectionId); + // Resends data to all the clients + MessageServices.Current.Publish(BROADCAST_DATA); + return base.OnReconnected(); } diff --git a/Step/Listeners/ListenersHandler.cs b/Step/Listeners/ListenersHandler.cs index 2436c678..10967098 100644 --- a/Step/Listeners/ListenersHandler.cs +++ b/Step/Listeners/ListenersHandler.cs @@ -28,11 +28,6 @@ namespace Step.Listeners SignalRListener.SendAlarmsToClient(a as DTOAlarmsModel); })); - infos.Add(MessageServices.Current.Subscribe(SEND_GENERIC_DATA, async (a, b) => - { - SignalRListener.SendNcInfoToClient(a as DTONcGenericDataModel); - })); - infos.Add(MessageServices.Current.Subscribe(SEND_AXES, async (a, b) => { SignalRListener.SendAxesToClient(a as DTOAxesModel); @@ -60,7 +55,12 @@ namespace Step.Listeners infos.Add(MessageServices.Current.Subscribe(SEND_EXPIRED_MAINTENANCES_DATA, async (a, b) => { SignalRListener.SendExpMaintenancesData(a); - })); + })); + + infos.Add(MessageServices.Current.Subscribe(BROADCAST_DATA, async (a, b) => + { + SignalRListener.BroadcastData(); + })); } public static void Stop() diff --git a/Step/Listeners/SignalR/SignalRListener.cs b/Step/Listeners/SignalR/SignalRListener.cs index 6ff9310f..9e6429d8 100644 --- a/Step/Listeners/SignalR/SignalRListener.cs +++ b/Step/Listeners/SignalR/SignalRListener.cs @@ -1,30 +1,31 @@ using Microsoft.AspNet.SignalR; using Step.Controllers.SignalR; using Step.Model.DTOModels; +using System.Collections.Generic; +using System.Linq; namespace Step.Listeners.SignalR { public static class SignalRListener { - private static DTOAlarmsModel alarms = new DTOAlarmsModel(); - private static DTOAxesModel axes = new DTOAxesModel(); - - public static void SendNcInfoToClient(DTONcGenericDataModel taskName) - { - var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").machineInfo(taskName); - } + private static DTOAlarmsModel LastAlarms = new DTOAlarmsModel(); + private static DTOAxesModel LastAxes = new DTOAxesModel(); + private static List LastRuntimeFunctionality = new List(); + private static List LastExpiredMaintenances = new List(); + private static DTOPowerOnDataModel LastPowerOnData = new DTOPowerOnDataModel(); + private static DTOProcessDataModel LastProcessesData = new DTOProcessDataModel(); public static void SendAlarmsToClient(DTOAlarmsModel newAlarmsData) { var context = GlobalHost.ConnectionManager.GetHubContext(); - //if (!alarms.Equals(newAlarmsData)) - //{ - // Intersect old alarms data with new data - alarms = alarms.IntersectModels(newAlarmsData as DTOAlarmsModel); - context.Clients.Group("ncData").alarms(alarms); - //} + if (!LastAlarms.Equals(newAlarmsData)) + { + // Intersect old alarms data with new data + LastAlarms = LastAlarms.IntersectModels(newAlarmsData as DTOAlarmsModel); + // Send data to clients + context.Clients.Group("ncData").alarms(LastAlarms); + } } public static void SendAxesToClient(DTOAxesModel newAxesData) @@ -33,10 +34,17 @@ namespace Step.Listeners.SignalR context.Clients.Group("ncData").axes(newAxesData); } - public static void SendPowerOnDataToClient(object newAxesData) + public static void SendPowerOnDataToClient(object powerOnData) { var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").powerOn(newAxesData); + + // Check if object are equals + if (!LastPowerOnData.Equals(powerOnData)) + { + LastPowerOnData = powerOnData as DTOPowerOnDataModel; + // Send data to clients + context.Clients.Group("ncData").powerOn(powerOnData); + } } public static void SendNcNetworkStatus(object ncStatus) @@ -44,26 +52,75 @@ namespace Step.Listeners.SignalR if ((bool)ncStatus == false) { var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").ncNetworkStatus(new { connected = false }); + // Send data to clients + context.Clients.Group("ncData").ncNetworkStatus( + new + { + connected = false + } + ); } } public static void SendProcessesData(object processesStatus) { var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").processesData(processesStatus); + + // Check if the new data and stored object are the same + if (!LastProcessesData.Equals(processesStatus)) + { + LastProcessesData = processesStatus as DTOProcessDataModel; + // Send data to clients + context.Clients.Group("ncData").processesData(processesStatus); + } } public static void SendFunctionalityData(object functionalityData) { var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").functionalityData(functionalityData); + var newData = functionalityData as List; + + // Check if the new data and stored object are the same + if (newData.Count != LastRuntimeFunctionality.Count || !LastRuntimeFunctionality.All(newData.Contains)) + { + LastRuntimeFunctionality = newData; + // Send data to clients + context.Clients.Group("ncData").functionalityData(functionalityData); + } } public static void SendExpMaintenancesData(object expiredMaintenances) { var context = GlobalHost.ConnectionManager.GetHubContext(); - context.Clients.Group("ncData").expiredMaintenances(expiredMaintenances); + var newData = expiredMaintenances as List; + // Check if the new data and stored object are the same + if (newData.Count != LastExpiredMaintenances.Count || !LastExpiredMaintenances.All(newData.Contains)) + { + LastExpiredMaintenances = newData; + // Send data to clients + context.Clients.Group("ncData").expiredMaintenances(expiredMaintenances); + } + } + + public static void BroadcastData() + { + var context = GlobalHost.ConnectionManager.GetHubContext(); + + var group = context.Clients.Group("ncData"); + // Send Alarms + group.alarms(LastAlarms); + + // Send Power On Data + group.powerOn(LastPowerOnData); + + // Send Processes data + group.processesData(LastProcessesData); + + // Send functionality + group.functionalityData(LastRuntimeFunctionality); + + // Send Maintenances + group.expiredMaintenances(LastExpiredMaintenances); } } -} +} \ No newline at end of file