Jetzt funktionieren auch Alarme, d.h. der Service generiert Alarme für die betreffenden Zonen / Assignments

This commit is contained in:
Daniel Schick 2022-12-31 15:47:30 +01:00
parent 1100c4d7b6
commit 8e0b4c56c1
7 changed files with 90 additions and 19 deletions

View File

@ -26,6 +26,10 @@ In der Übersicht nur Daten aus der Datenbank, vorerst keine Daten aus Wetris.
2) der Zeitpunkt des letzten Reports innerhalb der Zone 2) der Zeitpunkt des letzten Reports innerhalb der Zone
3) keine Referenz sondern Kopie der Position/Timestamp? 3) keine Referenz sondern Kopie der Position/Timestamp?
- Alarm / Zuordnung sind unabhängig von der Gruppe. Die Gruppe / der Zulauf ergibt sich erst in der Webanwendung. (Ist das sinnvoll?) - Alarm / Zuordnung sind unabhängig von der Gruppe. Die Gruppe / der Zulauf ergibt sich erst in der Webanwendung. (Ist das sinnvoll?)
- Für die Abfrage in der Gruppe der Zonen Außenweser/Binnenweser: Jeweils "neuester" Alarm:
- wenn kein weiterer Alarm: o : unspezifisch
- wenn vorh. Alarm in Zone mit niedrigere Seq : <- eingehend
- wenn vorh. Alarm in Zone mit höherer Seq : -> abgehend
## Stand Dez 22 ## Stand Dez 22

View File

