aboutsummaryrefslogtreecommitdiff
path: root/PagerMessage.cs
diff options
context:
space:
mode:
authorJake Mannens <jake@asger.xyz>2024-09-20 16:21:09 +1000
committerJake Mannens <jake@asger.xyz>2024-10-29 11:42:54 +1100
commite8e3c4cba8ffa0056e984c113cfbb75319e00022 (patch)
tree8336315e61f9e77207276d478b25fe5dc7c3d06c /PagerMessage.cs
parent0e21907c76dbefed11f382bcf949143f0716567f (diff)
v0.4-rc1v0.4-rc1
Diffstat (limited to 'PagerMessage.cs')
-rw-r--r--PagerMessage.cs71
1 files changed, 56 insertions, 15 deletions
diff --git a/PagerMessage.cs b/PagerMessage.cs
index b817d23..765636c 100644
--- a/PagerMessage.cs
+++ b/PagerMessage.cs
@@ -1,6 +1,6 @@
using Microsoft.EntityFrameworkCore;
-using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
namespace PagerParser;
@@ -21,6 +21,7 @@ public enum EmergencyService {
[Index(nameof(Message))]
public class PagerMessage {
+ [JsonIgnore]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PagerMessageId { get; set; }
public DateTime Timestamp { get; set; }
@@ -32,8 +33,19 @@ public class PagerMessage {
(Timestamp, Message).GetHashCode();
}
+public enum MapType {
+ Melways = 1,
+ SpacialVisionCentral = 2,
+ SpacialVisionNorthEast = 3,
+ SpacialVisionNorthWest = 4,
+ SpacialVisionSouthEast = 5,
+ SpacialVisionSouthWest = 6
+}
+
[Index(nameof(FirecomJobNo))]
+[Index(nameof(PageDestination))]
public class ParsedPagerMessage {
+ [JsonIgnore]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ParsedPagerMessageId { get; set; }
public int FirecomJobNo { get; set; }
@@ -41,16 +53,19 @@ public class ParsedPagerMessage {
public string JobType { get; set; }
public AlertLevel AlertLevel { get; set; }
public string Description { get; set; }
- public int? MelwaysMapNo { get; set; }
- public string? MelwaysGrid { get; set; }
+ public MapType? MapType { get; set; }
+ public int? MapNo { get; set; }
+ public string? MapGrid { get; set; }
public int? GridReference { get; set; }
public EmergencyService AttendingServices { get; set; }
public string? Note { get; set; }
public int? FireGroundChannel { get; set; }
+ public List<string> PagedServices { get; set; } = new();
public string PageDestination { get; set; }
public virtual GpsPosition? GpsPosition { get; set; }
+ [JsonIgnore]
[ForeignKey(nameof(PagerMessage))]
public virtual PagerMessage OriginalMessage { get; set; }
}
@@ -67,10 +82,23 @@ public interface IPagerMessageParserService {
// Running a single instance of the service isn't an issue, as this
// service is only used by the fetch service for parsing new messages.
public class PagerMessageParserService : IPagerMessageParserService {
+ public static readonly Dictionary<string, MapType> MapTypeMap = new() {
+ { "M", MapType.Melways },
+ { "SVC", MapType.SpacialVisionCentral },
+ { "SVNE", MapType.SpacialVisionNorthEast },
+ { "SVNW", MapType.SpacialVisionNorthWest },
+ { "SVSE", MapType.SpacialVisionSouthEast },
+ { "SVSW", MapType.SpacialVisionSouthWest },
+ };
+
private const string Pattern =
- @"^@@ALERT\s+([A-Z]*[0-9]+)\s+([A-Z&]+)C([13])\s+(\*\s+)?(.*)\s+M\s+(\d+)\s+([A-Z]\d+)\s+\((\d+)\)\s+(\*\s+[^*]+\*\s+)?([AFPRS]+)\s+(([A-Z0-9]+\s)+)F([0-9]+)\s+\[([A-Z]+)\]$";
+ @"^@@ALERT\s+([A-Z]*[0-9]+)\s+([A-Z&]+)C([13])\s+(\*\s+)?(.*)\s+(M|SVC|SVNE|SVNW|SVSE|SVSW)\s+(\d+)\s+([A-Z]\d+)\s+\((\d+)\)\s+(\*\s+[^*]+\*\s+)?([AFPRS]+)\s+(([A-Z0-9]+\s)+)F([0-9]+)\s+\[([A-Z0-9]+)[_]?\]$";
+
+ private Regex pageMessageRegex =
+ new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
- private Regex pageMessageRegex = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
+ private Regex firegroundRegex =
+ new Regex("^FGD([0-9]+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public ParsedPagerMessage Parse(string message) {
ParsedPagerMessage m = new();
@@ -84,25 +112,38 @@ public class PagerMessageParserService : IPagerMessageParserService {
m.AssignmentArea = match.Groups[1].Value;
m.JobType = match.Groups[2].Value;
m.Description = match.Groups[5].Value;
- m.FirecomJobNo = Int32.Parse(match.Groups[13].Value);
- m.PageDestination = match.Groups[14].Value;
+ m.FirecomJobNo = Int32.Parse(match.Groups[14].Value);
+ m.PageDestination = match.Groups[15].Value;
// Parse optional message components
- if(match.Groups[6].Success) m.MelwaysMapNo = Int32.Parse(match.Groups[6].Value);
- if(match.Groups[7].Success) m.MelwaysGrid = match.Groups[7].Value;
- if(match.Groups[8].Success) m.GridReference = Int32.Parse(match.Groups[8].Value);
- if(match.Groups[9].Success) m.Note = match.Groups[9].Value;
+ if(match.Groups[7].Success) m.MapNo = Int32.Parse(match.Groups[7].Value);
+ if(match.Groups[8].Success) m.MapGrid = match.Groups[8].Value;
+ if(match.Groups[9].Success) m.GridReference = Int32.Parse(match.Groups[9].Value);
+ if(match.Groups[10].Success) m.Note = match.Groups[10].Value;
+
+ // Parse map type using map type dictionary
+ if(match.Groups[6].Success) {
+ MapTypeMap.TryGetValue(match.Groups[6].Value, out var mapType);
+ m.MapType = mapType;
+ }
+
+ var pagedServicesField = match.Groups[12].Value.Split(" ");
// Attempt to extract the fire-ground channel as it can be mixed
// into the list of paged services.
- m.FireGroundChannel = match.Groups[11].Value
- .Split(" ")
- .Select(x => Regex.Match(x, "^FGD([0-9]+)$"))
+ m.FireGroundChannel = pagedServicesField
+ .Select(x => firegroundRegex.Match(x))
.Where(m => m.Success)
.Select(m => (int?) int.Parse(m.Groups[1].Value))
.DefaultIfEmpty(null)
.First();
+ // Parse the paged services, ignoring the fireground channel
+ m.PagedServices = pagedServicesField
+ .Where(x => !firegroundRegex.IsMatch(x))
+ .Where(x => !string.IsNullOrEmpty(x))
+ .ToList();
+
switch(match.Groups[3].Value) {
case "1": m.AlertLevel = AlertLevel.Code1; break;
case "3": m.AlertLevel = AlertLevel.Code3; break;
@@ -110,7 +151,7 @@ public class PagerMessageParserService : IPagerMessageParserService {
}
// Handle each character to construct a bitmap of attending services
- foreach(char c in match.Groups[10].Value) {
+ foreach(char c in match.Groups[11].Value) {
switch(c) {
case 'A': m.AttendingServices |= EmergencyService.Ambulance; break;
case 'F': m.AttendingServices |= EmergencyService.Fire; break;