Add doormode schudeling
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ chartjs-plugin-datalabels
|
||||
/Aperio_Control_Centre/wwwroot/openlayers
|
||||
/Publish
|
||||
/Aperio_Control_Centre/wwwroot/ix-icons
|
||||
/Aperio_Control_Centre/wwwroot/js
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aperio_Control_Centre.ACSDatabase\Aperio_Control_Centre.ACSDatabase.csproj" />
|
||||
<ProjectReference Include="..\Aperio_Control_Centre\Aperio_Control_Centre.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.Extensions;
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
{
|
||||
@@ -13,13 +15,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Daily,
|
||||
WeekDays = WeekDaysTypes.Daily,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (dagelijks)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
}
|
||||
|
||||
@@ -31,13 +36,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.None,
|
||||
WeekDays = WeekDaysTypes.None,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (nooit)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
}
|
||||
|
||||
@@ -49,13 +57,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Monday,
|
||||
WeekDays = WeekDaysTypes.Monday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (ma)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -73,13 +84,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Tuesday,
|
||||
WeekDays = WeekDaysTypes.Tuesday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (di)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -97,13 +111,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Wednesday,
|
||||
WeekDays = WeekDaysTypes.Wednesday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (wo)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -121,13 +138,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Thursday,
|
||||
WeekDays = WeekDaysTypes.Thursday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (do)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -145,13 +165,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Friday,
|
||||
WeekDays = WeekDaysTypes.Friday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (vr)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -169,13 +192,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Saturday,
|
||||
WeekDays = WeekDaysTypes.Saturday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (za)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -193,13 +219,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromDays(1) - TimeSpan.FromMilliseconds(1),
|
||||
WeekDays = Types.WeekDaysTypes.Sunday,
|
||||
WeekDays = WeekDaysTypes.Sunday,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.TwentyFourHours,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("24 uur (zo)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 20)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 21)));
|
||||
@@ -217,13 +246,16 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Id = 1,
|
||||
BeginTime = TimeSpan.Zero,
|
||||
EndTime = TimeSpan.FromHours(12),
|
||||
WeekDays = Types.WeekDaysTypes.Daily,
|
||||
WeekDays = WeekDaysTypes.Daily,
|
||||
Name = "Tijdzone",
|
||||
TwentyFourHours = Types.TwentyFourHoursTypes.Timeselected,
|
||||
Active = Types.ActiveStates.Active,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
Active = ActiveStates.Active,
|
||||
Info = "Tijdzone",
|
||||
LastChanged = DateTime.UtcNow
|
||||
};
|
||||
|
||||
Assert.AreEqual("00:00 - 12:00 (dagelijks)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 19, 1, 1, 1)));
|
||||
Assert.IsFalse(timezone.IsTimezoneActive(new DateTime(2022, 9, 19, 12, 1, 1)));
|
||||
|
||||
@@ -234,5 +266,302 @@ namespace Aperio_Control_Centre.ACSDatabase.UnitTest
|
||||
Assert.IsTrue(timezone.IsTimezoneActive(new DateTime(2022, 9, 19, 12, 1, 1)));
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void Daily_Timespan_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(12),
|
||||
WeekDays = WeekDaysTypes.Daily,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("12:00 - 00:00 (dagelijks)", timezone.GetTimezoneString);
|
||||
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 12, 0, 0)).TotalSeconds);
|
||||
Assert.AreEqual((uint)0, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 12, 0, 0)).ToDeciSeconds());
|
||||
|
||||
Assert.AreEqual(3600, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 11, 0, 0)).TotalSeconds);
|
||||
Assert.AreEqual((uint)36000, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 11, 0, 0)).ToDeciSeconds());
|
||||
|
||||
Assert.AreEqual(43200, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 0, 0, 0)).TotalSeconds);
|
||||
Assert.AreEqual((uint)432000, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 0, 0, 0)).ToDeciSeconds());
|
||||
|
||||
Assert.AreEqual(82800, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 13, 0, 0)).TotalSeconds);
|
||||
Assert.AreEqual((uint)828000, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 13, 0, 0)).ToDeciSeconds());
|
||||
|
||||
Assert.AreEqual(86399, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 12, 0, 1)).TotalSeconds);
|
||||
Assert.AreEqual((uint)863990, timezone.TimeToNextBeginTime(new DateTime(2025, 1, 1, 12, 0, 1)).ToDeciSeconds());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Day_Timespan_days_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(8),
|
||||
Monday = true,
|
||||
Tuesday = true,
|
||||
Wednesday = true,
|
||||
Thursday = true,
|
||||
Friday = true,
|
||||
Saturday = false,
|
||||
Sunday = false,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("08:00 - 00:00 (ma,di,wo,do,vr)", timezone.GetTimezoneString);
|
||||
|
||||
DateTime monday = new(2025, 9, 15, 12, 0, 0);
|
||||
Assert.AreEqual(72000, timezone.TimeToNextBeginTime(monday).TotalSeconds);
|
||||
|
||||
DateTime tuesday = new(2025, 9, 16, 12, 0, 0);
|
||||
Assert.AreEqual(72000, timezone.TimeToNextBeginTime(tuesday).TotalSeconds);
|
||||
|
||||
DateTime wednesday = new(2025, 9, 17, 12, 0, 0);
|
||||
Assert.AreEqual(72000, timezone.TimeToNextBeginTime(wednesday).TotalSeconds);
|
||||
|
||||
DateTime thursday = new(2025, 9, 18, 12, 0, 0);
|
||||
Assert.AreEqual(72000, timezone.TimeToNextBeginTime(thursday).TotalSeconds);
|
||||
|
||||
|
||||
DateTime friday = new(2025, 9, 19, 12, 0, 0);
|
||||
Assert.AreEqual(244800, timezone.TimeToNextBeginTime(friday).TotalSeconds);
|
||||
|
||||
DateTime saturday = new(2025, 9, 20, 12, 0, 0);
|
||||
Assert.AreEqual(158400, timezone.TimeToNextBeginTime(saturday).TotalSeconds);
|
||||
|
||||
DateTime sunday = new(2025, 9, 21, 12, 0, 0);
|
||||
Assert.AreEqual(72000, timezone.TimeToNextBeginTime(sunday).TotalSeconds);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Day_Timespan_None_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(8),
|
||||
Monday = false,
|
||||
Tuesday = false,
|
||||
Wednesday = false,
|
||||
Thursday = false,
|
||||
Friday = false,
|
||||
Saturday = false,
|
||||
Sunday = false,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("08:00 - 00:00 (nooit)", timezone.GetTimezoneString);
|
||||
|
||||
DateTime monday = new(2025, 9, 15, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(monday).TotalSeconds);
|
||||
|
||||
DateTime tuesday = new(2025, 9, 16, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(tuesday).TotalSeconds);
|
||||
|
||||
DateTime wednesday = new(2025, 9, 17, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(wednesday).TotalSeconds);
|
||||
|
||||
DateTime thursday = new(2025, 9, 18, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(thursday).TotalSeconds);
|
||||
|
||||
DateTime friday = new(2025, 9, 19, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(friday).TotalSeconds);
|
||||
|
||||
DateTime saturday = new(2025, 9, 20, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(saturday).TotalSeconds);
|
||||
|
||||
DateTime sunday = new(2025, 9, 21, 12, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(sunday).TotalSeconds);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Day_Timespan_SingleDay_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(12),
|
||||
Monday = false,
|
||||
Tuesday = false,
|
||||
Wednesday = true,
|
||||
Thursday = false,
|
||||
Friday = false,
|
||||
Saturday = false,
|
||||
Sunday = false,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("12:00 - 00:00 (wo)", timezone.GetTimezoneString);
|
||||
|
||||
DateTime monday = new(2025, 9, 15, 0, 0, 0);
|
||||
Assert.AreEqual(2, timezone.TimeToNextBeginTime(monday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(monday).Hours);
|
||||
|
||||
DateTime tuesday = new(2025, 9, 16, 0, 0, 0);
|
||||
Assert.AreEqual(1, timezone.TimeToNextBeginTime(tuesday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(tuesday).Hours);
|
||||
|
||||
DateTime wednesday = new(2025, 9, 17, 0, 0, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(wednesday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(wednesday).Hours);
|
||||
|
||||
DateTime thursday = new(2025, 9, 18, 0, 0, 0);
|
||||
Assert.AreEqual(6, timezone.TimeToNextBeginTime(thursday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(thursday).Hours);
|
||||
|
||||
DateTime friday = new(2025, 9, 19, 0, 0, 0);
|
||||
Assert.AreEqual(5, timezone.TimeToNextBeginTime(friday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(friday).Hours);
|
||||
|
||||
DateTime saturday = new(2025, 9, 20, 0, 0, 0);
|
||||
Assert.AreEqual(4, timezone.TimeToNextBeginTime(saturday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(saturday).Hours);
|
||||
|
||||
DateTime sunday = new(2025, 9, 21, 0, 0, 0);
|
||||
Assert.AreEqual(3, timezone.TimeToNextBeginTime(sunday).Days);
|
||||
Assert.AreEqual(12, timezone.TimeToNextBeginTime(sunday).Hours);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Day_Timespan_SingleDay_Time_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(12),
|
||||
Monday = false,
|
||||
Tuesday = false,
|
||||
Wednesday = true,
|
||||
Thursday = false,
|
||||
Friday = false,
|
||||
Saturday = false,
|
||||
Sunday = false,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("12:00 - 00:00 (wo)", timezone.GetTimezoneString);
|
||||
|
||||
DateTime monday = new(2025, 9, 15, 10, 0, 0);
|
||||
Assert.AreEqual(2, timezone.TimeToNextBeginTime(monday).Days);
|
||||
Assert.AreEqual(2, timezone.TimeToNextBeginTime(monday).Hours);
|
||||
|
||||
DateTime tuesday = new(2025, 9, 16, 11, 0, 0);
|
||||
Assert.AreEqual(1, timezone.TimeToNextBeginTime(tuesday).Days);
|
||||
Assert.AreEqual(1, timezone.TimeToNextBeginTime(tuesday).Hours);
|
||||
|
||||
DateTime wednesday = new(2025, 9, 17, 12, 0, 0);
|
||||
Assert.AreEqual(7, timezone.TimeToNextBeginTime(wednesday).Days);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(wednesday).Hours);
|
||||
|
||||
DateTime thursday = new(2025, 9, 18, 13, 0, 0);
|
||||
Assert.AreEqual(5, timezone.TimeToNextBeginTime(thursday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(thursday).Hours);
|
||||
|
||||
DateTime friday = new(2025, 9, 19, 14, 0, 0);
|
||||
Assert.AreEqual(4, timezone.TimeToNextBeginTime(friday).Days);
|
||||
Assert.AreEqual(22, timezone.TimeToNextBeginTime(friday).Hours);
|
||||
|
||||
DateTime saturday = new(2025, 9, 20, 15, 0, 0);
|
||||
Assert.AreEqual(3, timezone.TimeToNextBeginTime(saturday).Days);
|
||||
Assert.AreEqual(21, timezone.TimeToNextBeginTime(saturday).Hours);
|
||||
|
||||
DateTime sunday = new(2025, 9, 21, 16, 0, 0);
|
||||
Assert.AreEqual(2, timezone.TimeToNextBeginTime(sunday).Days);
|
||||
Assert.AreEqual(20, timezone.TimeToNextBeginTime(sunday).Hours);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void Day_Timespan_WorkDays_Time_Test()
|
||||
{
|
||||
Timezone timezone = new()
|
||||
{
|
||||
BeginTime = TimeSpan.FromHours(8),
|
||||
EndTime = TimeSpan.FromHours(16).Add(TimeSpan.FromMinutes(30)),
|
||||
Monday = true,
|
||||
Tuesday = true,
|
||||
Wednesday = true,
|
||||
Thursday = true,
|
||||
Friday = true,
|
||||
Saturday = false,
|
||||
Sunday = false,
|
||||
TwentyFourHours = TwentyFourHoursTypes.Timeselected,
|
||||
};
|
||||
|
||||
Assert.AreEqual("08:00", timezone.BeginTimeString());
|
||||
Assert.AreEqual("16:30", timezone.EndTimeString());
|
||||
Assert.AreEqual("08:00 - 16:30 (ma,di,wo,do,vr)", timezone.GetTimezoneString);
|
||||
Assert.AreEqual("ma,di,wo,do,vr", timezone.GetWeekdayShortString);
|
||||
|
||||
DateTime monday = new(2025, 9, 22, 8, 30, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(monday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(monday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(monday).Minutes);
|
||||
Assert.AreEqual("23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(monday).ToCustomString());
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(monday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(monday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(monday).Minutes);
|
||||
Assert.AreEqual("8:hr 0:min 0:sec", timezone.TimeToNextEndTime(monday).ToCustomString());
|
||||
|
||||
DateTime tuesday = new(2025, 9, 23, 8, 30, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(tuesday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(tuesday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(tuesday).Minutes);
|
||||
Assert.AreEqual("23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(tuesday).ToCustomString());
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(tuesday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(tuesday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(tuesday).Minutes);
|
||||
Assert.AreEqual("8:hr 0:min 0:sec", timezone.TimeToNextEndTime(tuesday).ToCustomString());
|
||||
|
||||
DateTime wednesday = new(2025, 9, 24, 8, 30, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(wednesday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(wednesday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(wednesday).Minutes);
|
||||
Assert.AreEqual("23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(wednesday).ToCustomString());
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(wednesday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(wednesday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(wednesday).Minutes);
|
||||
Assert.AreEqual("8:hr 0:min 0:sec", timezone.TimeToNextEndTime(wednesday).ToCustomString());
|
||||
|
||||
DateTime thursday = new(2025, 9, 25, 8, 30, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(thursday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(thursday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(thursday).Minutes);
|
||||
Assert.AreEqual("23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(thursday).ToCustomString());
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(thursday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(thursday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(thursday).Minutes);
|
||||
Assert.AreEqual("8:hr 0:min 0:sec", timezone.TimeToNextEndTime(thursday).ToCustomString());
|
||||
|
||||
DateTime friday = new(2025, 9, 26, 8, 30, 0);
|
||||
Assert.AreEqual(2, timezone.TimeToNextBeginTime(friday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(friday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(friday).Minutes);
|
||||
Assert.AreEqual("2:days 23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(friday).ToCustomString());
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(friday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(friday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(friday).Minutes);
|
||||
Assert.AreEqual("8:hr 0:min 0:sec", timezone.TimeToNextEndTime(friday).ToCustomString());
|
||||
|
||||
DateTime saturday = new(2025, 9, 27, 8, 30, 0);
|
||||
Assert.AreEqual(1, timezone.TimeToNextBeginTime(saturday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(saturday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(saturday).Minutes);
|
||||
Assert.AreEqual("1:days 23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(saturday).ToCustomString());
|
||||
Assert.AreEqual(2, timezone.TimeToNextEndTime(saturday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(saturday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(saturday).Minutes);
|
||||
Assert.AreEqual("2:days 8:hr 0:min 0:sec", timezone.TimeToNextEndTime(saturday).ToCustomString());
|
||||
|
||||
DateTime sunday = new(2025, 9, 28, 8, 30, 0);
|
||||
Assert.AreEqual(0, timezone.TimeToNextBeginTime(sunday).Days);
|
||||
Assert.AreEqual(23, timezone.TimeToNextBeginTime(sunday).Hours);
|
||||
Assert.AreEqual(30, timezone.TimeToNextBeginTime(sunday).Minutes);
|
||||
Assert.AreEqual("23:hr 30:min 0:sec", timezone.TimeToNextBeginTime(sunday).ToCustomString());
|
||||
Assert.AreEqual(1, timezone.TimeToNextEndTime(sunday).Days);
|
||||
Assert.AreEqual(8, timezone.TimeToNextEndTime(sunday).Hours);
|
||||
Assert.AreEqual(0, timezone.TimeToNextEndTime(sunday).Minutes);
|
||||
Assert.AreEqual("1:days 8:hr 0:min 0:sec", timezone.TimeToNextEndTime(sunday).ToCustomString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace Aperio_Control_Centre.ACSDatabase
|
||||
|
||||
public DbSet<Models.AuthorizationEntry> AuthorizationMatrix { get; set; } = null!;
|
||||
|
||||
public DbSet<Models.DoorModeSchedule> DoorModeSchedules { get; set; } = null!;
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
@@ -102,8 +103,18 @@ namespace Aperio_Control_Centre.ACSDatabase
|
||||
.HasColumnName("Info")
|
||||
.HasMaxLength(500);
|
||||
|
||||
entity.OwnsMany<SupportedDoorMode>(
|
||||
mode => mode.DoorModes, builder => { builder.ToJson(); });
|
||||
entity.OwnsMany<SupportedDoorMode>(e => e.DoorModes, b =>
|
||||
{
|
||||
b.ToJson();
|
||||
});
|
||||
|
||||
//entity.OwnsMany<DoorModeSchedulerItem>(e => e.DoorModeScheduler, b => { b.ToJson().Ignore(x => x.TimeZone); });
|
||||
//entity.OwnsMany<DoorModeSchedulerItem>(e => e.DoorModeScheduler, b =>
|
||||
//{
|
||||
// b.ToJson();
|
||||
// //b.Ignore(x => x.TimeZone);
|
||||
// //b.OwnsOne(t => t.Timezone);
|
||||
//});
|
||||
|
||||
entity.Property(e => e.ProductClass)
|
||||
.HasColumnName("ProductClass");
|
||||
@@ -490,7 +501,7 @@ namespace Aperio_Control_Centre.ACSDatabase
|
||||
entity.Ignore(e => e.WholeDayTime);
|
||||
entity.Ignore(e => e.GetTimezoneString);
|
||||
entity.Ignore(e => e.GetWeekdayShortString);
|
||||
entity.Ignore(e => e.IsTimezoneActive2);
|
||||
//entity.Ignore(e => e.IsTimezoneActive2);
|
||||
|
||||
entity.HasMany(e => e.Authorizations)
|
||||
.WithOne(e => e.Timezone)
|
||||
@@ -665,6 +676,24 @@ namespace Aperio_Control_Centre.ACSDatabase
|
||||
// .IsRequired();
|
||||
|
||||
});
|
||||
|
||||
modelBuilder.Entity<DoorModeSchedule>(entity =>
|
||||
{
|
||||
entity.ToTable("DoorModeSchedules");
|
||||
entity.HasKey(e => e.Id);
|
||||
entity.Property(e => e.Id).HasColumnName("ID");
|
||||
entity.Property(e => e.DeviceId).HasColumnName("Device_Id").IsRequired(true);
|
||||
entity.Property(e => e.DoorMode).HasColumnName("DoorMode").IsRequired(true);
|
||||
entity.Property(e => e.TimezoneId).HasColumnName("Timezone_Id").IsRequired(true);
|
||||
|
||||
entity.HasOne(d => d.Device)
|
||||
.WithMany(p => p.DoorModeSchedules)
|
||||
.HasForeignKey(d => d.DeviceId);
|
||||
|
||||
entity.HasOne(d => d.Timezone)
|
||||
.WithMany(p => p.DoorModeSchedules)
|
||||
.HasForeignKey(d => d.TimezoneId);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
944
Aperio_Control_Centre.ACSDatabase/Migrations/20250919125957_[AddDoorModeScheduling].Designer.cs
generated
Normal file
944
Aperio_Control_Centre.ACSDatabase/Migrations/20250919125957_[AddDoorModeScheduling].Designer.cs
generated
Normal file
@@ -0,0 +1,944 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Aperio_Control_Centre.ACSDatabase;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
{
|
||||
[DbContext(typeof(ACSDatabaseContext))]
|
||||
[Migration("20250919125957_[AddDoorModeScheduling]")]
|
||||
partial class AddDoorModeScheduling
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.AuthorizationEntry", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("DeviceGroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("DeviceGroup_Id");
|
||||
|
||||
b.Property<int>("TimezoneId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Timezone_Id");
|
||||
|
||||
b.Property<int>("UserGroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("UserGroup_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DeviceGroupId");
|
||||
|
||||
b.HasIndex("TimezoneId");
|
||||
|
||||
b.HasIndex("UserGroupId");
|
||||
|
||||
b.ToTable("AuthorizationMatrix", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Department", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Departments", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Device", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<int?>("BatteryState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("BatteryState");
|
||||
|
||||
b.Property<int?>("ConnectionState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ConnectionState");
|
||||
|
||||
b.Property<string>("DeviceId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("nvarchar(10)")
|
||||
.HasColumnName("DeviceID");
|
||||
|
||||
b.Property<int?>("DoorState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("DoorState");
|
||||
|
||||
b.Property<int?>("EmergencyInsideState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("EmergencyInsideState");
|
||||
|
||||
b.Property<int?>("EmergencyOutsideState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("EmergencyOutsideState");
|
||||
|
||||
b.Property<int?>("HandleState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("HandleState");
|
||||
|
||||
b.Property<string>("HubId")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("nvarchar(10)")
|
||||
.HasColumnName("HubID");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<string>("Ipaddress")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Ipaddress");
|
||||
|
||||
b.Property<int?>("KeyCylinderState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("KeyCylinderState");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<DateTime?>("LastData")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastData");
|
||||
|
||||
b.Property<int?>("LocationId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Location_Id");
|
||||
|
||||
b.Property<int?>("LockState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("LockState");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int?>("ProductClass")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ProductClass");
|
||||
|
||||
b.Property<int?>("TamperState")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("TamperState");
|
||||
|
||||
b.Property<int?>("UnlockTime")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("UnlockTime");
|
||||
|
||||
b.Property<int?>("UnlockTimezoneId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("UnlockTimezone_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "LocationId" }, "IX_FK_Devices_Locations");
|
||||
|
||||
b.HasIndex(new[] { "UnlockTimezoneId" }, "IX_FK_Devices_Timezones");
|
||||
|
||||
b.HasIndex(new[] { "DeviceId" }, "NonClusteredIndex-Device_Id");
|
||||
|
||||
b.ToTable("Devices", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("DeviceGroups", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroupJoin", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("DeviceId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Device_Id");
|
||||
|
||||
b.Property<int>("GroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Group_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "DeviceId" }, "IX_FK_DeviceGroupJoins_Device");
|
||||
|
||||
b.HasIndex(new[] { "GroupId" }, "IX_FK_DeviceGroupJoins_Group");
|
||||
|
||||
b.ToTable("DeviceGroupJoins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroupJoin2", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("DeviceGroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("DeviceGroup_Id");
|
||||
|
||||
b.Property<int>("DeviceId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Device_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DeviceGroupId");
|
||||
|
||||
b.HasIndex("DeviceId");
|
||||
|
||||
b.ToTable("DeviceGroupJoins2", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DoorModeSchedule", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("DeviceId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Device_Id");
|
||||
|
||||
b.Property<int>("DoorMode")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("DoorMode");
|
||||
|
||||
b.Property<int>("ExecuteMode")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TimezoneId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Timezone_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DeviceId");
|
||||
|
||||
b.HasIndex("TimezoneId");
|
||||
|
||||
b.ToTable("DoorModeSchedules", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.GlobalSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Value");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GlobalSettings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Group", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int>("TimezoneId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Timezone_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TimezoneId");
|
||||
|
||||
b.ToTable("Groups", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Location", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("City")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("City");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Country");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Latitude")
|
||||
.HasMaxLength(12)
|
||||
.HasColumnType("nvarchar(12)")
|
||||
.HasColumnName("Latitude");
|
||||
|
||||
b.Property<string>("Longitude")
|
||||
.HasMaxLength(12)
|
||||
.HasColumnType("nvarchar(12)")
|
||||
.HasColumnName("Longitude");
|
||||
|
||||
b.Property<string>("Nr")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("nvarchar(10)")
|
||||
.HasColumnName("Nr");
|
||||
|
||||
b.Property<string>("Province")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Province");
|
||||
|
||||
b.Property<string>("Street")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Street");
|
||||
|
||||
b.Property<string>("Zipcode")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("nvarchar(10)")
|
||||
.HasColumnName("Zipcode");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Locations", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Logging", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int?>("Access")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Access");
|
||||
|
||||
b.Property<string>("CredentialString")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("CredentialString");
|
||||
|
||||
b.Property<int?>("CredentialType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("CredentialType");
|
||||
|
||||
b.Property<int?>("DeviceId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Device_Id");
|
||||
|
||||
b.Property<int>("LogType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("LogType");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("nvarchar(200)")
|
||||
.HasColumnName("Message");
|
||||
|
||||
b.Property<DateTime>("Time")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("Time");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("User_Id");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("UserName");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "DeviceId" }, "IX_FK_DevicesLoggingsX");
|
||||
|
||||
b.HasIndex(new[] { "UserId" }, "IX_FK_UsersLoggingsX");
|
||||
|
||||
b.HasIndex(new[] { "DeviceId" }, "NonClusteredIndex-Device_Id");
|
||||
|
||||
b.HasIndex(new[] { "LogType" }, "NonClusteredIndex-LogType");
|
||||
|
||||
b.HasIndex(new[] { "UserId" }, "NonClusteredIndex-User_Id");
|
||||
|
||||
b.ToTable("Loggings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Timezone", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<TimeSpan>("BeginTime")
|
||||
.HasColumnType("time")
|
||||
.HasColumnName("BeginTime");
|
||||
|
||||
b.Property<TimeSpan>("EndTime")
|
||||
.HasColumnType("time")
|
||||
.HasColumnName("EndTime");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int>("TwentyFourHours")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("TwentyFourHours");
|
||||
|
||||
b.Property<int>("WeekDays")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("WeekDays");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Timezones", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<DateTime>("Created")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("Created");
|
||||
|
||||
b.Property<string>("CredentialString")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("CredentialString");
|
||||
|
||||
b.Property<int>("CredentialType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("CredentialType");
|
||||
|
||||
b.Property<int?>("DepartmentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Department_Id");
|
||||
|
||||
b.Property<bool?>("Dordrecht")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("Dordrecht");
|
||||
|
||||
b.Property<int?>("Expires")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Expires");
|
||||
|
||||
b.Property<int?>("GroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Group_Id");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.Property<int?>("PassNumber")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("PassNumber");
|
||||
|
||||
b.Property<string>("SubLine")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("SubLine");
|
||||
|
||||
b.Property<int?>("Watched")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Watched");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex(new[] { "DepartmentId" }, "IX_FK_Users_Departments");
|
||||
|
||||
b.HasIndex(new[] { "GroupId" }, "IX_FK_Users_Groups");
|
||||
|
||||
b.HasIndex(new[] { "CredentialString" }, "NonClusteredIndex-CredentialString");
|
||||
|
||||
b.ToTable("Users", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.UserGroup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("Active")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Active");
|
||||
|
||||
b.Property<string>("Info")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("nvarchar(500)")
|
||||
.HasColumnName("Info");
|
||||
|
||||
b.Property<DateTime>("LastChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("LastChanged");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(50)")
|
||||
.HasColumnName("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("UserGroups", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.UserGroupJoin", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("UserGroupId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("UserGroup_Id");
|
||||
|
||||
b.Property<int>("UserId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("User_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserGroupId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserGroupJoins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.AuthorizationEntry", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroup", "DeviceGroup")
|
||||
.WithMany("Authorizations")
|
||||
.HasForeignKey("DeviceGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "Timezone")
|
||||
.WithMany("Authorizations")
|
||||
.HasForeignKey("TimezoneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.UserGroup", "UserGroup")
|
||||
.WithMany("Authorizations")
|
||||
.HasForeignKey("UserGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("DeviceGroup");
|
||||
|
||||
b.Navigation("Timezone");
|
||||
|
||||
b.Navigation("UserGroup");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Device", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Location", "Location")
|
||||
.WithMany("Devices")
|
||||
.HasForeignKey("LocationId")
|
||||
.HasConstraintName("FK_Devices_Locations");
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "UnlockTimezone")
|
||||
.WithMany("Devices")
|
||||
.HasForeignKey("UnlockTimezoneId")
|
||||
.HasConstraintName("FK_Devices_Timezones");
|
||||
|
||||
b.OwnsMany("Aperio_Control_Centre.ACSDatabase.Models.SupportedDoorMode", "DoorModes", b1 =>
|
||||
{
|
||||
b1.Property<int>("DeviceId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.Property<int>("__synthesizedOrdinal")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.Property<bool>("CurrentMode")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b1.Property<int>("DoorMode")
|
||||
.HasColumnType("int");
|
||||
|
||||
b1.HasKey("DeviceId", "__synthesizedOrdinal");
|
||||
|
||||
b1.ToTable("Devices");
|
||||
|
||||
b1.ToJson("DoorModes");
|
||||
|
||||
b1.WithOwner()
|
||||
.HasForeignKey("DeviceId");
|
||||
});
|
||||
|
||||
b.Navigation("DoorModes");
|
||||
|
||||
b.Navigation("Location");
|
||||
|
||||
b.Navigation("UnlockTimezone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroupJoin", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Device", "Device")
|
||||
.WithMany("DeviceGroupJoins")
|
||||
.HasForeignKey("DeviceId")
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_DeviceGroupJoins_Device");
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Group", "Group")
|
||||
.WithMany("DeviceGroupJoins")
|
||||
.HasForeignKey("GroupId")
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_DeviceGroupJoins_Group");
|
||||
|
||||
b.Navigation("Device");
|
||||
|
||||
b.Navigation("Group");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroupJoin2", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroup", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DeviceGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Device", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("DeviceId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DoorModeSchedule", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Device", "Device")
|
||||
.WithMany("DoorModeSchedules")
|
||||
.HasForeignKey("DeviceId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "Timezone")
|
||||
.WithMany("DoorModeSchedules")
|
||||
.HasForeignKey("TimezoneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Device");
|
||||
|
||||
b.Navigation("Timezone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Group", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "Timezone")
|
||||
.WithMany("Groups")
|
||||
.HasForeignKey("TimezoneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("FK_Timezones_Groups");
|
||||
|
||||
b.Navigation("Timezone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Logging", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Device", "Device")
|
||||
.WithMany("Loggings")
|
||||
.HasForeignKey("DeviceId")
|
||||
.HasConstraintName("FK_DevicesLoggingsX");
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.User", "User")
|
||||
.WithMany("Loggings")
|
||||
.HasForeignKey("UserId")
|
||||
.HasConstraintName("FK_UsersLoggingsX");
|
||||
|
||||
b.Navigation("Device");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.User", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Department", "Department")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("DepartmentId")
|
||||
.HasConstraintName("FK_Users_Departments");
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Group", "Group")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("GroupId")
|
||||
.HasConstraintName("FK_Users_Groups");
|
||||
|
||||
b.Navigation("Department");
|
||||
|
||||
b.Navigation("Group");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.UserGroupJoin", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.UserGroup", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserGroupId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.User", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Department", b =>
|
||||
{
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Device", b =>
|
||||
{
|
||||
b.Navigation("DeviceGroupJoins");
|
||||
|
||||
b.Navigation("DoorModeSchedules");
|
||||
|
||||
b.Navigation("Loggings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DeviceGroup", b =>
|
||||
{
|
||||
b.Navigation("Authorizations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Group", b =>
|
||||
{
|
||||
b.Navigation("DeviceGroupJoins");
|
||||
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Location", b =>
|
||||
{
|
||||
b.Navigation("Devices");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Timezone", b =>
|
||||
{
|
||||
b.Navigation("Authorizations");
|
||||
|
||||
b.Navigation("Devices");
|
||||
|
||||
b.Navigation("DoorModeSchedules");
|
||||
|
||||
b.Navigation("Groups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.User", b =>
|
||||
{
|
||||
b.Navigation("Loggings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.UserGroup", b =>
|
||||
{
|
||||
b.Navigation("Authorizations");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddDoorModeScheduling : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DoorModeSchedules",
|
||||
columns: table => new
|
||||
{
|
||||
ID = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("SqlServer:Identity", "1, 1"),
|
||||
Device_Id = table.Column<int>(type: "int", nullable: false),
|
||||
DoorMode = table.Column<int>(type: "int", nullable: false),
|
||||
ExecuteMode = table.Column<int>(type: "int", nullable: false),
|
||||
Timezone_Id = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DoorModeSchedules", x => x.ID);
|
||||
table.ForeignKey(
|
||||
name: "FK_DoorModeSchedules_Devices_Device_Id",
|
||||
column: x => x.Device_Id,
|
||||
principalTable: "Devices",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_DoorModeSchedules_Timezones_Timezone_Id",
|
||||
column: x => x.Timezone_Id,
|
||||
principalTable: "Timezones",
|
||||
principalColumn: "ID",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DoorModeSchedules_Device_Id",
|
||||
table: "DoorModeSchedules",
|
||||
column: "Device_Id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DoorModeSchedules_Timezone_Id",
|
||||
table: "DoorModeSchedules",
|
||||
column: "Timezone_Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "DoorModeSchedules");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.4")
|
||||
.HasAnnotation("ProductVersion", "9.0.9")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128);
|
||||
|
||||
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
|
||||
@@ -283,6 +283,39 @@ namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
b.ToTable("DeviceGroupJoins2", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DoorModeSchedule", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("ID");
|
||||
|
||||
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("DeviceId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Device_Id");
|
||||
|
||||
b.Property<int>("DoorMode")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("DoorMode");
|
||||
|
||||
b.Property<int>("ExecuteMode")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("TimezoneId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("Timezone_Id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("DeviceId");
|
||||
|
||||
b.HasIndex("TimezoneId");
|
||||
|
||||
b.ToTable("DoorModeSchedules", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.GlobalSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@@ -771,6 +804,25 @@ namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.DoorModeSchedule", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Device", "Device")
|
||||
.WithMany("DoorModeSchedules")
|
||||
.HasForeignKey("DeviceId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "Timezone")
|
||||
.WithMany("DoorModeSchedules")
|
||||
.HasForeignKey("TimezoneId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Device");
|
||||
|
||||
b.Navigation("Timezone");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Aperio_Control_Centre.ACSDatabase.Models.Group", b =>
|
||||
{
|
||||
b.HasOne("Aperio_Control_Centre.ACSDatabase.Models.Timezone", "Timezone")
|
||||
@@ -841,6 +893,8 @@ namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
{
|
||||
b.Navigation("DeviceGroupJoins");
|
||||
|
||||
b.Navigation("DoorModeSchedules");
|
||||
|
||||
b.Navigation("Loggings");
|
||||
});
|
||||
|
||||
@@ -867,6 +921,8 @@ namespace Aperio_Control_Centre.ACSDatabase.Migrations
|
||||
|
||||
b.Navigation("Devices");
|
||||
|
||||
b.Navigation("DoorModeSchedules");
|
||||
|
||||
b.Navigation("Groups");
|
||||
});
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
public string? Info { get; set; }
|
||||
|
||||
[Display(Name = nameof(DoorModes))]
|
||||
//public List<SupportedDoorMode>? DoorModes { get; set; }
|
||||
public SupportedDoorModes? DoorModes { get; set; }
|
||||
|
||||
|
||||
[Display(Name = nameof(ProductClass))]
|
||||
public ProductClass? ProductClass { get; set; }
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
[Range(0, int.MaxValue, ErrorMessage = "Seconden groter dan 0")]
|
||||
public int? UnlockTime { get; set; }
|
||||
|
||||
[Obsolete("Use door mode schedules")]
|
||||
[Display(Name = nameof(UnlockTimezone))]
|
||||
public int? UnlockTimezoneId { get; set; }
|
||||
|
||||
@@ -92,7 +93,7 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm:ss}", ApplyFormatInEditMode = true)]
|
||||
public DateTime LastChanged { get; set; }
|
||||
|
||||
//todo use last data
|
||||
//TODO: use last data
|
||||
[Display(Name = nameof(LastData))]
|
||||
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm:ss}", ApplyFormatInEditMode = true)]
|
||||
public DateTime? LastData { get; set; }
|
||||
@@ -101,6 +102,7 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
[Display(Name = nameof(Location))]
|
||||
public Location? Location { get; set; }
|
||||
|
||||
[Obsolete("Use door mode schedules")]
|
||||
[Display(Name = nameof(UnlockTimezone))]
|
||||
public Timezone? UnlockTimezone { get; set; }
|
||||
|
||||
@@ -113,6 +115,13 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
public List<DeviceGroup> DeviceGroups { get; } = [];
|
||||
|
||||
|
||||
[Display(Name = nameof(DoorModeSchedules))]
|
||||
public List<DoorModeSchedule>? DoorModeSchedules { get; set; }
|
||||
|
||||
|
||||
[NotMapped]
|
||||
public SelectList? LocationSelection { get; set; }
|
||||
|
||||
//public Device? Gateway { get; set; }
|
||||
//public ICollection<Device> ChildDevices { get; } = [];
|
||||
|
||||
@@ -122,8 +131,8 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
//[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm:ss}", ApplyFormatInEditMode = true)]
|
||||
//public DateTimeOffset LastChangedLocal => LastChanged.ToLocalTime();
|
||||
|
||||
[NotMapped]
|
||||
public SelectList? LocationSelection { get; set; }
|
||||
//[NotMapped]
|
||||
//public SelectList? ExecuteModeSelection { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
[Display(Name = nameof(DeviceGroups))]
|
||||
@@ -138,7 +147,15 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
|
||||
[NotMapped]
|
||||
public List<Logging> LastLoggings { get; set; } = [];
|
||||
|
||||
|
||||
|
||||
|
||||
//[NotMapped]
|
||||
//[Display(Name = "Deur stand planner")]
|
||||
//public DoorModeScheduler? DoorModeScheduler { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
public uint OpenTimeDeciseconds()
|
||||
{
|
||||
|
||||
30
Aperio_Control_Centre.ACSDatabase/Models/DoorModeSchedule.cs
Normal file
30
Aperio_Control_Centre.ACSDatabase/Models/DoorModeSchedule.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
{
|
||||
public class DoorModeSchedule
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public int DeviceId { get; set; }
|
||||
|
||||
[Required]
|
||||
public DoorMode DoorMode { get; set; }
|
||||
|
||||
[Required]
|
||||
public ExecuteMode ExecuteMode { get; set; }
|
||||
|
||||
[Required]
|
||||
public int TimezoneId { get; set; }
|
||||
|
||||
|
||||
[Display(Name = nameof(Device))]
|
||||
public Device? Device { get; set; }
|
||||
|
||||
[Display(Name = nameof(Timezone))]
|
||||
public Timezone? Timezone { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.Models.Extensions
|
||||
{
|
||||
public static class DoorModeScheduleExtension
|
||||
{
|
||||
public static DoorModeSchedule? GetFirstActiveDoorModeschedule(this List<DoorModeSchedule>? doorModeSchedules)
|
||||
{
|
||||
if(doorModeSchedules != null)
|
||||
{
|
||||
Debug.WriteLine("has DoorModeSchedules");
|
||||
|
||||
foreach (DoorModeSchedule doorModeSchedule in doorModeSchedules)
|
||||
{
|
||||
Debug.WriteLine($"DoorModeSchedule - {doorModeSchedule.Timezone?.GetTimezoneString} - {doorModeSchedule.DoorMode} - {doorModeSchedule.ExecuteMode}");
|
||||
|
||||
if (doorModeSchedule.Timezone.IsTimezoneActive())
|
||||
{
|
||||
Debug.WriteLine("time zone is active");
|
||||
|
||||
//await WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), doorModeSchedule.DoorMode, doorModeSchedule.Timezone.TimeToNextEndTime().ToDeciSeconds(), TimingMode.TIME, doorModeSchedule.ExecuteMode), token);
|
||||
return doorModeSchedule;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,38 @@ namespace Aperio_Control_Centre.ACSDatabase.Models.Extensions
|
||||
{
|
||||
public static class LoggingExtensions
|
||||
{
|
||||
//public static async Task AddLogAsync(this DbSet<Logging> loggings, ILogEntryBase log, CancellationToken token)
|
||||
//{
|
||||
// ArgumentNullException.ThrowIfNull(loggings);
|
||||
// ArgumentNullException.ThrowIfNull(log);
|
||||
// Logging logEntry = new()
|
||||
// {
|
||||
// Time = DateTime.UtcNow,
|
||||
// LogType = log.LogType,
|
||||
|
||||
// //Device = device,
|
||||
// //User = user,
|
||||
// //Access = access,
|
||||
// //CredentialString = user?.CredentialString,
|
||||
// //CredentialType = user?.CredentialType,
|
||||
// Message = log.Message,
|
||||
// };
|
||||
|
||||
// if(log is UserLogEntry userlog)
|
||||
// {
|
||||
// logEntry.User = userlog.User;
|
||||
// }
|
||||
|
||||
|
||||
// await loggings.AddAsync(logEntry, token);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------
|
||||
|
||||
public static async Task AddLogAsync<T>(this DbSet<Logging> loggings, Device device, T state, CancellationToken token) where T : Enum
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(device);
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Aperio_Control_Centre.ACSDatabase.Models.Extensions
|
||||
.Select(s => new SelectListItem
|
||||
{
|
||||
Value = s.Id.ToString(),
|
||||
Text = s.Name,
|
||||
Text = $"{s.Name} - {s.GetTimezoneString}",
|
||||
}).ToListAsync(token);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class BootlogEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.Bootlog;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,26 @@
|
||||
////using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
////namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
////{
|
||||
//// public class DTCEntry : LogEntryBase
|
||||
//// {
|
||||
//// public override LogTypes LogType { get; } = LogTypes.DTC;
|
||||
//// }
|
||||
////}
|
||||
|
||||
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class DTCEntry : Logging
|
||||
// {
|
||||
// public DTCEntry()
|
||||
// {
|
||||
// Time = DateTime.UtcNow;
|
||||
// LogType = Types.LogTypes.DTC;
|
||||
// }
|
||||
|
||||
|
||||
// //public override LogTypes LogType { get; } = LogTypes.DTC;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,9 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class DeviceLogEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.Device;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,11 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public interface ILogEntryBase
|
||||
// {
|
||||
// //public LogTypes LogType { get; }
|
||||
|
||||
// //public string? Message { get; set; }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,10 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class LogEntryBase : Logging, ILogEntryBase
|
||||
// {
|
||||
// public virtual LogTypes LogType { get; } = LogTypes.Unknown;
|
||||
// public string? Message { get; set; }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,9 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class ManualOpenEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.ManualOpen;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,9 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class SystemLogEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.System;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,9 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class UnknownUserEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.UnknownUser;
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,14 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
|
||||
//namespace Aperio_Control_Centre.ACSDatabase.Models.LogEntrys
|
||||
//{
|
||||
// public class UserLogEntry : LogEntryBase
|
||||
// {
|
||||
// public override LogTypes LogType { get; } = LogTypes.User;
|
||||
|
||||
// public User? User { get; set; }
|
||||
|
||||
|
||||
|
||||
// }
|
||||
//}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
|
||||
namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
{
|
||||
@@ -56,5 +57,24 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<SelectListItem> DoorModeSelectListItems()
|
||||
{
|
||||
return this
|
||||
.Select(s => new SelectListItem
|
||||
{
|
||||
Value = s.DoorMode.ToString(),
|
||||
Text = s.DoorMode.ToString(),
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public SelectList DoorModeSelectList()
|
||||
{
|
||||
return new SelectList(DoorModeSelectListItems(), "Value", "Text");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
[Display(Name = nameof(Authorizations))]
|
||||
public ICollection<AuthorizationEntry> Authorizations { get; } = [];
|
||||
|
||||
|
||||
[Display(Name = nameof(DoorModeSchedules))]
|
||||
public ICollection<DoorModeSchedule> DoorModeSchedules { get; } = [];
|
||||
|
||||
//[NotMapped]
|
||||
//[Display(Name = "Last changed")]
|
||||
//[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy HH:mm:ss}", ApplyFormatInEditMode = true)]
|
||||
@@ -285,9 +289,9 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
}
|
||||
|
||||
|
||||
[NotMapped]
|
||||
[Display(Name = "Tijdzone actief")]
|
||||
public bool IsTimezoneActive2 => IsTimezoneActive(DateTime.Now);
|
||||
//[NotMapped]
|
||||
//[Display(Name = "Tijdzone actief")]
|
||||
//public bool IsTimezoneActive2 => IsTimezoneActive(DateTime.Now);
|
||||
|
||||
//[Display(Name = "Tijdzone actief")]
|
||||
public bool IsTimezoneActive()
|
||||
@@ -341,5 +345,101 @@ namespace Aperio_Control_Centre.ACSDatabase.Models
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TimeSpan TimeToNextBeginTime()
|
||||
{
|
||||
return TimeToNextTime(BeginTime, DateTime.Now);
|
||||
}
|
||||
public TimeSpan TimeToNextBeginTime(DateTime dateTime)
|
||||
{
|
||||
return TimeToNextTime(BeginTime, dateTime);
|
||||
}
|
||||
|
||||
public TimeSpan TimeToNextEndTime()
|
||||
{
|
||||
return TimeToNextTime(EndTime, DateTime.Now);
|
||||
}
|
||||
public TimeSpan TimeToNextEndTime(DateTime dateTime)
|
||||
{
|
||||
return TimeToNextTime(EndTime, dateTime);
|
||||
}
|
||||
|
||||
|
||||
private TimeSpan TimeToNextTime(TimeSpan time, DateTime currentDateTime)
|
||||
{
|
||||
//Debug.WriteLine($"-----------------------------------------------------------");
|
||||
//Debug.WriteLine($"currentDateTime {currentDateTime.ToString()} - {currentDateTime.DayOfWeek}");
|
||||
//Debug.WriteLine($"time {time.ToString()}");
|
||||
|
||||
if (WeekDays == WeekDaysTypes.Daily)
|
||||
{
|
||||
return RemainingTimeOffDay(time, currentDateTime.TimeOfDay);
|
||||
}
|
||||
else if (WeekDays == WeekDaysTypes.None)
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.WriteLine($"day of week {today}");
|
||||
|
||||
WeekDaysTypes weekday = currentDateTime.DayOfWeek.ToWeekDaysTypes();
|
||||
if (WeekDays.HasFlag(weekday))
|
||||
{
|
||||
//Debug.WriteLine("has flag");
|
||||
if (time > currentDateTime.TimeOfDay)
|
||||
{
|
||||
//on the same day
|
||||
//Debug.WriteLine($"Same day");
|
||||
return RemainingTimeOffDay(time, currentDateTime.TimeOfDay);
|
||||
}
|
||||
}
|
||||
|
||||
IOrderedEnumerable<DayOfWeek> reordereddays = Enum.GetValues<DayOfWeek>()
|
||||
.Cast<DayOfWeek>()
|
||||
.OrderBy(d => (d - (currentDateTime.DayOfWeek + 1) + 7) % 7);
|
||||
|
||||
TimeSpan days = new();
|
||||
foreach (DayOfWeek day in reordereddays)
|
||||
{
|
||||
//Debug.WriteLine($"----- day = {day}");
|
||||
WeekDaysTypes? wday = day.ToWeekDaysTypes();
|
||||
if (WeekDays.HasFlag(wday.Value))
|
||||
{
|
||||
//Debug.WriteLine($"wday has flag {wday.Value}");
|
||||
//Debug.WriteLine($"+ Add day - {days.TotalDays}");
|
||||
days = days.Add(TimeSpan.FromDays(1));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.WriteLine($"++ Add day - {days.TotalDays}");
|
||||
days = days.Add(TimeSpan.FromDays(1));
|
||||
}
|
||||
}
|
||||
//Debug.WriteLine($"Total Days = {days.TotalDays}");
|
||||
//Debug.WriteLine($"Total Days = {days.Days}");
|
||||
|
||||
TimeSpan remaining = time - currentDateTime.TimeOfDay;
|
||||
//Debug.WriteLine($"Remaining {remaining.TotalSeconds} sec - {remaining.TotalHours} hr");
|
||||
days = days.Add(remaining);
|
||||
//Debug.WriteLine($"Days = {days.TotalDays}");
|
||||
return days;
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeSpan RemainingTimeOffDay(TimeSpan time, TimeSpan currentTime)
|
||||
{
|
||||
TimeSpan remaining = time - currentTime;
|
||||
//Debug.WriteLine($"Remaining {remaining.TotalSeconds} sec - {remaining.TotalHours} hr");
|
||||
if (remaining.TotalSeconds < 0)
|
||||
{
|
||||
remaining = remaining.Add(TimeSpan.FromDays(1));
|
||||
}
|
||||
//Debug.WriteLine($"Remaining +24hr {remaining.TotalSeconds} sec - {remaining.TotalHours} hr");
|
||||
return remaining;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,4 +189,7 @@
|
||||
<data name="TamperState" xml:space="preserve">
|
||||
<value>Tamper status</value>
|
||||
</data>
|
||||
<data name="DoorModeSchedules" xml:space="preserve">
|
||||
<value>Deur stand planning</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -189,4 +189,7 @@
|
||||
<data name="TamperState" xml:space="preserve">
|
||||
<value>Tamper status</value>
|
||||
</data>
|
||||
<data name="DoorModeSchedules" xml:space="preserve">
|
||||
<value>Door mode schedules</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -24,4 +24,23 @@ namespace Aperio_Control_Centre.ACSDatabase.Types
|
||||
[Display(Name = "Dagelijks")]
|
||||
Daily = 128
|
||||
}
|
||||
|
||||
public static class WeekDaysTypesExtensions
|
||||
{
|
||||
public static WeekDaysTypes ToWeekDaysTypes(this DayOfWeek value)
|
||||
{
|
||||
// insert switch statement here
|
||||
return value switch
|
||||
{
|
||||
DayOfWeek.Monday => WeekDaysTypes.Monday,
|
||||
DayOfWeek.Tuesday => WeekDaysTypes.Tuesday,
|
||||
DayOfWeek.Wednesday => WeekDaysTypes.Wednesday,
|
||||
DayOfWeek.Thursday => WeekDaysTypes.Thursday,
|
||||
DayOfWeek.Friday => WeekDaysTypes.Friday,
|
||||
DayOfWeek.Saturday => WeekDaysTypes.Saturday,
|
||||
DayOfWeek.Sunday => WeekDaysTypes.Sunday,
|
||||
_ => WeekDaysTypes.None,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace Aperio_Control_Centre.Aadp.Commands
|
||||
{
|
||||
public class CommandIdBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A unique ID for this Device Group
|
||||
/// </summary>
|
||||
public Id DeviceGroupId { get; protected set; } = new();
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,30 @@ using System.Text;
|
||||
|
||||
namespace Aperio_Control_Centre.Aadp.Commands.DoorControl
|
||||
{
|
||||
/// <summary>
|
||||
/// SetDoorModeCommand asks the Door (or Device Group) to change its door mode.
|
||||
/// The door mode is the behavior of the entire door setup; it may affect more than one device.
|
||||
/// The new door mode can either have a specified duration or be valid until a new SetDoorModeCommand is sent.
|
||||
/// This is selected by setting the Timing type in the Duration field to TIME and Duration
|
||||
/// Time to the desired duration, setting Duration Mode to INFINITE or DEFAULT will result in
|
||||
/// INFINITE duration.If choosing a specific time, the door will change to its most restrictive mode after the specified duration.
|
||||
/// All modes might not be supported by all doors; the command should be implemented with a best effort approach.
|
||||
/// </summary>
|
||||
public class SetDoorModeCommand : CommandIdBase, IPduCommand
|
||||
{
|
||||
public Enumerations.PDUTypes PDUType => Enumerations.PDUTypes.SetDoorModeCommand;
|
||||
|
||||
/// <summary>
|
||||
/// Door mode to set.
|
||||
/// </summary>
|
||||
public Enumerations.DoorMode Mode { get; set; }
|
||||
/// <summary>
|
||||
/// The duration of this door mode.
|
||||
/// </summary>
|
||||
public Timing Duration { get; set; } = new();
|
||||
/// <summary>
|
||||
/// When the door mode command shall be executed.
|
||||
/// </summary>
|
||||
public Enumerations.ExecuteMode Exec { get; set; }
|
||||
|
||||
public SetDoorModeCommand() { }
|
||||
@@ -20,6 +38,13 @@ namespace Aperio_Control_Centre.Aadp.Commands.DoorControl
|
||||
// Duration = new Timing(time, mode);
|
||||
// Exec = execute;
|
||||
//}
|
||||
//public SetDoorModeCommand(DeviceId deviceId, Enumerations.DoorMode doorMode, uint time, Enumerations.TimingMode mode, Enumerations.ExecuteMode execute)
|
||||
//{
|
||||
// DeviceGroupId = deviceId.ToId();
|
||||
// Mode = doorMode;
|
||||
// Duration = new Timing(time, mode);
|
||||
// Exec = execute;
|
||||
//}
|
||||
public SetDoorModeCommand(Id id, Enumerations.DoorMode doorMode, uint time, Enumerations.TimingMode mode, Enumerations.ExecuteMode execute)
|
||||
{
|
||||
DeviceGroupId = id;
|
||||
@@ -27,6 +52,13 @@ namespace Aperio_Control_Centre.Aadp.Commands.DoorControl
|
||||
Duration = new Timing(time, mode);
|
||||
Exec = execute;
|
||||
}
|
||||
public SetDoorModeCommand(Id id, Enumerations.DoorMode doorMode, Enumerations.ExecuteMode execute)
|
||||
{
|
||||
DeviceGroupId = id;
|
||||
Mode = doorMode;
|
||||
Duration = new Timing(0, Enumerations.TimingMode.INFINITE);
|
||||
Exec = execute;
|
||||
}
|
||||
|
||||
public void Deserialize(ref byte[] arr, ref int idx)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes if a credential was granted access or not.
|
||||
/// </summary>
|
||||
public enum AccessDecision : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Access Denied
|
||||
/// </summary>
|
||||
DENIED = 0,
|
||||
/// <summary>
|
||||
/// Access Granted
|
||||
/// </summary>
|
||||
GRANTED = 1,
|
||||
/// <summary>
|
||||
/// Reserved, do not use
|
||||
/// </summary>
|
||||
RESERVED = 2,
|
||||
/// <summary>
|
||||
/// Reserved, do not use
|
||||
/// </summary>
|
||||
RESERVED1 = 3,
|
||||
/// <summary>
|
||||
/// Credential was not valid alone (typically a PIN is needed also)
|
||||
/// </summary>
|
||||
ANOTHER_CREDENTIAL_REQUESTED = 4,
|
||||
/// <summary>
|
||||
/// Access decision is not applicable (no credential data in message)
|
||||
/// </summary>
|
||||
NOT_APPLICABLE = 127
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,51 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes what triggered the message CredentialManagementNotification.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum CredentialManagementNotificationType : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Don’t use.
|
||||
/// </summary>
|
||||
RESERVED = 0x00,
|
||||
/// <summary>
|
||||
/// Credential has been added to storage.
|
||||
/// Response to add credential.
|
||||
/// </summary>
|
||||
CREDENTIAL_ADDED = 0x01,
|
||||
/// <summary>
|
||||
/// A single credential has been deleted.
|
||||
/// Response to delete credential.
|
||||
/// </summary>
|
||||
SINGLE_CREDENTIAL_DELETED = 0x02,
|
||||
/// <summary>
|
||||
/// All credentials have been deleted.
|
||||
/// Response to delete credential.
|
||||
/// </summary>
|
||||
ALL_CREDENTIALS_DELETED = 0x03,
|
||||
/// <summary>
|
||||
/// All dynamically added credentials have been deleted.
|
||||
/// Response to delete credential.
|
||||
/// </summary>
|
||||
ALL_DYNAMIC_CREDENTIALS_DELETED = 0x04,
|
||||
/// <summary>
|
||||
/// All statically added credentials have been deleted.
|
||||
/// Response to delete credential.
|
||||
/// </summary>
|
||||
ALL_STATIC_CREDENTIALS_DELETED = 0x05,
|
||||
/// <summary>
|
||||
/// Initiated by device, packet sequence number is zero.
|
||||
/// </summary>
|
||||
CREDENTIAL_DATABASE_UPDATED = 0x06,
|
||||
/// <summary>
|
||||
/// Generic failure, no further details.
|
||||
/// </summary>
|
||||
FAIL = 0x80,
|
||||
/// <summary>
|
||||
/// Device indicates that storage is full.
|
||||
/// </summary>
|
||||
FAILED_STORAGE_FULL = 0x81
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// The DoorSide describes which side of a door a certain state or event is related to.
|
||||
/// </summary>
|
||||
public enum DoorSide : int
|
||||
{
|
||||
/// <summary>
|
||||
/// DoorSide is not known or irrelevant.
|
||||
/// </summary>
|
||||
UNKNOWN = 0,
|
||||
/// <summary>
|
||||
/// DoorSide is on the inside, or the secure side.
|
||||
/// </summary>
|
||||
INSIDE = 1,
|
||||
/// <summary>
|
||||
/// oorSide is on the outside, or the unsecure side.
|
||||
/// </summary>
|
||||
OUTSIDE = 2,
|
||||
/// <summary>
|
||||
/// Both sides.
|
||||
/// </summary>
|
||||
BOTH = 3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// The DoorState describes the state of the door, i.e. if the door is open or closed.
|
||||
/// </summary>
|
||||
public enum DoorState : int
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of the door is unknown
|
||||
/// </summary>
|
||||
UNKNOWN = 0,
|
||||
/// <summary>
|
||||
/// At least one door monitoring sensor reports that the door is open
|
||||
/// </summary>
|
||||
OPEN = 1,
|
||||
/// <summary>
|
||||
/// All door monitoring sensors report that the door is closed
|
||||
/// </summary>
|
||||
CLOSED = 2,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// An ExecuteMode defines a command execution mode. The execution mode indicates the
|
||||
@@ -10,15 +13,18 @@
|
||||
/// As soon as possible.
|
||||
/// If the command cannot be executed immediately, it may be done later.
|
||||
/// </summary>
|
||||
[Display(Name = "zo snel mogelijk")]
|
||||
ASAP = 0,
|
||||
/// <summary>
|
||||
/// Must be performed immediately after the message is
|
||||
/// received, it is not allowed to be performed at a later time.
|
||||
/// </summary>
|
||||
[Display(Name = "onmiddellijk")]
|
||||
IMMEDIATE = 1,
|
||||
/// <summary>
|
||||
/// Perform at next door opening sequence.
|
||||
/// </summary>
|
||||
[Display(Name = "volgende deur beweging")]
|
||||
DOORSEQUENCE = 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,88 @@
|
||||
namespace Aperio_Control_Centre.Aadp.Enumerations
|
||||
{
|
||||
/// <summary>
|
||||
/// The Indication identifies a type of indication.
|
||||
/// These values represent the logical indication, i.e.the message conveyed to the user.
|
||||
/// They do not specify the behavior in terms of visual and audible devices used to perform the indication.
|
||||
/// The specific behavior depends on the door equipment.
|
||||
/// </summary>
|
||||
public enum Indication : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Enter PIN / use keypad
|
||||
/// </summary>
|
||||
KEYPAD = 0,
|
||||
/// <summary>
|
||||
/// Show card / use tag
|
||||
/// </summary>
|
||||
USE_TAG = 1,
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// </summary>
|
||||
RESERVED1 = 2,
|
||||
/// <summary>
|
||||
/// Access Granted
|
||||
/// </summary>
|
||||
GRANTED = 3,
|
||||
/// <summary>
|
||||
/// Access Denied
|
||||
/// </summary>
|
||||
DENIED = 4,
|
||||
/// <summary>
|
||||
/// Back light
|
||||
/// </summary>
|
||||
BACKLIGHT = 5,
|
||||
/// <summary>
|
||||
/// Alarm armed
|
||||
/// </summary>
|
||||
ARMED = 6,
|
||||
/// <summary>
|
||||
/// Alarm disarmed
|
||||
/// </summary>
|
||||
DISARMED = 7,
|
||||
/// <summary>
|
||||
/// Application defined 1
|
||||
/// </summary>
|
||||
APPL1 = 8,
|
||||
/// <summary>
|
||||
/// Application defined 2
|
||||
/// </summary>
|
||||
APPL2 = 9,
|
||||
/// <summary>
|
||||
/// Application defined 3
|
||||
/// </summary>
|
||||
APPL3 = 10,
|
||||
/// <summary>
|
||||
/// Door held open for too long
|
||||
/// </summary>
|
||||
DOOR_HELD = 11,
|
||||
/// <summary>
|
||||
/// Door forced open without being unlocked first
|
||||
/// </summary>
|
||||
DOOR_FORCED = 12,
|
||||
/// <summary>
|
||||
/// User attention is required by external system
|
||||
/// </summary>
|
||||
USER_ATTENTION = 13,
|
||||
/// <summary>
|
||||
/// The Fire Alarm has been triggered
|
||||
/// </summary>
|
||||
FIRE_ALARM = 14,
|
||||
/// <summary>
|
||||
/// Emit a beacon signal for low visibility (smoke) guidance
|
||||
/// </summary>
|
||||
BEACON_SIGNAL = 15,
|
||||
/// <summary>
|
||||
/// Burglary alarm has been triggered
|
||||
/// </summary>
|
||||
BURGLARY_ALARM = 16,
|
||||
/// <summary>
|
||||
/// The Panic Alarm has been triggered
|
||||
/// </summary>
|
||||
PANIC_ALARM = 17,
|
||||
/// <summary>
|
||||
/// Acknowledge input from user
|
||||
/// </summary>
|
||||
ACKNOWLEDGE = 18,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,20 @@
|
||||
|
||||
namespace Aperio_Control_Centre.Aadp.Types.ApplicationTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// The Timing describes different timing constraints
|
||||
/// </summary>
|
||||
public class Timing : IPduType
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes how the Time field should be interpreted.
|
||||
/// </summary>
|
||||
public Enumerations.TimingMode Mode { get; set; }
|
||||
/// <summary>
|
||||
/// The time specified in deciseconds i.e. 10ths of seconds.
|
||||
/// This value is only relevant if Mode is TIME.
|
||||
/// The field is either way included in the message.
|
||||
/// </summary>
|
||||
public VariableLengthQuantity Time { get; set; } = new();
|
||||
|
||||
public Timing() { }
|
||||
|
||||
@@ -54,10 +54,9 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
_connection = connection;
|
||||
}
|
||||
|
||||
public Task RemoveConnection()
|
||||
public void RemoveConnection()
|
||||
{
|
||||
Debug.WriteLine("TestingAperioConnectionContext RemoveConnection");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task Receive(CancellationTokenSource linkedCts)
|
||||
|
||||
@@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingAperioHubDevice : IAperioHubDevice
|
||||
internal sealed class TestingAperioHubDevice : IAperioHubDevice
|
||||
{
|
||||
private IAperioConnectionContext? _connection;
|
||||
private DeviceId _deviceId;
|
||||
|
||||
@@ -6,6 +6,7 @@ using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.AperioServer;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,7 +15,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingAperioLockDevice : IAperioLockDevice
|
||||
internal sealed class TestingAperioLockDevice : IAperioLockDevice
|
||||
{
|
||||
private IAperioConnectionContext? _connection;
|
||||
private DeviceId _deviceId;
|
||||
@@ -56,6 +57,8 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
|
||||
public HandleState HandleState => throw new NotImplementedException();
|
||||
|
||||
public List<SchedulerItem> DoorModeSchedules => throw new NotImplementedException();
|
||||
|
||||
public event EventHandler? DeviceChanged;
|
||||
|
||||
public Task ClearDTCOnDevice(uint dtcId, CancellationToken token)
|
||||
@@ -217,5 +220,15 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task LoadDoorModeSchedule(CancellationToken token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
//public void SetDoorModeOnDevice(DoorMode? doorMode)
|
||||
//{
|
||||
// throw new NotImplementedException();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.AperioServer;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,7 +15,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingAperioOptaDevice : IAperioOptaDevice
|
||||
internal sealed class TestingAperioOptaDevice : IAperioOptaDevice
|
||||
{
|
||||
private IAperioConnectionContext? _connection;
|
||||
private DeviceId _deviceId;
|
||||
@@ -51,6 +52,8 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
public ActivatorState EmergencyInsideState { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
public ActivatorState EmergencyOutsideState { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
public List<SchedulerItem> DoorModeSchedules => throw new NotImplementedException();
|
||||
|
||||
public event EventHandler? DeviceChanged;
|
||||
|
||||
public Task ClearDTCOnDevice(uint dtcId, CancellationToken token)
|
||||
@@ -190,5 +193,15 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task LoadDoorModeSchedule(CancellationToken token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
//public void SetDoorModeOnDevice(DoorMode? doorMode)
|
||||
//{
|
||||
// throw new NotImplementedException();
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingAperioTimeoutFeature : IAperioTimeoutFeature
|
||||
internal sealed class TestingAperioTimeoutFeature : IAperioTimeoutFeature
|
||||
{
|
||||
public DateTime GetStartTime => DateTime.Now;
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Aperio_Control_Centre.Aadp.Types;
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.AperioServer;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingDeviceList : IAperioDeviceList
|
||||
internal sealed class TestingDeviceList : IAperioDeviceList
|
||||
{
|
||||
public event EventHandler DeviceListChanged;
|
||||
|
||||
@@ -47,6 +49,11 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
return [];
|
||||
}
|
||||
|
||||
public IEnumerable<SchedulerItem> GetSchedules()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveConnection(IAperioConnectionContext conn)
|
||||
{
|
||||
Debug.WriteLine("RemoveConnection");
|
||||
@@ -57,5 +64,10 @@ namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
Debug.WriteLine("RemoveDevice");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
IEnumerable<DoorModeSchedule> IAperioDeviceList.GetSchedules()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingLogger<T> : ILogger<T>
|
||||
internal sealed class TestingLogger<T> : ILogger<T>
|
||||
{
|
||||
public List<string> Messages { get; } = [];
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ using Aperio_Control_Centre.ScreenLogging;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingScreenLoggerBridge : IScreenLoggerBridge
|
||||
internal sealed class TestingScreenLoggerBridge : IScreenLoggerBridge
|
||||
{
|
||||
public List<string> Messages { get; } = [];
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using System.Diagnostics;
|
||||
|
||||
namespace Aperio_Control_Centre.UnitTest.AperioServer.Setups
|
||||
{
|
||||
internal class TestingServerInfoService : IServerInfoService
|
||||
internal sealed class TestingServerInfoService : IServerInfoService
|
||||
{
|
||||
public List<string> Messages { get; } = [];
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace Aperio_Control_Centre.ACSCredentials
|
||||
.Include(l => l.Location)
|
||||
.Include(t => t.UnlockTimezone)
|
||||
.Include(d => d.DeviceGroups)
|
||||
.Include(s => s.DoorModeSchedules!).ThenInclude(t => t.Timezone)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (Device == null)
|
||||
|
||||
53
Aperio_Control_Centre/AperioServer/AperioAlarmClock.cs
Normal file
53
Aperio_Control_Centre/AperioServer/AperioAlarmClock.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
//using System.Diagnostics;
|
||||
//using System.Timers;
|
||||
|
||||
//namespace Aperio_Control_Centre.AperioServer
|
||||
//{
|
||||
// public sealed class AperioAlarmClock : IDisposable
|
||||
// {
|
||||
// private System.Timers.Timer alarmTimer;
|
||||
|
||||
// public void Dispose()
|
||||
// {
|
||||
// //throw new NotImplementedException();
|
||||
// alarmTimer.Dispose();
|
||||
// }
|
||||
|
||||
// public void SetAlarm(DateTime alarmTime)
|
||||
// {
|
||||
// Debug.WriteLine($"Enter the alarm time (HH:mm): {alarmTime}");
|
||||
// //string inputTime = Console.ReadLine();
|
||||
|
||||
// //if (DateTime.TryParse(inputTime, out DateTime alarmTime))
|
||||
// //{
|
||||
// //DateTime now = DateTime.Now;
|
||||
// TimeSpan timeToAlarm = alarmTime - DateTime.Now;
|
||||
|
||||
// if (timeToAlarm < TimeSpan.Zero)
|
||||
// {
|
||||
// timeToAlarm = timeToAlarm.Add(TimeSpan.FromDays(1)); // Set for the next day
|
||||
// }
|
||||
|
||||
// Debug.WriteLine($"Alarm set for {alarmTime.TimeOfDay}. It will ring in {timeToAlarm.TotalSeconds} seconds.");
|
||||
|
||||
// alarmTimer = new System.Timers.Timer(timeToAlarm.TotalMilliseconds);
|
||||
// alarmTimer.Elapsed += OnAlarmTriggered;
|
||||
// alarmTimer.AutoReset = false; // Trigger only once
|
||||
// alarmTimer.Start();
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // Debug.WriteLine("Invalid time format. Please use HH:mm.");
|
||||
// //}
|
||||
|
||||
// //Debug.WriteLine("Press Enter to exit...");
|
||||
// //Console.ReadLine();
|
||||
// }
|
||||
|
||||
// private void OnAlarmTriggered(object? sender, ElapsedEventArgs e)
|
||||
// {
|
||||
// Debug.WriteLine("ALARM! Time to wake up!");
|
||||
// alarmTimer.Dispose(); // Clean up the timer
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -7,6 +7,7 @@ using Aperio_Control_Centre.Aadp.Types;
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models.Extensions;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Log;
|
||||
@@ -20,6 +21,8 @@ using System.Buffers;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net;
|
||||
using System.Security.Principal;
|
||||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
||||
|
||||
namespace Aperio_Control_Centre.AperioServer
|
||||
{
|
||||
@@ -40,7 +43,7 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
public IDuplexPipe Transport { get => _connection.Transport; set => _connection.Transport = value; }
|
||||
public IPAddress Address { get => ((IPEndPoint)_connection.RemoteEndPoint!).Address; }
|
||||
|
||||
|
||||
|
||||
|
||||
public AperioConnectionContext(
|
||||
IAperioDeviceList devicesList,
|
||||
@@ -73,7 +76,7 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
}, connection);
|
||||
}
|
||||
|
||||
public async Task RemoveConnection()
|
||||
public void RemoveConnection()
|
||||
{
|
||||
_connection.Features.Get<IAperioTimeoutFeature>()?.Dispose();
|
||||
|
||||
@@ -166,16 +169,29 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
}
|
||||
}
|
||||
|
||||
//Instantiate a Singleton of the Semaphore with a value of 1. This means that only 1 thread can be granted access at a time.
|
||||
private static readonly SemaphoreSlim _writeSemaphoreSlim = new(1, 1);
|
||||
public async Task WriteToDevice(IPduCommand command, CancellationToken token)
|
||||
{
|
||||
await Transport.Output.WriteAsync(PduMessage.Serialize(command), token);
|
||||
_screenLogger.AddScreenlog(new AperioScreenLog()
|
||||
//Asynchronously wait to enter the Semaphore. If no-one has been granted access to the Semaphore, code execution will proceed, otherwise this thread waits here until the semaphore is released
|
||||
await _writeSemaphoreSlim.WaitAsync(token);
|
||||
try
|
||||
{
|
||||
IPAddress = Address,
|
||||
Direction = LogDirections.TX,
|
||||
PDUType = command.PDUType,
|
||||
Message = command.LogString()
|
||||
});
|
||||
await Transport.Output.WriteAsync(PduMessage.Serialize(command), token);
|
||||
_screenLogger.AddScreenlog(new AperioScreenLog()
|
||||
{
|
||||
IPAddress = Address,
|
||||
Direction = LogDirections.TX,
|
||||
PDUType = command.PDUType,
|
||||
Message = command.LogString()
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
//When the task is ready, release the semaphore. It is vital to ALWAYS release the semaphore when we are ready, or else we will end up with a Semaphore that is forever locked.
|
||||
//This is why it is important to do the Release within a try...finally clause; program execution may crash or take a different path, this way you are guaranteed execution
|
||||
_writeSemaphoreSlim.Release();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------- Aperio Data handeling ------------------------------------------------------
|
||||
@@ -234,14 +250,14 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
case GetDeviceParameterResult command:
|
||||
foreach (DeviceParameterNotificationBlock block in command.ParameterResultBlock)
|
||||
{
|
||||
await DeviceParameterAction(command.Device, block, token);
|
||||
DeviceParameterAction(command.Device, block);
|
||||
}
|
||||
break;
|
||||
|
||||
case DeviceParameterNotification command:
|
||||
foreach (DeviceParameterNotificationBlock block in command.ParameterNotificationBlock)
|
||||
{
|
||||
await DeviceParameterAction(command.Device, block, token);
|
||||
DeviceParameterAction(command.Device, block);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -249,28 +265,40 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
|
||||
if (pducommand is CommandDeviceIdBase deviceid)
|
||||
{
|
||||
Debug.WriteLine($"----> CommandDeviceIdBase - {pducommand.PDUType} - {deviceid.Device.ToIdString()}");
|
||||
//Debug.WriteLine($"----> CommandDeviceIdBase - {pducommand.PDUType} - {deviceid.Device.ToIdString()}");
|
||||
|
||||
|
||||
IAperioBase? device = _devicesList.GetDevice(deviceid.Device);
|
||||
if (device != null)
|
||||
if (_devicesList.GetDevice(deviceid.Device) is IAperioBase device)
|
||||
{
|
||||
await device.SetConnectionState(ConnectionStates.Online, token);
|
||||
await device.SetConnection(this, token);
|
||||
await device.HandleMessage(pducommand, token);
|
||||
}
|
||||
|
||||
//IAperioBase? device = _devicesList.GetDevice(deviceid.Device);
|
||||
//if (device != null)
|
||||
//{
|
||||
// await device.SetConnectionState(ConnectionStates.Online, token);
|
||||
// await device.SetConnection(this, token);
|
||||
// await device.HandleMessage(pducommand, token);
|
||||
//}
|
||||
}
|
||||
else if (pducommand is CommandIdBase id)
|
||||
{
|
||||
Debug.WriteLine($"----> CommandIdBase - {pducommand.PDUType} - {id.DeviceGroupId.Charaters}");
|
||||
//Debug.WriteLine($"----> CommandIdBase - {pducommand.PDUType} - {id.DeviceGroupId.Charaters}");
|
||||
|
||||
IAperioBase? device = _devicesList.GetDevice(id.DeviceGroupId);
|
||||
if (device != null)
|
||||
if (_devicesList.GetDevice(id.DeviceGroupId) is IAperioBase device)
|
||||
{
|
||||
await device.SetConnectionState(ConnectionStates.Online, token);
|
||||
await device.SetConnection(this, token);
|
||||
await device.HandleMessage(pducommand, token);
|
||||
}
|
||||
//IAperioBase? device = _devicesList.GetDevice(id.DeviceGroupId);
|
||||
//if (device != null)
|
||||
//{
|
||||
// await device.SetConnectionState(ConnectionStates.Online, token);
|
||||
// await device.SetConnection(this, token);
|
||||
// await device.HandleMessage(pducommand, token);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -318,7 +346,13 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
if (device != null)
|
||||
{
|
||||
device.ConnectionState = ConnectionStates.Offline;
|
||||
await db.DisableDevice(device, null, token);
|
||||
|
||||
device.Active = ActiveStates.Inactive;
|
||||
device.LastChanged = DateTime.UtcNow;
|
||||
await db.Loggings.AddLogAsync(device, "Geblokkeerd", LogTypes.Device, token);
|
||||
|
||||
|
||||
//await db.DisableDevice(device, null, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
}
|
||||
@@ -344,18 +378,22 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
}
|
||||
|
||||
|
||||
private async Task DeviceParameterAction(DeviceId devId, DeviceParameterNotificationBlock block, CancellationToken token)
|
||||
private void DeviceParameterAction(DeviceId devId, DeviceParameterNotificationBlock block)
|
||||
{
|
||||
Debug.WriteLine($"Device Parameter {block.Name.Name} - {block.Type} - {block.Value} {block.Result}");
|
||||
|
||||
//if (string.Compare(block.Name.Name, "FwVersion") == 0)
|
||||
if (block.Name.Name.Equals("FwVersion", StringComparison.Ordinal))
|
||||
{
|
||||
IAperioBase? device = _devicesList.GetDevice(devId);
|
||||
if (device != null)
|
||||
if (_devicesList.GetDevice(devId) is IAperioBase device)
|
||||
{
|
||||
device.FirmwareVersion = block.GetValue<string>() ?? string.Empty;
|
||||
}
|
||||
//IAperioBase? device = _devicesList.GetDevice(devId);
|
||||
//if (device != null)
|
||||
//{
|
||||
// device.FirmwareVersion = block.GetValue<string>() ?? string.Empty;
|
||||
//}
|
||||
|
||||
}
|
||||
else if (block.Name.Name.Equals("LockVersions", StringComparison.Ordinal))
|
||||
@@ -367,11 +405,15 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
{
|
||||
LockVersion lockVersion = new(arr);
|
||||
//Debug.WriteLine($"LOCKVERSION this:{devId} - parameter:{lockVersion.Id.ToId()} - {lockVersion.Version}");
|
||||
IAperioBase? device = _devicesList.GetDevice(lockVersion.Id);
|
||||
if (device != null)
|
||||
if (_devicesList.GetDevice(lockVersion.Id) is IAperioBase device)
|
||||
{
|
||||
device.LockVersion = lockVersion.Version;
|
||||
}
|
||||
//IAperioBase? device = _devicesList.GetDevice(lockVersion.Id);
|
||||
//if (device != null)
|
||||
//{
|
||||
// device.LockVersion = lockVersion.Version;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
Logger.LogError(_logger, $"{aperioConnection.Address} - {aperioConnection.ConnectionId}", ex);
|
||||
}
|
||||
|
||||
await aperioConnection.RemoveConnection();
|
||||
aperioConnection.RemoveConnection();
|
||||
|
||||
_screenLogging.AddScreenlog(new SystemScreenLog()
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Components.Aperio;
|
||||
using Aperio_Control_Centre.Log;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using Aperio_Control_Centre.ScreenLogging;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
@@ -33,6 +34,19 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
return _deviceDictionary.Values.Where(c => c.Connection != null).Select(c => c.Connection).GroupBy(c => c.ConnectionId).Select(g => g.First());
|
||||
}
|
||||
|
||||
public IEnumerable<DoorModeSchedule> GetSchedules()
|
||||
{
|
||||
//IEnumerable<SchedulerItem> ksldfkd = _deviceDictionary.Values.OfType<IAperioDoor>().SelectMany(s => s.DoorModeSchedules);
|
||||
|
||||
//foreach (var kvp in ksldfkd)
|
||||
//{
|
||||
// Debug.WriteLine($"Scheduler item = {kvp.DoorModeSchedule.Timezone.BeginTime} - {kvp.DoorModeSchedule.Timezone.EndTime} - {kvp.DoorModeSchedule.DoorMode} - {kvp.DoorModeSchedule.ExecuteMode} - {kvp.DoorModeSchedule.Device.Name}");
|
||||
//}
|
||||
|
||||
return _deviceDictionary.Values.OfType<IAperioDoor>().SelectMany(s => s.DoorModeSchedules).Select(s => s.DoorModeSchedule);
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<IAperioBase> GetDevices(string connectionId)
|
||||
{
|
||||
return _deviceDictionary.Values.Where(c => c.Connection?.ConnectionId == connectionId);
|
||||
@@ -182,6 +196,6 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
{
|
||||
Message = $"Removed {devId} from devicelist"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
|
||||
public void ResetTimeout()
|
||||
{
|
||||
Debug.WriteLine("AperioTimeoutFeature Reset timeout");
|
||||
//Debug.WriteLine("AperioTimeoutFeature Reset timeout");
|
||||
_timeoutCounter = _timeoutValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,23 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//protected private async Task<int?> GetDatabaseDeviceId(ACSDatabaseContext db, CancellationToken token)
|
||||
//{
|
||||
// if (DataBaseDeviceID != 0)
|
||||
// {
|
||||
// //return await db.Devices.FindAsync([DataBaseDeviceID], token);
|
||||
// return DataBaseDeviceID;
|
||||
// }
|
||||
// Device? device = await db.Devices.GetDeviceFromString(_deviceId.ToIdString(), token);
|
||||
// if (device != null)
|
||||
// {
|
||||
// DataBaseDeviceID = device.Id;
|
||||
// Name = device.Name;
|
||||
// //return device;
|
||||
// return DataBaseDeviceID;
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
|
||||
public virtual Task GetStatusFromDevice(CancellationToken token)
|
||||
{
|
||||
@@ -196,13 +213,14 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
DeviceStatus = deviceStatus;
|
||||
//Debug.WriteLine($"DeviceStatus Changed to {_deviceStatus}");
|
||||
|
||||
using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
Device? dbDevice = await GetDatabaseDevice(db, token);
|
||||
if (dbDevice != null)
|
||||
{
|
||||
await db.Loggings.AddLogAsync(dbDevice, DeviceStatus, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
//TODO: Device status in db opslaan??, veel meldingen
|
||||
//using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
//Device? dbDevice = await GetDatabaseDevice(db, token);
|
||||
//if (dbDevice != null)
|
||||
//{
|
||||
// await db.Loggings.AddLogAsync(dbDevice, DeviceStatus, token);
|
||||
// await db.SaveChangesAsync(token);
|
||||
//}
|
||||
_screenLogger.AddScreenlog(new SystemScreenLog()
|
||||
{
|
||||
IPAddress = Connection?.Address,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Aperio_Control_Centre.Aadp.Commands.DeviceStates;
|
||||
using Aperio_Control_Centre.Aadp.Commands.DoorControl;
|
||||
using Aperio_Control_Centre.Aadp.Commands.InputFromUser;
|
||||
using Aperio_Control_Centre.Aadp.Commands.OperationAndMaintenance;
|
||||
using Aperio_Control_Centre.Aadp.Commands.OutputToUser;
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
@@ -11,6 +10,8 @@ using Aperio_Control_Centre.ACSDatabase;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models.Extensions;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.Extensions;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using Aperio_Control_Centre.ScreenLogging;
|
||||
using Aperio_Control_Centre.StatusBroadcast;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -39,6 +40,7 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
dbDevice.DoorModes = _doorModes;
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
RaiseDeviceChanged();
|
||||
}
|
||||
|
||||
public async Task GetSupportedDoorModesFromDevice(CancellationToken token)
|
||||
@@ -65,6 +67,141 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
await SaveDoorModeToDatabase(token);
|
||||
}
|
||||
|
||||
//------------- Door mode scheduler ---------------------------------
|
||||
|
||||
//public void SetDoorModeOnDevice(DoorMode? doorMode)
|
||||
//{
|
||||
// Debug.WriteLine($"Set door mode on device {Name} - {doorMode}");
|
||||
// //if (checker.Device.DoorModes.Where(m => m.DoorMode is DoorMode.FREE_OPEN).Any())
|
||||
// //{
|
||||
// // await WriteToDevice(new SetDoorModeCommand(new Id(_deviceId.ToIdString()), DoorMode.FREE_OPEN, checker.Device!.OpenTimeFromNowDeciseconds(), TimingMode.TIME, ExecuteMode.ASAP), token);
|
||||
// //}
|
||||
// //else if (checker.Device.DoorModes.Where(m => m.DoorMode is DoorMode.FREE_UNLOCKED).Any())
|
||||
// //{
|
||||
// // await WriteToDevice(new SetDoorModeCommand(new Id(_deviceId.ToIdString()), DoorMode.FREE_UNLOCKED, checker.Device!.OpenTimeFromNowDeciseconds(), TimingMode.TIME, ExecuteMode.ASAP), token);
|
||||
// //}
|
||||
// //else
|
||||
// //{
|
||||
// // Debug.WriteLine("Not supportted door mode");
|
||||
// //}
|
||||
//}
|
||||
|
||||
|
||||
public List<SchedulerItem> DoorModeSchedules { get; private set; } = [];
|
||||
//private readonly List<SchedulerItem> _schedulerItems = [];
|
||||
//public List<SchedulerItem> GetDoorModeSchedule()
|
||||
//{
|
||||
// return _schedulerItems;
|
||||
//}
|
||||
public async Task LoadDoorModeSchedule(CancellationToken token)
|
||||
{
|
||||
Debug.WriteLine("Load DoorModeSchedule In AperioDoor");
|
||||
|
||||
if (DoorModeSchedules.Count != 0)
|
||||
{
|
||||
foreach (var item in DoorModeSchedules)
|
||||
{
|
||||
if (item.BeginTimer != null)
|
||||
{
|
||||
item.BeginTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
await item.BeginTimer.DisposeAsync();
|
||||
}
|
||||
if (item.EndTimer != null)
|
||||
{
|
||||
item.EndTimer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
await item.EndTimer.DisposeAsync();
|
||||
}
|
||||
}
|
||||
DoorModeSchedules.Clear();
|
||||
}
|
||||
|
||||
//await WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), DoorMode.INSIDEOUT_LOCKED, ExecuteMode.ASAP), token);
|
||||
|
||||
|
||||
using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
List<DoorModeSchedule> schedules = await db.DoorModeSchedules
|
||||
.Where(d => d.DeviceId == DataBaseDeviceID)
|
||||
.Include(t => t.Timezone)
|
||||
.Include(d => d.Device)
|
||||
.ToListAsync(token);
|
||||
|
||||
foreach (DoorModeSchedule item in schedules)
|
||||
{
|
||||
Debug.WriteLine($"ID:{item.Id} - Timezone:{item.Timezone?.GetTimezoneString} - device:{item.DeviceId} - {item.DoorMode} - {item.Timezone?.TwentyFourHours}");
|
||||
if (item.Timezone?.WeekDays != WeekDaysTypes.None)
|
||||
{
|
||||
SchedulerItem schedulerItem = new()
|
||||
{
|
||||
DoorModeSchedule = item
|
||||
};
|
||||
|
||||
Debug.WriteLine($"Seconds to next begin + 24hr {item.Timezone?.TimeToNextBeginTime().TotalSeconds}");
|
||||
|
||||
schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, item.Timezone!.TimeToNextBeginTime(), Timeout.InfiniteTimeSpan);
|
||||
//schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, TimeSpan.FromSeconds(30), Timeout.InfiniteTimeSpan);
|
||||
if (item.Timezone.IsTimezoneActive())
|
||||
{
|
||||
Debug.WriteLine("Time zone active");
|
||||
await WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), item.DoorMode, item.Timezone.TimeToNextEndTime().ToDeciSeconds(), TimingMode.TIME, item.ExecuteMode), token);
|
||||
}
|
||||
|
||||
if (item.Device?.ProductClass == ProductClass.OPTA_V1)
|
||||
{
|
||||
//Debug.WriteLine($"Seconds to next end + 24hr {item.Timezone.TimeToNextEndTime().TotalSeconds}");
|
||||
//schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, item.Timezone.TimeToNextEndTime(), Timeout.InfiniteTimeSpan);
|
||||
//schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, TimeSpan.FromSeconds(60), Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
|
||||
DoorModeSchedules.Add(schedulerItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BeginTimerCallback(object? state)
|
||||
{
|
||||
Debug.WriteLine("BeginTimerCallback");
|
||||
//Logger.LogInformation(_logger, $"Timed Hosted Service is working.");
|
||||
if (state is SchedulerItem item)
|
||||
{
|
||||
Debug.WriteLine($"{DateTime.Now} -----> BeginTimerCallback {item.DoorModeSchedule.Timezone?.GetTimezoneString} - {item.DoorModeSchedule.Device?.Name} - {item.DoorModeSchedule.DoorMode} - {item.DoorModeSchedule.ExecuteMode} - {item.DoorModeSchedule.Timezone.TimeToNextEndTime().ToDeciSeconds()}");
|
||||
//SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
//WriteToDevice(new SetDoorModeCommand(new Id(_deviceId.ToIdString()), DoorMode.FREE_OPEN, checker.Device!.OpenTimeFromNowDeciseconds(), TimingMode.TIME, ExecuteMode.ASAP), default).Wait();
|
||||
//WriteToDevice(new SetDoorModeCommand(_deviceId, item.DoorModeSchedule.DoorMode.Value, 500, TimingMode.TIME, ExecuteMode.ASAP), default).Wait();
|
||||
WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), item.DoorModeSchedule.DoorMode, item.DoorModeSchedule.Timezone.TimeToNextEndTime().ToDeciSeconds(), TimingMode.TIME, item.DoorModeSchedule.ExecuteMode), default).Wait();
|
||||
|
||||
|
||||
item.BeginTimer = new Timer(BeginTimerCallback, item, item.DoorModeSchedule.Timezone.TimeToNextBeginTime(), Timeout.InfiniteTimeSpan);
|
||||
//item.BeginTimer = new Timer(BeginTimerCallback, item, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
}
|
||||
}
|
||||
|
||||
//private void EndTimerCallback(object? state)
|
||||
//{
|
||||
// Debug.WriteLine("EndTimerCallback");
|
||||
// //Logger.LogInformation(_logger, $"Timed Hosted Service is working.");
|
||||
// if (state is SchedulerItem item)
|
||||
// {
|
||||
// Debug.WriteLine($"{DateTime.Now} <------ EndTimerCallback {item.DoorModeSchedule.Timezone?.GetTimezoneString} - {item.DoorModeSchedule.Device?.Name} - {item.DoorModeSchedule.DoorMode}");
|
||||
|
||||
// //Debug.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}");
|
||||
|
||||
// //SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
// //SetDoorModeOnDevice(DoorMode.INSIDEOUT_LOCKED);
|
||||
|
||||
// //WriteToDevice(new SetDoorModeCommand(_deviceId, DoorMode.INSIDEOUT_LOCKED, 5, TimingMode.INFINITE, ExecuteMode.ASAP), default).Wait();
|
||||
// WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), DoorMode.INSIDEOUT_LOCKED, ExecuteMode.ASAP), default).Wait();
|
||||
|
||||
|
||||
// item.EndTimer = new Timer(EndTimerCallback, item, item.DoorModeSchedule.Timezone.TimeToNextEndTime(), Timeout.InfiniteTimeSpan);
|
||||
// //item.EndTimer = new Timer(EndTimerCallback, item, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------- Door state -----------------------------------------------------
|
||||
public async Task GetDoorStateFromDevice(CancellationToken token)
|
||||
{
|
||||
@@ -101,7 +238,7 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
if (LockState != lockState)
|
||||
{
|
||||
LockState = lockState;
|
||||
//Debug.WriteLine($"Lock state Changed to {_lockState}");
|
||||
Debug.WriteLine($"Lock state Changed to {lockState}");
|
||||
//await _statusBroadcast.SendLockStatus(Id, _lockState, token);
|
||||
using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
Device? dbDevice = await GetDatabaseDevice(db, token);
|
||||
@@ -234,6 +371,12 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
return;
|
||||
}
|
||||
|
||||
if (checker.Device?.DoorModeSchedules != null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
string logstring;
|
||||
if (checker.Device?.UnlockTimezone != null)
|
||||
{
|
||||
@@ -269,9 +412,19 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
}
|
||||
else
|
||||
{
|
||||
await UnlockDoor(checker.Device!.OpenTimeDeciseconds(), token);
|
||||
logstring = $"Toegang {checker.Device.OpenTimeSeconds()} seconden";
|
||||
DoorModeSchedule? doormode = checker.Device?.DoorModeSchedules.GetFirstActiveDoorModeschedule();
|
||||
if(doormode != null)
|
||||
{
|
||||
await WriteToDevice(new SetDoorModeCommand(_deviceId.ToId(), doormode.DoorMode, doormode.Timezone.TimeToNextEndTime().ToDeciSeconds(), TimingMode.TIME, doormode.ExecuteMode), token);
|
||||
logstring = $"Toegang tot {doormode.Timezone.EndTime}";
|
||||
}
|
||||
else
|
||||
{
|
||||
await UnlockDoor(checker.Device!.OpenTimeDeciseconds(), token);
|
||||
logstring = $"Toegang {checker.Device.OpenTimeSeconds()} seconden";
|
||||
}
|
||||
}
|
||||
|
||||
await checker.UserLogMessage(logstring, AccessTypes.Granted, token);
|
||||
await _statusBroadcast.SendWatched(checker.User, checker.Device, true, db, token);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
await base.SetBaseDevice(deviceId, conn, token);
|
||||
HubDeviceId = hostId;
|
||||
await CreateDatabaseDevice(conn.Address.ToIpString(), token);
|
||||
await LoadDoorModeSchedule(token);
|
||||
}
|
||||
|
||||
private async Task CreateDatabaseDevice(string ipaddress, CancellationToken token)
|
||||
@@ -192,14 +193,14 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
HandleState = handleState;
|
||||
//Debug.WriteLine($"Handle state Changed to {_handleState}");
|
||||
|
||||
using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
Device? dbDevice = await GetDatabaseDevice(db, token);
|
||||
if (dbDevice != null)
|
||||
{
|
||||
dbDevice.HandleState = HandleState;
|
||||
await db.Loggings.AddLogAsync(dbDevice, HandleState, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
}
|
||||
//using ACSDatabaseContext db = await _contextFactory.CreateDbContextAsync(token);
|
||||
//Device? dbDevice = await GetDatabaseDevice(db, token);
|
||||
//if (dbDevice != null)
|
||||
//{
|
||||
// dbDevice.HandleState = HandleState;
|
||||
// await db.Loggings.AddLogAsync(dbDevice, HandleState, token);
|
||||
// await db.SaveChangesAsync(token);
|
||||
//}
|
||||
_screenLogger.AddScreenlog(new SystemScreenLog()
|
||||
{
|
||||
IPAddress = Connection?.Address,
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
ArgumentNullException.ThrowIfNull(conn);
|
||||
await base.SetBaseDevice(deviceId, conn, token);
|
||||
await CreateDatabaseDevice(conn.Address.ToIpString(), token);
|
||||
await LoadDoorModeSchedule(token);
|
||||
}
|
||||
|
||||
private async Task CreateDatabaseDevice(string ipaddress, CancellationToken token)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Aperio_Control_Centre.Aadp.Commands.InputFromUser;
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.Models;
|
||||
|
||||
namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
{
|
||||
@@ -10,6 +12,10 @@ namespace Aperio_Control_Centre.AperioServer.Devices
|
||||
|
||||
public Task GetDoorModeFromDevice(CancellationToken token);
|
||||
public DoorMode GetDoorMode();
|
||||
//public void SetDoorModeOnDevice(DoorMode? doorMode);
|
||||
|
||||
public Task LoadDoorModeSchedule(CancellationToken token);
|
||||
public List<SchedulerItem> DoorModeSchedules { get; }
|
||||
|
||||
public Task GetDoorStateFromDevice(CancellationToken token);
|
||||
public DoorState DoorState { get; }
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
public IPAddress Address { get; }
|
||||
|
||||
public void SetConnection(ConnectionContext connection);
|
||||
public Task RemoveConnection();
|
||||
public void RemoveConnection();
|
||||
|
||||
public void Abort(ConnectionAbortedException abortReason);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Models;
|
||||
|
||||
namespace Aperio_Control_Centre.AperioServer
|
||||
{
|
||||
@@ -10,6 +12,8 @@ namespace Aperio_Control_Centre.AperioServer
|
||||
public IEnumerable<IAperioBase> GetDevices();
|
||||
public IEnumerable<IAperioConnectionContext?> GetConnections();
|
||||
|
||||
public IEnumerable<DoorModeSchedule> GetSchedules();
|
||||
|
||||
public IEnumerable<IAperioBase> GetDevices(string connectionId);
|
||||
|
||||
public IAperioBase? GetDevice(string devId);
|
||||
|
||||
@@ -49,6 +49,10 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.9.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Plotly.Blazor" Version="6.0.2" />
|
||||
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="9.0.9" />
|
||||
<PackageReference Include="System.Management" Version="9.0.9" />
|
||||
|
||||
@@ -175,19 +175,35 @@
|
||||
|
||||
string message = string.Empty;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
private PeriodicTimer refreshTimer = new(TimeSpan.FromSeconds(1));
|
||||
|
||||
// protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
// {
|
||||
// if (firstRender)
|
||||
// {
|
||||
// deviceList.DeviceListChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
|
||||
// await UpdateTable();
|
||||
// }
|
||||
// await base.OnAfterRenderAsync(firstRender);
|
||||
// }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (firstRender)
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
deviceList.DeviceListChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
|
||||
devices = deviceList.GetDevices().AsQueryable();
|
||||
|
||||
while (await refreshTimer.WaitForNextTickAsync())
|
||||
{
|
||||
deviceList.DeviceListChanged += async (s, e) => await InvokeAsync(() => UpdateTable());
|
||||
await UpdateTable();
|
||||
}
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refreshTimer.Dispose();
|
||||
deviceList.DeviceListChanged -= async (s, e) => await InvokeAsync(() => UpdateTable());
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
@implements IDisposable
|
||||
@inject IAperioDeviceList deviceList
|
||||
@inject IStringLocalizer<Aperio_Control_Centre.Resources.ValidationResources> localizer
|
||||
@using Aperio_Control_Centre.Models
|
||||
@using Microsoft.AspNetCore.Components.QuickGrid
|
||||
@using Microsoft.AspNetCore.Connections
|
||||
@using Aperio_Control_Centre.Extensions
|
||||
@attribute [Authorize]
|
||||
|
||||
|
||||
<QuickGrid Items="@schedules" class="table table-hover" @ref="schedulesGrid">
|
||||
|
||||
<TemplateColumn Title="Name">
|
||||
<a href="/Device/Edit/@context.Device?.Id">@context.Device?.Name</a>
|
||||
</TemplateColumn>
|
||||
|
||||
<TemplateColumn Title="Timezone">
|
||||
<a href="/Timezone/Edit/@context.Timezone?.Id">@context.Timezone?.GetTimezoneString</a>
|
||||
</TemplateColumn>
|
||||
|
||||
<TemplateColumn Title="Begin Time">
|
||||
@context.Timezone?.BeginTimeString()
|
||||
<br />
|
||||
@context.Timezone?.TimeToNextBeginTime().ToCustomString()
|
||||
</TemplateColumn>
|
||||
<TemplateColumn Title="End Time">
|
||||
@context.Timezone?.EndTimeString()
|
||||
<br />
|
||||
@context.Timezone?.TimeToNextEndTime().ToCustomString()
|
||||
</TemplateColumn>
|
||||
|
||||
<PropertyColumn Title="Door Mode" Property="@(p => p.DoorMode)" />
|
||||
|
||||
<PropertyColumn Title="Execute Mode" Property="@(p => p.ExecuteMode)" />
|
||||
|
||||
</QuickGrid>
|
||||
|
||||
@code {
|
||||
private QuickGrid<DoorModeSchedule>? schedulesGrid;
|
||||
private IQueryable<DoorModeSchedule>? schedules;
|
||||
|
||||
private PeriodicTimer refreshTimer = new(TimeSpan.FromSeconds(1));
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
schedules = deviceList.GetSchedules().AsQueryable();
|
||||
|
||||
while (await refreshTimer.WaitForNextTickAsync())
|
||||
{
|
||||
await UpdateTable();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
refreshTimer?.Dispose();
|
||||
}
|
||||
|
||||
private async Task UpdateTable()
|
||||
{
|
||||
schedules = deviceList.GetSchedules().AsQueryable();
|
||||
|
||||
await schedulesGrid!.RefreshDataAsync();
|
||||
this.StateHasChanged();
|
||||
}
|
||||
|
||||
// private void CloseConnection(IAperioConnectionContext conn)
|
||||
// {
|
||||
// conn.Abort(new("User closed connection"));
|
||||
// }
|
||||
}
|
||||
@@ -27,6 +27,14 @@ namespace Aperio_Control_Centre.Controllers
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Authorize]
|
||||
public ActionResult Schedules()
|
||||
{
|
||||
ViewBag.Title = _localizer["Schedules"];
|
||||
return View();
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[Authorize]
|
||||
|
||||
@@ -1,24 +1,92 @@
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Aperio_Control_Centre.Aadp.Types.ApplicationTypes;
|
||||
using Aperio_Control_Centre.ACSDatabase;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models.Extensions;
|
||||
using Aperio_Control_Centre.ACSDatabase.Types;
|
||||
using Aperio_Control_Centre.AperioServer;
|
||||
using Aperio_Control_Centre.AperioServer.Devices;
|
||||
using Aperio_Control_Centre.Extensions;
|
||||
using Aperio_Control_Centre.Models;
|
||||
using Aperio_Control_Centre.PagedList;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using OfficeOpenXml.Drawing.Chart;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Principal;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace Aperio_Control_Centre.Controllers
|
||||
{
|
||||
public class DeviceController(IDbContextFactory<ACSDatabaseContext> dbContextFactory, IStringLocalizer<DeviceController> localizer) : Controller
|
||||
public class DeviceController(IAperioDeviceList deviceList, IDbContextFactory<ACSDatabaseContext> dbContextFactory, IStringLocalizer<DeviceController> localizer) : Controller
|
||||
{
|
||||
private readonly IAperioDeviceList _devicesList = deviceList;
|
||||
private readonly IDbContextFactory<ACSDatabaseContext> _contextFactory = dbContextFactory;
|
||||
private readonly IStringLocalizer<DeviceController> _localizer = localizer;
|
||||
|
||||
//private static async Task<Device> LoadDeviceParameters(Device device, ACSDatabaseContext db, CancellationToken token)
|
||||
//{
|
||||
// device.LocationSelection = await db.Locations.LocationSelectList(token);
|
||||
// device.TimezoneSelection = await db.Timezones.TimeZoneSelectList(token);
|
||||
// device.DeviceGroupsSelectList = await db.DeviceGroups.DeviceGroupsListItems(device, token);
|
||||
// device.LastLoggings = await db.Loggings.LastDeviceLoggings(device, 25, token);
|
||||
// device.DoorModes = (await db.Devices.FindAsync([device.Id], token))?.DoorModes;
|
||||
// //if (device.DoorModeSchedules != null)
|
||||
// //{
|
||||
// // //await device.DoorModeScheduler.LoadTimezones(db, token);
|
||||
// //}
|
||||
// //device.ExecuteModeSelection = ExecuteModeSelectList();
|
||||
|
||||
|
||||
// return device;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
//private static List<SelectListItem> ExecuteModeSelectItems()
|
||||
//{
|
||||
// return Enum.GetValues<ExecuteMode>().Cast<ExecuteMode>().Select(static s => new SelectListItem
|
||||
// {
|
||||
// Value = s.GetDisplayName(),
|
||||
// Text = s.GetDisplayName()
|
||||
// }).ToList();
|
||||
|
||||
|
||||
// //return locations
|
||||
// // .Where(a => a.Active != ActiveStates.Deleted)
|
||||
// // .Select(s => new SelectListItem
|
||||
// // {
|
||||
// // Value = s.Id.ToString(),
|
||||
// // Text = s.AddressString,
|
||||
// // }).ToListAsync(token);
|
||||
//}
|
||||
|
||||
//private static SelectList ExecuteModeSelectList()
|
||||
//{
|
||||
|
||||
// //return new SelectList(ExecuteMode.Select(u => new { Value = u.ID, Text = u.Name }), "Value", "Text");
|
||||
|
||||
// var enumlist = Enum.GetValues<ExecuteMode>().Cast<ExecuteMode>().Select(s => new SelectListItem
|
||||
// {
|
||||
// Value = s.GetDisplayName(),
|
||||
// Text = s.GetDisplayName()
|
||||
// }).ToList();
|
||||
|
||||
// return new SelectList(enumlist, "Value", "Text");
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// GET: /Device/
|
||||
[HttpGet]
|
||||
[Authorize(Roles = "Administrator, DeviceAdmin, Viewer")]
|
||||
@@ -123,6 +191,8 @@ namespace Aperio_Control_Centre.Controllers
|
||||
device.LocationSelection = await db.Locations.LocationSelectList(token);
|
||||
device.TimezoneSelection = await db.Timezones.TimeZoneSelectList(token);
|
||||
device.DeviceGroupsSelectList = await db.DeviceGroups.DeviceGroupsListItems(token);
|
||||
|
||||
|
||||
ModelState.AddModelError(string.Empty, "Model invalid");
|
||||
|
||||
return View(device);
|
||||
@@ -143,6 +213,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
Device? device = await db.Devices
|
||||
.Where(d => d.Id == id)
|
||||
.Include(l => l.Location)
|
||||
.Include(d => d.DoorModeSchedules)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (device == null)
|
||||
@@ -162,6 +233,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
device.TimezoneSelection = await db.Timezones.TimeZoneSelectList(token);
|
||||
device.DeviceGroupsSelectList = await db.DeviceGroups.DeviceGroupsListItems(device, token);
|
||||
device.LastLoggings = await db.Loggings.LastDeviceLoggings(device, 25, token);
|
||||
//device.DoorModes = (await db.Devices.FindAsync([device.Id], token))?.DoorModes;
|
||||
|
||||
ViewBag.Title = _localizer["Edit"];
|
||||
|
||||
@@ -182,6 +254,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
Device? device = await db.Devices
|
||||
.Where(x => x.Id == deviceEdit.Id)
|
||||
.Include(g => g.DeviceGroups)
|
||||
.Include(s => s.DoorModeSchedules)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (device == null)
|
||||
@@ -191,6 +264,10 @@ namespace Aperio_Control_Centre.Controllers
|
||||
//https://learn.microsoft.com/nl-nl/ef/core/saving/disconnected-entities
|
||||
db.Entry(device).CurrentValues.SetValues(deviceEdit);
|
||||
|
||||
//Debug.WriteLine(db.ChangeTracker.DebugView.LongView);
|
||||
//db.ChangeTracker.DetectChanges();
|
||||
//Debug.WriteLine(db.ChangeTracker.DebugView.LongView);
|
||||
|
||||
if (device.ProductClass != ProductClass.GATEWAY)
|
||||
{
|
||||
if (deviceEdit.DeviceGroupsSelectList != null)
|
||||
@@ -219,6 +296,23 @@ namespace Aperio_Control_Centre.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (deviceEdit.DoorModeSchedules != null)
|
||||
{
|
||||
device.DoorModeSchedules = [];
|
||||
|
||||
//Debug.WriteLine($"DoorModeScheduler count = {deviceEdit.DoorModeSchedules?.Count}");
|
||||
foreach (var item in deviceEdit.DoorModeSchedules)
|
||||
{
|
||||
//Debug.WriteLine($"{item.DoorMode} - {item.TimezoneId} - {item.DeviceId}");
|
||||
item.DeviceId = device.Id;
|
||||
device.DoorModeSchedules?.Add(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
device.DoorModeSchedules = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (device.ProductClass == ProductClass.GATEWAY)
|
||||
@@ -242,11 +336,34 @@ namespace Aperio_Control_Centre.Controllers
|
||||
await db.AddLogAsync(User.Identity, device, "Apparaat bewerkt", LogTypes.Device, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
|
||||
if (device.ProductClass != ProductClass.GATEWAY)
|
||||
{
|
||||
if (_devicesList.GetDevice(device.DeviceId) is IAperioDoor door)
|
||||
{
|
||||
await door.LoadDoorModeSchedule(token);
|
||||
}
|
||||
}
|
||||
|
||||
return Request.Cookies.RedirectToCookie();
|
||||
}
|
||||
|
||||
//deviceEdit.LocationSelection = await db.Locations.LocationSelectList(token);
|
||||
//deviceEdit.TimezoneSelection = await db.Timezones.TimeZoneSelectList(token);
|
||||
//deviceEdit.DeviceGroupsSelectList = await db.DeviceGroups.DeviceGroupsListItems(deviceEdit, token);
|
||||
//deviceEdit.LastLoggings = await db.Loggings.LastDeviceLoggings(deviceEdit, 25, token);
|
||||
//deviceEdit.DoorModes = (await db.Devices.FindAsync([deviceEdit.Id], token))?.DoorModes;
|
||||
//if (deviceEdit.DoorModeScheduler != null)
|
||||
//{
|
||||
// await deviceEdit.DoorModeScheduler.LoadTimezones(db, token);
|
||||
//}
|
||||
|
||||
//deviceEdit = await LoadDeviceParameters(deviceEdit, db, token);
|
||||
deviceEdit.LocationSelection = await db.Locations.LocationSelectList(token);
|
||||
deviceEdit.TimezoneSelection = await db.Timezones.TimeZoneSelectList(token);
|
||||
deviceEdit.DeviceGroupsSelectList = await db.DeviceGroups.DeviceGroupsListItems(deviceEdit, token);
|
||||
deviceEdit.LastLoggings = await db.Loggings.LastDeviceLoggings(deviceEdit, 25, token);
|
||||
deviceEdit.DoorModes = (await db.Devices.FindAsync([deviceEdit.Id], token))?.DoorModes;
|
||||
|
||||
ModelState.AddModelError(string.Empty, "Model invalid");
|
||||
|
||||
return View(deviceEdit);
|
||||
@@ -268,6 +385,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
.Where(d => d.Id == id)
|
||||
.Include(l => l.Location)
|
||||
.Include(t => t.UnlockTimezone)
|
||||
.Include(s => s.DoorModeSchedules!).ThenInclude(t => t.Timezone)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (device == null)
|
||||
@@ -319,6 +437,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
.Where(d => d.Id == id)
|
||||
.Include(l => l.Location)
|
||||
.Include(t => t.UnlockTimezone)
|
||||
.Include(s => s.DoorModeSchedules!).ThenInclude(t => t.Timezone)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (device == null)
|
||||
@@ -345,7 +464,10 @@ namespace Aperio_Control_Centre.Controllers
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
await db.DisableDevice(device, User.Identity, token);
|
||||
device.Active = ActiveStates.Inactive;
|
||||
device.LastChanged = DateTime.UtcNow;
|
||||
await db.AddLogAsync(User.Identity, device, "Geblokkeerd", LogTypes.Device, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
|
||||
return Request.Cookies.RedirectToCookie();
|
||||
}
|
||||
@@ -366,6 +488,7 @@ namespace Aperio_Control_Centre.Controllers
|
||||
.Where(d => d.Id == id)
|
||||
.Include(l => l.Location)
|
||||
.Include(t => t.UnlockTimezone)
|
||||
.Include(s => s.DoorModeSchedules!).ThenInclude(t => t.Timezone)
|
||||
.SingleOrDefaultAsync(token);
|
||||
|
||||
if (device == null)
|
||||
@@ -393,7 +516,6 @@ namespace Aperio_Control_Centre.Controllers
|
||||
}
|
||||
device.Active = ActiveStates.Active;
|
||||
device.LastChanged = DateTime.UtcNow;
|
||||
db.Devices.Update(device);
|
||||
await db.AddLogAsync(User.Identity, device, "Geactiveerd", LogTypes.Device, token);
|
||||
await db.SaveChangesAsync(token);
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using Aperio_Control_Centre.Aadp.Enumerations;
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
|
||||
namespace Aperio_Control_Centre.Extensions
|
||||
{
|
||||
public static class DoorModeScheduleExtensions
|
||||
{
|
||||
public static string GetFullDescription(this DoorModeSchedule doorModeSchedule)
|
||||
{
|
||||
//return $"{doorModeSchedule.Timezone?.Name} - {doorModeSchedule.Timezone?.GetTimezoneString} - {doorModeSchedule.DoorMode} - {doorModeSchedule.ExecuteMode.GetDisplayName()}";
|
||||
return $"{doorModeSchedule.Timezone?.Name} - {doorModeSchedule.Timezone?.GetTimezoneString} - {doorModeSchedule.DoorMode} - {doorModeSchedule.ExecuteMode}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,9 +334,9 @@ namespace Aperio_Control_Centre.Extensions
|
||||
switch (state)
|
||||
{
|
||||
case HandleState.NOT_USED:
|
||||
return CreateBlazorStateIcon("orange", size, "Kruk niet gebruikt", "eye-off");
|
||||
return CreateBlazorStateIcon("green", size, "Kruk niet gebruikt", "arrow-up");
|
||||
case HandleState.BOTH_USED:
|
||||
return CreateBlazorStateIcon("green", size, "Kruk gebruikt", "eye");
|
||||
return CreateBlazorStateIcon("orange", size, "Kruk gebruikt", "arrow-down");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
19
Aperio_Control_Centre/Extensions/TimeSpanExtensions.cs
Normal file
19
Aperio_Control_Centre/Extensions/TimeSpanExtensions.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
namespace Aperio_Control_Centre.Extensions
|
||||
{
|
||||
public static class TimeSpanExtensions
|
||||
{
|
||||
public static uint ToDeciSeconds(this TimeSpan value)
|
||||
{
|
||||
return (uint)value.TotalSeconds * 10;
|
||||
}
|
||||
|
||||
public static string ToCustomString(this TimeSpan value)
|
||||
{
|
||||
if (value.Days == 0)
|
||||
{
|
||||
return $"{value.Hours}:hr {value.Minutes}:min {value.Seconds}:sec";
|
||||
}
|
||||
return $"{value.Days}:days {value.Hours}:hr {value.Minutes}:min {value.Seconds}:sec";
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Aperio_Control_Centre/Models/SchedulerItem.cs
Normal file
12
Aperio_Control_Centre/Models/SchedulerItem.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
|
||||
namespace Aperio_Control_Centre.Models
|
||||
{
|
||||
public class SchedulerItem
|
||||
{
|
||||
public DoorModeSchedule DoorModeSchedule { get; set; }
|
||||
|
||||
public Timer? BeginTimer { get; set; }
|
||||
public Timer? EndTimer { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ namespace Aperio_Control_Centre
|
||||
builder.Logging.AddConsole();
|
||||
//builder.Logging.AddDebug();
|
||||
|
||||
//TODO: remove event logging
|
||||
const string eventLogSource = "Aperio Control Centre";
|
||||
if (!EventLog.SourceExists(eventLogSource))
|
||||
{
|
||||
@@ -103,6 +104,7 @@ namespace Aperio_Control_Centre
|
||||
eventLogSettings.LogName = eventLogSource;
|
||||
eventLogSettings.SourceName = eventLogSource;
|
||||
});
|
||||
|
||||
builder.Logging.AddFileLogger();
|
||||
//builder.Logging.AddFileLogger(configuration =>
|
||||
//{
|
||||
@@ -167,7 +169,8 @@ namespace Aperio_Control_Centre
|
||||
options.MigrationsAssembly("Aperio_Control_Centre.ACSDatabase");
|
||||
});
|
||||
#if DEBUG
|
||||
//.EnableSensitiveDataLogging()
|
||||
options.EnableSensitiveDataLogging();
|
||||
options.EnableDetailedErrors();
|
||||
#endif
|
||||
options.UseSeeding((context, _) =>
|
||||
{
|
||||
@@ -266,6 +269,15 @@ namespace Aperio_Control_Centre
|
||||
builder.Services.AddTelegramBot(builder.Configuration.GetSection("Telegram"), _programCancellationTokenSource.Token);
|
||||
|
||||
|
||||
//ACS Scheduler
|
||||
//builder.Services.AddHostedService<Scheduler.SchedulerService>();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//builder.Services.Configure<AperioServerOptions>(ctx =>
|
||||
//{
|
||||
// ctx.TimeOutValue = builder.Configuration.GetValue<int>("Aperio:ConnectionTimeout");
|
||||
|
||||
189
Aperio_Control_Centre/Scheduler/SchedulerService.cs
Normal file
189
Aperio_Control_Centre/Scheduler/SchedulerService.cs
Normal file
@@ -0,0 +1,189 @@
|
||||
//using Aperio_Control_Centre.ACSDatabase;
|
||||
//using Aperio_Control_Centre.ACSDatabase.Models;
|
||||
//using Aperio_Control_Centre.AperioServer;
|
||||
//using Aperio_Control_Centre.AperioServer.Devices;
|
||||
//using Aperio_Control_Centre.Log;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using System.Diagnostics;
|
||||
|
||||
//namespace Aperio_Control_Centre.Scheduler
|
||||
//{
|
||||
// public class SchedulerItem
|
||||
// {
|
||||
// public DoorModeSchedule DoorModeSchedule { get; set; }
|
||||
|
||||
// public Timer? BeginTimer { get; set; }
|
||||
// public Timer? EndTimer { get; set; }
|
||||
// }
|
||||
|
||||
// //public sealed class SchedulerService : IHostedService, IDisposable
|
||||
// //{
|
||||
// // private readonly ILogger<SchedulerService> _logger;
|
||||
// // private readonly IDbContextFactory<ACSDatabaseContext> _dbContextFactory;
|
||||
// // private readonly IAperioDeviceList _devicesList;
|
||||
|
||||
// // private readonly List<SchedulerItem> _items = [];
|
||||
|
||||
// // public SchedulerService(IAperioDeviceList devicesList, ILogger<SchedulerService> logger, IDbContextFactory<ACSDatabaseContext> dbContextFactory)
|
||||
// // {
|
||||
// // _devicesList = devicesList;
|
||||
// // _logger = logger;
|
||||
// // _dbContextFactory = dbContextFactory;
|
||||
// // }
|
||||
|
||||
// // public async Task StartAsync(CancellationToken stoppingToken)
|
||||
// // {
|
||||
// // //_logger.LogInformation("Timed Hosted Service running.");
|
||||
// // Logger.LogInformation(_logger, "Timed Hosted Service running.");
|
||||
|
||||
// // await LoadSchedulerItems(stoppingToken);
|
||||
// // }
|
||||
|
||||
// // public async Task LoadSchedulerItems(CancellationToken token)
|
||||
// // {
|
||||
// // using ACSDatabaseContext db = await _dbContextFactory.CreateDbContextAsync(token);
|
||||
|
||||
// // List<DoorModeSchedule> schedules = await db.DoorModeSchedules
|
||||
// // .Include(t => t.Timezone)
|
||||
// // .Include(d => d.Device)
|
||||
// // .ToListAsync(token);
|
||||
|
||||
// // foreach (DoorModeSchedule item in schedules)
|
||||
// // {
|
||||
// // AddSchedulerItem(item);
|
||||
|
||||
// // //Debug.WriteLine($"ID:{item.Id} - Timezone:{item.Timezone?.GetTimezoneString} - device:{item.Device?.Name} - {item.DoorMode}");
|
||||
|
||||
// // //SchedulerItem schedulerItem = new();
|
||||
// // //schedulerItem.DoorModeSchedule = item;
|
||||
|
||||
// // //Debug.WriteLine($"Seconds to next begin + 24hr {item.Timezone.TimeToNextBeginTime().TotalSeconds}");
|
||||
// // ////schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, item.Timezone.TimeToNextBeginTime(), Timeout.InfiniteTimeSpan);
|
||||
// // //schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
|
||||
// // //Debug.WriteLine($"Seconds to next end + 24hr {item.Timezone.TimeToNextEndTime().TotalSeconds}");
|
||||
// // ////schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, item.Timezone.TimeToNextEndTime(), Timeout.InfiniteTimeSpan);
|
||||
// // //schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
|
||||
|
||||
// // //_items.Add(schedulerItem);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
// // public void AddSchedulerItem(DoorModeSchedule item)
|
||||
// // {
|
||||
// // Debug.WriteLine($"ID:{item.Id} - Timezone:{item.Timezone?.GetTimezoneString} - device:{item.Device?.Name} - {item.DoorMode}");
|
||||
|
||||
// // SchedulerItem schedulerItem = new()
|
||||
// // {
|
||||
// // DoorModeSchedule = item
|
||||
// // };
|
||||
|
||||
// // Debug.WriteLine($"Seconds to next begin + 24hr {item.Timezone.TimeToNextBeginTime().TotalSeconds}");
|
||||
// // //schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, item.Timezone.TimeToNextBeginTime(), Timeout.InfiniteTimeSpan);
|
||||
// // schedulerItem.BeginTimer = new Timer(BeginTimerCallback, schedulerItem, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
|
||||
// // Debug.WriteLine($"Seconds to next end + 24hr {item.Timezone.TimeToNextEndTime().TotalSeconds}");
|
||||
// // //schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, item.Timezone.TimeToNextEndTime(), Timeout.InfiniteTimeSpan);
|
||||
// // schedulerItem.EndTimer = new Timer(EndTimerCallback, schedulerItem, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
|
||||
|
||||
// // _items.Add(schedulerItem);
|
||||
// // }
|
||||
|
||||
|
||||
|
||||
// // private void BeginTimerCallback(object? state)
|
||||
// // {
|
||||
// // //Logger.LogInformation(_logger, $"Timed Hosted Service is working.");
|
||||
// // //Debug.WriteLine($"DoWork Fired");
|
||||
// // if (state is SchedulerItem item)
|
||||
// // {
|
||||
// // Debug.WriteLine($"-----> BeginTimerCallback {item.DoorModeSchedule.Timezone?.GetTimezoneString} - {item.DoorModeSchedule.Device?.Name}");
|
||||
|
||||
// // if(_devicesList.GetDevice(item.DoorModeSchedule.Device?.DeviceId) is IAperioDoor door)
|
||||
// // {
|
||||
// // door.SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
// // }
|
||||
|
||||
// // //IAperioBase? device = _devicesList.GetDevice(item.DoorModeSchedule.Device?.DeviceId);
|
||||
// // //if (device != null)
|
||||
// // //{
|
||||
// // // if (device is IAperioDoor door)
|
||||
// // // {
|
||||
// // // door.SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
|
||||
|
||||
// // // }
|
||||
// // //}
|
||||
// // else
|
||||
// // {
|
||||
// // Debug.WriteLine($"SchedulerService - {item.DoorModeSchedule.Device.Name} device not connected");
|
||||
// // }
|
||||
|
||||
// // //item.BeginTimer = new Timer(BeginTimerCallback, item, item.DoorModeSchedule.Timezone.TimeToNextBeginTime(), Timeout.InfiniteTimeSpan);
|
||||
// // item.BeginTimer = new Timer(BeginTimerCallback, item, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // private void EndTimerCallback(object? state)
|
||||
// // {
|
||||
// // //Logger.LogInformation(_logger, $"Timed Hosted Service is working.");
|
||||
// // //Debug.WriteLine($"DoWork Fired");
|
||||
// // if (state is SchedulerItem item)
|
||||
// // {
|
||||
// // Debug.WriteLine($"<------ EndTimerCallback {item.DoorModeSchedule.Timezone?.GetTimezoneString} - {item.DoorModeSchedule.Device?.Name}");
|
||||
|
||||
// // if (_devicesList.GetDevice(item.DoorModeSchedule.Device?.DeviceId) is IAperioDoor door)
|
||||
// // {
|
||||
// // door.SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
// // }
|
||||
// // //IAperioBase? device = _devicesList.GetDevice(item.DoorModeSchedule.Device?.DeviceId);
|
||||
// // //if (device != null)
|
||||
// // //{
|
||||
// // // if (device is IAperioDoor door)
|
||||
// // // {
|
||||
// // // door.SetDoorModeOnDevice(item.DoorModeSchedule.DoorMode);
|
||||
|
||||
|
||||
// // // }
|
||||
// // //}
|
||||
// // else
|
||||
// // {
|
||||
// // Debug.WriteLine($"SchedulerService - {item.DoorModeSchedule.Device.Name} device not connected");
|
||||
// // }
|
||||
|
||||
// // //item.EndTimer = new Timer(EndTimerCallback, item, item.DoorModeSchedule.Timezone.TimeToNextEndTime(), Timeout.InfiniteTimeSpan);
|
||||
// // item.EndTimer = new Timer(EndTimerCallback, item, TimeSpan.FromMinutes(1), Timeout.InfiniteTimeSpan);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
|
||||
|
||||
// // public Task StopAsync(CancellationToken stoppingToken)
|
||||
// // {
|
||||
// // ///_logger.LogInformation("Timed Hosted Service is stopping.");
|
||||
// // Logger.LogInformation(_logger, "Timed Hosted Service is stopping.");
|
||||
// // //_timer?.Change(Timeout.Infinite, 0);
|
||||
|
||||
// // foreach (SchedulerItem item in _items)
|
||||
// // {
|
||||
// // item.BeginTimer?.Change(Timeout.Infinite, 0);
|
||||
// // item.EndTimer?.Change(Timeout.Infinite, 0);
|
||||
// // }
|
||||
|
||||
// // return Task.CompletedTask;
|
||||
// // }
|
||||
|
||||
// // public void Dispose()
|
||||
// // {
|
||||
// // //_timer?.Dispose();
|
||||
// // foreach (SchedulerItem item in _items)
|
||||
// // {
|
||||
// // item.BeginTimer?.Dispose();
|
||||
// // item.EndTimer?.Dispose();
|
||||
// // }
|
||||
// // }
|
||||
// //}
|
||||
//}
|
||||
62
Aperio_Control_Centre/Scripts/DoorModeScheduler.ts
Normal file
62
Aperio_Control_Centre/Scripts/DoorModeScheduler.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
function indexDoorModeScheduler() {
|
||||
//var doorModeScheduler = document.getElementById("DoorModeScheduler");
|
||||
var li = document.getElementById("DoorModeScheduler").getElementsByTagName("li");
|
||||
for (var i = 0; i < li.length; i++) {
|
||||
//console.log("li " + i);
|
||||
(li[i].querySelector("#timezoneid") as HTMLInputElement).name = "DoorModeSchedules[" + i + "].TimezoneId";
|
||||
(li[i].querySelector("#doormode") as HTMLInputElement).name = "DoorModeSchedules[" + i + "].DoorMode";
|
||||
(li[i].querySelector("#executemode") as HTMLInputElement).name = "DoorModeSchedules[" + i + "].ExecuteMode";
|
||||
}
|
||||
}
|
||||
|
||||
function removeDoorModeSchedulerItem(button) {
|
||||
//console.log("removeDoorModeSchedulerItem");
|
||||
button.parentElement.remove();
|
||||
indexDoorModeScheduler();
|
||||
}
|
||||
|
||||
|
||||
function addDoorModeSchedulerItem(button: any) {
|
||||
//console.log("addDoorModeSchedulerItem");
|
||||
var timezoneSelect = (document.getElementById("UnlockTimezoneIdAdd")) as HTMLSelectElement;
|
||||
var doormodeSelect = (document.getElementById("DoorModeAdd")) as HTMLSelectElement;
|
||||
var executemodeSelect = (document.getElementById("ExecuteModeAdd")) as HTMLSelectElement;
|
||||
if (timezoneSelect.selectedIndex != 0 && doormodeSelect.selectedIndex != 0 && executemodeSelect.selectedIndex != 0) {
|
||||
|
||||
var li = document.createElement("li") as HTMLLIElement;
|
||||
li.innerHTML = timezoneSelect.options[timezoneSelect.selectedIndex].text + " - " + doormodeSelect.value + " - " + executemodeSelect.value;
|
||||
li.className = "list-group-item d-flex justify-content-between align-items-center";
|
||||
|
||||
var timezoneidinput = document.createElement("input") as HTMLInputElement;
|
||||
timezoneidinput.id = "timezoneid";
|
||||
timezoneidinput.name = "DoorModeSchedules[].TimezoneId";
|
||||
timezoneidinput.value = timezoneSelect.value;
|
||||
timezoneidinput.type = "hidden";
|
||||
li.appendChild(timezoneidinput);
|
||||
|
||||
var doormodeinput = document.createElement("input") as HTMLInputElement;
|
||||
doormodeinput.id = "doormode";
|
||||
doormodeinput.name = "DoorModeSchedules[].DoorMode";
|
||||
doormodeinput.value = doormodeSelect.value;
|
||||
doormodeinput.type = "hidden";
|
||||
li.appendChild(doormodeinput);
|
||||
|
||||
var executemodeinput = document.createElement("input") as HTMLInputElement;
|
||||
executemodeinput.id = "executemode";
|
||||
executemodeinput.name = "DoorModeSchedules[].ExecuteMode";
|
||||
executemodeinput.value = executemodeSelect.value;
|
||||
executemodeinput.type = "hidden";
|
||||
li.appendChild(executemodeinput);
|
||||
|
||||
var removebutton = document.createElement("button") as HTMLButtonElement;
|
||||
removebutton.className = "btn btn-outline-danger";
|
||||
removebutton.innerHTML = "remove";
|
||||
removebutton.onclick = function () { removeDoorModeSchedulerItem(this); };
|
||||
li.appendChild(removebutton);
|
||||
|
||||
document.getElementById("DoorModeScheduler").appendChild(li);
|
||||
|
||||
indexDoorModeScheduler();
|
||||
}
|
||||
}
|
||||
7
Aperio_Control_Centre/Views/Aperio/Schedules.cshtml
Normal file
7
Aperio_Control_Centre/Views/Aperio/Schedules.cshtml
Normal file
@@ -0,0 +1,7 @@
|
||||
@Html.PageTitle((string)ViewBag.Title, (string)ViewBag.Message)
|
||||
|
||||
<div class="row justify-content-center p-0 m-0">
|
||||
<component type="typeof(Aperio_Control_Centre.Components.Aperio.AperioSchedules)" render-mode="Server" />
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.web.js"></script>
|
||||
@@ -3,6 +3,8 @@
|
||||
@inject IConfiguration Configuration
|
||||
@model Aperio_Control_Centre.ACSDatabase.Models.Device
|
||||
|
||||
<script src="~/js/DoorModeScheduler.js"></script>
|
||||
|
||||
@Html.PageTitle((string)ViewBag.Title, (string)ViewBag.Message)
|
||||
|
||||
@using (Html.BeginForm())
|
||||
@@ -10,7 +12,7 @@
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-10 offset-lg-1 col-xl-6 offset-xl-3">
|
||||
<div class="col-lg-10 offset-lg-1 col-xl-8 offset-xl-2">
|
||||
|
||||
@if (!ViewData.ModelState.IsValid)
|
||||
{
|
||||
@@ -91,10 +93,59 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row mb-3">
|
||||
@Html.LabelFor(model => model.DoorModeSchedules, new { @class = "col-form-label col-sm-2" })
|
||||
<div class="col-sm-10">
|
||||
<ul class="list-group" id="DoorModeScheduler" name="DoorModeScheduler">
|
||||
@for (int i = 0; i < Model.DoorModeSchedules?.Count(); i++)
|
||||
{
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
@Model.DoorModeSchedules[i].GetFullDescription()
|
||||
|
||||
<input id="timezoneid" name="DoorModeSchedules[@i].TimezoneId" type="hidden" value="@Model.DoorModeSchedules[i].TimezoneId" />
|
||||
<input id="doormode" name="DoorModeSchedules[@i].DoorMode" type="hidden" value="@Model.DoorModeSchedules[i].DoorMode" />
|
||||
<input id="executemode" name="DoorModeSchedules[@i].ExecuteMode" type="hidden" value="@Model.DoorModeSchedules[i].ExecuteMode" />
|
||||
|
||||
<button class="btn btn-outline-danger" type="button" onclick="removeDoorModeSchedulerItem(this)">remove</button>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<br />
|
||||
<div class="input-group">
|
||||
@if (Model.DoorModes != null)
|
||||
{
|
||||
@Html.DropDownList("UnlockTimezoneIdAdd", Model.TimezoneSelection, "Selecteer tijdzone", htmlAttributes: new { @class = "form-select" })
|
||||
@Html.DropDownList("DoorModeAdd", Model.DoorModes?.DoorModeSelectList(), "Selecteer deur stand", htmlAttributes: new { @class = "form-select" })
|
||||
@Html.DropDownList("ExecuteModeAdd", new SelectList(Enum.GetValues(typeof(ExecuteMode))), "Selecteer uitvoering", htmlAttributes: new { @class = "form-select" })
|
||||
|
||||
<button class="btn btn-outline-info" id="add" type="button" onclick="addDoorModeSchedulerItem(this)">Add</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<select class="form-select" disabled><option value="">Selecteer tijdzone</option></select>
|
||||
<select class="form-select" disabled><option value="">Selecteer deur stand</option></select>
|
||||
<select class="form-select" disabled><option value="">Selecteer uitvoering</option></select>
|
||||
<button class="btn btn-outline-secondary" type="button" disabled>Add</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row mb-3">
|
||||
@Html.LabelFor(model => model.UnlockTime, htmlAttributes: new { @class = "col-form-label col-sm-2" })
|
||||
<div class="col-sm-10">
|
||||
@Html.EditorFor(model => model.UnlockTime, new { htmlAttributes = new { @class = "form-control" } })
|
||||
<div class="input-group">
|
||||
@Html.EditorFor(model => model.UnlockTime, new { htmlAttributes = new { @class = "form-control" } })
|
||||
<span class="input-group-text">Seconden</span>
|
||||
</div>
|
||||
@Html.ValidationMessageFor(model => model.UnlockTime, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,12 +154,17 @@
|
||||
@Html.LabelFor(model => model.DoorState, htmlAttributes: new { @class = "col-form-label col-sm-2" })
|
||||
<div class="col-sm-10">
|
||||
@Html.LockStateIcon(Model.LockState, 15)
|
||||
@Html.HiddenFor(model => model.LockState)
|
||||
@if (Model.ProductClass == ProductClass.LOCK)
|
||||
{
|
||||
@Html.DoorStateIcon(Model.DoorState, 15)
|
||||
@Html.HiddenFor(model => model.DoorState)
|
||||
@Html.HandleStateIcon(Model.HandleState, 15)
|
||||
@Html.HiddenFor(model => model.HandleState)
|
||||
@Html.KeyCylinderStateIcon(Model.KeyCylinderState, 15)
|
||||
@Html.HiddenFor(model => model.KeyCylinderState)
|
||||
@Html.TamperStateIcon(Model.TamperState, 15)
|
||||
@Html.HiddenFor(model => model.TamperState)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -119,6 +175,7 @@
|
||||
@Html.LabelFor(model => model.BatteryState, htmlAttributes: new { @class = "col-form-label col-sm-2" })
|
||||
<div class="col-sm-10">
|
||||
@Html.BatteryStateIcon(Model.BatteryState, 15)
|
||||
@Html.HiddenFor(model => model.BatteryState)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@@ -139,6 +196,7 @@
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@Html.HiddenFor(model => model.DoorModes)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -158,6 +216,7 @@
|
||||
@Html.LabelFor(model => model.Ipaddress, new { @class = "col-form-label col-sm-2" })
|
||||
<div class="col-sm-1">
|
||||
@Html.ConnectionStateIcon(Model.ConnectionState, 15)
|
||||
@Html.HiddenFor(model => model.ConnectionState)
|
||||
</div>
|
||||
<div class="col-sm-9">
|
||||
@if (Model.ProductClass == ProductClass.H1502R11)
|
||||
@@ -168,6 +227,7 @@
|
||||
{
|
||||
@Html.DisplayFor(model => model.Ipaddress)
|
||||
}
|
||||
@Html.HiddenFor(model => model.Ipaddress)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -182,8 +242,10 @@
|
||||
@Html.CheckBoxFor(model => model.DeviceGroupsSelectList[i].Selected, new { @checked = "checked", @class = "form-check-input", @id = $"DeviceGroupsSelectList_{i}" })
|
||||
@Html.HiddenFor(model => model.DeviceGroupsSelectList[i].Value, new { @id = $"DeviceGroupsSelectList_{i}" })
|
||||
@Html.HiddenFor(model => model.DeviceGroupsSelectList[i].Text, new { @id = $"DeviceGroupsSelectList_{i}" })
|
||||
@* @Html.TimeZoneActiveIcon(Model.DeviceGroupsSelectList[i].TimeZoneActive, 10) *@
|
||||
<label class="form-check-label" for="@Html.Raw($"DeviceGroupsSelectList_{i}")">
|
||||
@Html.DisplayName(Model.DeviceGroupsSelectList[i].Text)
|
||||
@Html.TimeZoneActiveIcon(Model.DeviceGroupsSelectList[i].TimeZoneActive, 8)
|
||||
</label>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -76,6 +76,23 @@
|
||||
<dd class="col-sm-9">@Html.TamperStateIcon(Model.TamperState, 15)</dd>
|
||||
}
|
||||
|
||||
|
||||
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.DoorModeSchedules)</dt>
|
||||
if (Model.DoorModeSchedules?.Count > 0)
|
||||
{
|
||||
foreach (var item in Model.DoorModeSchedules)
|
||||
{
|
||||
<dd class="col-sm-9 offset-sm-3 my-0">
|
||||
@* @Html.DisplayName(item.FullName()) *@
|
||||
@Html.DisplayName(item.GetFullDescription())
|
||||
</dd>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<dd class="col-sm-9"></dd>
|
||||
}
|
||||
|
||||
<dt class="col-sm-3">@Html.DisplayNameFor(model => model.UnlockTimezone)</dt>
|
||||
<dd class="col-sm-9">@Html.DisplayFor(model => model.UnlockTimezone!.Name)</dd>
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
<ul class="dropdown-menu">
|
||||
<li>@Html.ActionLink(Localizer["Connections"].Value, "Connections", "Aperio", null, new { @class = "dropdown-item" })</li>
|
||||
<li>@Html.ActionLink(Localizer["Devices"].Value, "Devices", "Aperio", null, new { @class = "dropdown-item" })</li>
|
||||
<li>@Html.ActionLink(Localizer["Schedules"].Value, "Schedules", "Aperio", null, new { @class = "dropdown-item" })</li>
|
||||
<li>@Html.ActionLink(Localizer["Performance"].Value, "AperioMetrics", "Metrics", null, new { @class = "dropdown-item" })</li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li>@Html.ActionLink(Localizer["Aperio logging"].Value, "AperioLive", "Loggings", null, new { @class = "dropdown-item" })</li>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"libraries": [
|
||||
{
|
||||
"provider": "cdnjs",
|
||||
"library": "bootstrap@5.3.7",
|
||||
"library": "bootstrap@5.3.8",
|
||||
"destination": "wwwroot/bootstrap/",
|
||||
"files": [
|
||||
"css/bootstrap-grid.min.css",
|
||||
|
||||
18
Aperio_Control_Centre/tsconfig.json
Normal file
18
Aperio_Control_Centre/tsconfig.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compileOnSave": true,
|
||||
"compilerOptions": {
|
||||
"noImplicitAny": false,
|
||||
"noEmitOnError": true,
|
||||
"removeComments": true,
|
||||
"sourceMap": false,
|
||||
"target": "es6",
|
||||
"outDir": "wwwroot/js"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"wwwroot"
|
||||
],
|
||||
"include": [
|
||||
"scripts/**/*"
|
||||
]
|
||||
}
|
||||
@@ -82,7 +82,6 @@
|
||||
$("#PassNumberBlock").hide();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$.extend($.expr[":"], {
|
||||
|
||||
Reference in New Issue
Block a user