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
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?)
- 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

View File

@ -45,18 +45,24 @@ namespace bsmd.AIS2Service
{
// load zones from storage
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)
{
// load up Zone list for all assignment mmsi's (to check)
foreach(MonitorAssignment ma in zone.Assignments)
{
if(!testZones.ContainsKey(ma.MMSI)) testZones[ma.MMSI] = new List<MonitorZone>();
testZones[ma.MMSI].Add(zone);
if(!testDict.ContainsKey(ma.MMSI)) testDict[ma.MMSI] = new List<AlarmAssignmentZone>();
ma.Alarms.AddRange(_storage.LoadAlarms(ma));
AlarmAssignmentZone aazone = new AlarmAssignmentZone();
aazone.Zone = zone;
aazone.Assignment = ma;
testDict[ma.MMSI].Add(aazone);
}
}
// loop
while(!_stopFlag)
{
@ -64,13 +70,40 @@ namespace bsmd.AIS2Service
foreach(int mmsi in _sitRepDict.Keys)
{
if(testZones.ContainsKey(mmsi))
if(testDict.ContainsKey(mmsi))
{
AIS_Target target = _sitRepDict[mmsi];
foreach(MonitorZone zone in testZones[mmsi]) {
if(zone.IsPointInPolygon4(target.Position))
foreach(AlarmAssignmentZone aazone in testDict[mmsi]) {
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
#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.Data;
using System.Threading.Tasks;
using System.Threading;
using System.Data.SQLite;
using log4net;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace bsmd.AIS2Service
{
@ -180,7 +179,8 @@ namespace bsmd.AIS2Service
int id = reader.GetInt32(0);
Alarm alarm = new Alarm(id, assignment);
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);
if(!reader.IsDBNull(4))
alarm.Acknowledged = reader.GetDateTime(4);
@ -207,8 +207,10 @@ namespace bsmd.AIS2Service
if (alarm.Id <= 0)
{
// 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);
cmd.Parameters.AddWithValue("@TS_FIRST", alarm.Timestamp_First);
cmd.Parameters.AddWithValue("@TS_LAST", alarm.Timestamp_Last);
int insertedRows = cmd.ExecuteNonQuery();
cmd.Dispose();
alarm.Id = GetLastInsertId();
@ -217,8 +219,14 @@ namespace bsmd.AIS2Service
else
{
// 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);
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();
cmd.Dispose();
return (updatedRows == 1);

View File

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

View File

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

View File

@ -121,5 +121,14 @@ namespace bsmd.AIS2Service.Properties {
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">
<Value Profile="(Default)">120</Value>
</Setting>
<Setting Name="MinAlarmIntervalMins" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">60</Value>
</Setting>
</Settings>
</SettingsFile>