@ -45,18 +45,24 @@ namespace bsmd.AIS2Service
{ {
// load zones from storage // load zones from storage
List<MonitorZone> allZones = _storage.LoadMonitorZones(); List<MonitorZone> allZones = _storage.LoadMonitorZones();
Dictionary<int, List<MonitorZone>> testZones = new Dictionary<int, List<MonitorZone>>(); Dictionary<int, List<AlarmAssignmentZone>> testDict = new Dictionary<int, List<AlarmAssignmentZone>>();
// letzte Alarme
// Dictionary<int, Alarm> currentAlarms = _storage.LoadAlarms();
foreach(MonitorZone zone in allZones) foreach(MonitorZone zone in allZones)
{ {
// load up Zone list for all assignment mmsi's (to check) // load up Zone list for all assignment mmsi's (to check)
foreach(MonitorAssignment ma in zone.Assignments) foreach(MonitorAssignment ma in zone.Assignments)
{ {
if(!testZones.ContainsKey(ma.MMSI)) testZones[ma.MMSI] = new List<MonitorZone>(); if(!testDict.ContainsKey(ma.MMSI)) testDict[ma.MMSI] = new List<AlarmAssignmentZone>();
testZones[ma.MMSI].Add(zone); ma.Alarms.AddRange(_storage.LoadAlarms(ma));
AlarmAssignmentZone aazone = new AlarmAssignmentZone();
aazone.Zone = zone;
aazone.Assignment = ma;
testDict[ma.MMSI].Add(aazone);
} }
} }
// loop // loop
while(!_stopFlag) while(!_stopFlag)
{ {
@ -64,13 +70,40 @@ namespace bsmd.AIS2Service
foreach(int mmsi in _sitRepDict.Keys) foreach(int mmsi in _sitRepDict.Keys)
{ {
if(testZones.ContainsKey(mmsi)) if(testDict.ContainsKey(mmsi))
{ {
AIS_Target target = _sitRepDict[mmsi]; AIS_Target target = _sitRepDict[mmsi];
foreach(MonitorZone zone in testZones[mmsi]) { foreach(AlarmAssignmentZone aazone in testDict[mmsi]) {
if(zone.IsPointInPolygon4(target.Position)) if(aazone.Zone.IsPointInPolygon4(target.Position))
{ {
_log.InfoFormat("{0} is in zone {1}", target.ToString(), zone.Name); _log.InfoFormat("{0} is in zone {1}", target.ToString(), aazone.Zone.Name);
Alarm alarm;
if (aazone.Assignment.Alarms.Count > 0)
{
alarm = aazone.Assignment.Alarms[0];
if(alarm.Timestamp_Last.HasValue &&
((DateTime.Now - alarm.Timestamp_Last.Value).TotalMinutes > Properties.Settings.Default.MinAlarmIntervalMins))
{
// this "old" alarm will be triggered again (overwritten)
alarm.Acknowledged = null;
alarm.Timestamp_Last = null;
alarm.Timestamp_First = DateTime.Now;
}
else
{
// update the last time the target registered in the zone
alarm.Timestamp_Last = DateTime.Now;
}
}
else
{
// create new alarm
alarm = new Alarm(-1, aazone.Assignment);
alarm.Timestamp_First = DateTime.Now;
alarm.ZoneMonitorType = aazone.Assignment.MonitorType;
aazone.Assignment.Alarms.Add(alarm);
}
_storage.Save(alarm);
} }
} }
} }
@ -113,6 +146,15 @@ namespace bsmd.AIS2Service
#endregion #endregion
#region class AssignmentZoneAlarm composition
private class AlarmAssignmentZone
{
public MonitorZone Zone { get; set; }
public MonitorAssignment Assignment { get; set; }
}
#endregion
} }
} }

View File

@ -1,13 +1,12 @@
using System; using log4net;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Threading.Tasks;
using System.Threading;
using System.Data.SQLite; using System.Data.SQLite;
using log4net; using System.Threading;
using System.Collections.Concurrent; using System.Threading.Tasks;
namespace bsmd.AIS2Service namespace bsmd.AIS2Service
{ {
@ -180,7 +179,8 @@ namespace bsmd.AIS2Service
int id = reader.GetInt32(0); int id = reader.GetInt32(0);
Alarm alarm = new Alarm(id, assignment); Alarm alarm = new Alarm(id, assignment);
alarm.Timestamp_First = reader.GetDateTime(1); alarm.Timestamp_First = reader.GetDateTime(1);
alarm.Timestamp_Last = reader.GetDateTime(2); if(!reader.IsDBNull(2))
alarm.Timestamp_Last = reader.GetDateTime(2);
alarm.ZoneMonitorType = (MonitorAssignment.ZoneMonitorType)reader.GetInt32(3); alarm.ZoneMonitorType = (MonitorAssignment.ZoneMonitorType)reader.GetInt32(3);
if(!reader.IsDBNull(4)) if(!reader.IsDBNull(4))
alarm.Acknowledged = reader.GetDateTime(4); alarm.Acknowledged = reader.GetDateTime(4);
@ -207,8 +207,10 @@ namespace bsmd.AIS2Service
if (alarm.Id <= 0) if (alarm.Id <= 0)
{ {
// insert // insert
string saveAlarmString = $"INSERT INTO alarm (zone_assignment_id, timestamp_first, timestamp_last, type, acknowledged) VALUES ({alarm.Assignment.Id}, '{alarm.Timestamp_First}', '{alarm.Timestamp_Last}', {alarm.ZoneMonitorType}, {alarm.Acknowledged})"; string saveAlarmString = $"INSERT INTO alarm (zone_assignment_id, timestamp_first, timestamp_last, type) VALUES ({alarm.Assignment.Id}, @TS_FIRST, @TS_LAST, {(int) alarm.ZoneMonitorType})";
SQLiteCommand cmd = new SQLiteCommand(saveAlarmString, _connection); SQLiteCommand cmd = new SQLiteCommand(saveAlarmString, _connection);
cmd.Parameters.AddWithValue("@TS_FIRST", alarm.Timestamp_First);
cmd.Parameters.AddWithValue("@TS_LAST", alarm.Timestamp_Last);
int insertedRows = cmd.ExecuteNonQuery(); int insertedRows = cmd.ExecuteNonQuery();
cmd.Dispose(); cmd.Dispose();
alarm.Id = GetLastInsertId(); alarm.Id = GetLastInsertId();
@ -217,8 +219,14 @@ namespace bsmd.AIS2Service
else else
{ {
// update // update
string updateAlarmString = $"UPDATE alarm SET acknowledged = {alarm.Acknowledged}, timestamp_last = '{alarm.Timestamp_Last}' WHERE id = {alarm.Id}"; string updateAlarmString = $"UPDATE alarm SET acknowledged = @TS_ACK, timestamp_first = @TS_FIRST, timestamp_last = @TS_LAST WHERE id = {alarm.Id}";
SQLiteCommand cmd = new SQLiteCommand(updateAlarmString, _connection); SQLiteCommand cmd = new SQLiteCommand(updateAlarmString, _connection);
cmd.Parameters.AddWithValue("@TS_FIRST", alarm.Timestamp_First);
cmd.Parameters.AddWithValue("@TS_LAST", alarm.Timestamp_Last);
if(alarm.Acknowledged.HasValue)
cmd.Parameters.AddWithValue("@TS_ACK", alarm.Acknowledged);
else
cmd.Parameters.AddWithValue("@TS_ACK", DBNull.Value);
int updatedRows = cmd.ExecuteNonQuery(); int updatedRows = cmd.ExecuteNonQuery();
cmd.Dispose(); cmd.Dispose();
return (updatedRows == 1); return (updatedRows == 1);

View File

@ -67,6 +67,9 @@
<setting name="MonitorTargetSaturationSecs" serializeAs="String"> <setting name="MonitorTargetSaturationSecs" serializeAs="String">
<value>120</value> <value>120</value>
</setting> </setting>
<setting name="MinAlarmIntervalMins" serializeAs="String">
<value>60</value>
</setting>
</bsmd.AIS2Service.Properties.Settings> </bsmd.AIS2Service.Properties.Settings>
</applicationSettings> </applicationSettings>
<runtime> <runtime>

View File

@ -277,6 +277,8 @@ namespace bsmd.AIS2Service
public long MonitorZoneId { get; set; } public long MonitorZoneId { get; set; }
public List<Alarm> Alarms { get; } = new List<Alarm>();
public override string ToString() public override string ToString()
{ {
return String.Format("{0} {1}", MMSI, MonitorType); return String.Format("{0} {1}", MMSI, MonitorType);
@ -298,7 +300,7 @@ namespace bsmd.AIS2Service
public DateTime Timestamp_First { get; set; } public DateTime Timestamp_First { get; set; }
public DateTime Timestamp_Last { get; set; } public DateTime? Timestamp_Last { get; set; }
public DateTime? Acknowledged { get; set; } public DateTime? Acknowledged { get; set; }

View File

@ -121,5 +121,14 @@ namespace bsmd.AIS2Service.Properties {
return ((int)(this["MonitorTargetSaturationSecs"])); return ((int)(this["MonitorTargetSaturationSecs"]));
} }
} }
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("60")]
public int MinAlarmIntervalMins {
get {
return ((int)(this["MinAlarmIntervalMins"]));
}
}
} }
} }

View File

@ -35,5 +35,8 @@
<Setting Name="MonitorTargetSaturationSecs" Type="System.Int32" Scope="Application"> <Setting Name="MonitorTargetSaturationSecs" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">120</Value> <Value Profile="(Default)">120</Value>
</Setting> </Setting>
<Setting Name="MinAlarmIntervalMins" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">60</Value>
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>