using Edge.Core.Processor;
using Edge.Core.Processor.Dispatcher.Attributes;
using Edge.Core.UniversalApi;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AreaIntrudeDetecterServer
{
[MetaPartsDescriptor(
"lang-zh-cn:区域闯入检测lang-zh-tw:區域闖入檢測lang-en-us:Area intrude detecter",
"lang-zh-cn:接收某区域的闯入行为,此程序作为服务器(接收端)需要与检测客户端配合使用(如基于视频流分析的jetson inference framework)" +
"lang-en-us:接收某区域的闯入行为,此程序作为服务器(接收端)需要与检测客户端配合使用(如基于视频流分析的jetson inference framework)",
new[] { "lang-zh-cn:摄像头lang-en-us:Cameralang-zh-tw:攝像頭" })]
public class App : IAppProcessor
{
private IServiceProvider services;
public string MetaConfigName { get; set; }
public class Area
{
public string Name { get; set; }
public int BndBox_LeftTop_X { get; set; }
public int BndBox_RightBottom_X { get; set; }
public int BndBox_LeftTop_Y { get; set; }
public int BndBox_RightBottom_Y { get; set; }
}
///
/// basically info can refer https://rawgit.com/dusty-nv/jetson-inference/python/docs/html/python/jetson.inference.html#detectNet
///
public class Detection
{
public string AreaName { get; set; }
public int? ClassID { get; set; }
public string ClassName { get; set; }
public double Confidence { get; set; }
public int? Height { get; set; }
public int? Width { get; set; }
}
private Timer timelyFireGenericAlarmTimer;
private int busy = 0;
private List cache = new List();
public App(int appConfig, IServiceProvider services)
{
this.services = services;
this.timelyFireGenericAlarmTimer = new Timer(async (o) =>
{
if (0 != Interlocked.CompareExchange(ref this.busy, 1, 0))
return;
try
{
var groupByAreaName = cache.GroupBy(d => new { d.AreaName, d.ClassName });
var universalApiHub = this.services.GetRequiredService();
foreach (var g in groupByAreaName)
{
foreach (var ig in g)
{
await universalApiHub.ClearAndFirePersistGenericAlarm(this,
new GenericAlarm()
{
Category = $"区域闯入检测",
Title = $"{this.GetFriendlyAreaName(g.Key.AreaName)} - {this.GetFriendlyClassName(ig.ClassName)}闯入",
Detail = $"系统有{(Math.Round(ig.Confidence, 2) * 100).ToString().Substring(0, 2)}%的确信度认为有{ig.ClassName} (ClassId: {ig.ClassID})闯入至区域: {this.GetFriendlyAreaName(g.Key.AreaName)}",
Severity = GenericAlarmSeverity.Warning
}, g => g.Title, g => g.Title);
}
}
this.cache.Clear();
}
finally
{
this.busy = 0;
}
}, null, 0, 1500);
}
int maxWaitTimes = 20;
[UniversalApi]
public async Task Report(IEnumerable input)
{
Console.WriteLine(input.Select(d => $"Detect in area: {d.AreaName} has object: {d.ClassName} with conf: {d.Confidence}").Aggregate((acc, n) => acc + " | " + n));
int waitTimes = 0;
while (0 != Interlocked.CompareExchange(ref this.busy, 1, 0))
{
Thread.Sleep(50);
waitTimes++;
if (waitTimes > maxWaitTimes)
return false;
}
try
{
this.cache.AddRange(input);
}
finally { this.busy = 0; }
return true;
}
private string GetFriendlyAreaName(string rawName)
{
switch (rawName.ToLower())
{
case "indoor0": return "消防通道A";
case "indoor1": return "消防通道B";
case "indoor2": return "消防通道C";
case "indoor3": return "消防通道D";
case "indoor4": return "消防通道E";
case "outdoor0": return "卸油区通道A";
case "outdoor1": return "卸油区通道B";
case "outdoor2": return "油罐区通道A";
case "outdoor3": return "油罐区通道B";
case "outdoor4": return "油罐区通道C";
default: return rawName;
}
}
private string GetFriendlyClassName(string rawName)
{
switch (rawName.ToLower())
{
case "person": return "人员";
case "chair": return "座椅";
case "bird": return "鸟类";
case "truck": return "卡车";
case "car": return "小汽车";
default: return rawName;
}
}
private List savedAreas = new List();
[UniversalApi]
public async Task SaveAreas(IEnumerable input)
{
this.savedAreas.AddRange(input);
return true;
}
[UniversalApi]
public async Task> GetAreas()
{
return this.savedAreas;
}
[UniversalApi]
public async Task ClearAreas()
{
this.savedAreas.Clear();
return true;
}
public void Init(IEnumerable processors)
{
//throw new NotImplementedException();
}
}
}