Skip to content

Commit

Permalink
Support AlarmChange.
Browse files Browse the repository at this point in the history
  • Loading branch information
hcoona committed Dec 14, 2019
1 parent aa4e4fa commit a324883
Show file tree
Hide file tree
Showing 13 changed files with 303 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public FakePlc(byte[] id)
LowHeaterPressure = false,
NoPower = false,
HeaterOverloadedBroken = false,
ElectricalHeaterBorken = false,
ElectricalHeaterBroken = false,
};

public void Dispose()
Expand Down Expand Up @@ -337,7 +337,7 @@ private PlcFrame CreateGetAlarmResponseFrame()
responseContent[3] = (byte)(this.Alarm.LowHeaterPressure ? 0x01 : 0x00);
responseContent[4] = (byte)(this.Alarm.NoPower ? 0x01 : 0x00);
responseContent[5] = (byte)(this.Alarm.HeaterOverloadedBroken ? 0x01 : 0x00);
responseContent[6] = (byte)(this.Alarm.ElectricalHeaterBorken ? 0x01 : 0x00);
responseContent[6] = (byte)(this.Alarm.ElectricalHeaterBroken ? 0x01 : 0x00);

return PlcFrame.Create(
PlcMessageType.GetAlarmResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ public async Task<Alarm> GetAlarmAsync(GetAlarmRequest request, DateTime? deadli
LowHeaterPressure = reader.ReadByte() != 0,
NoPower = reader.ReadByte() != 0,
HeaterOverloadedBroken = reader.ReadByte() != 0,
ElectricalHeaterBorken = reader.ReadByte() != 0,
ElectricalHeaterBroken = reader.ReadByte() != 0,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// </copyright>

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
Expand All @@ -20,8 +21,10 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using GrpcAlarm = GeothermalResearchInstitute.v2.Alarm;
using GrpcAlarmChange = GeothermalResearchInstitute.v2.AlarmChange;
using GrpcMetric = GeothermalResearchInstitute.v2.Metric;
using ModelAlarm = GeothermalResearchInstitute.ServerConsole.Models.Alarm;
using ModelAlarmChange = GeothermalResearchInstitute.ServerConsole.Models.AlarmChange;
using ModelMetric = GeothermalResearchInstitute.ServerConsole.Models.Metric;

namespace GeothermalResearchInstitute.ServerConsole.GrpcServices
Expand Down Expand Up @@ -264,7 +267,48 @@ public override Task<ListAlarmChangesResponse> ListAlarmChanges(
ListAlarmChangesRequest request,
ServerCallContext context)
{
throw new NotImplementedException();
string id = BitConverter.ToString(request.DeviceId.ToByteArray());

DateTimeOffset endDateTime;
if (string.IsNullOrEmpty(request.PageToken))
{
endDateTime = request.EndTime?.ToDateTimeOffset() ?? DateTimeOffset.UtcNow;
}
else
{
endDateTime = DateTime.Parse(request.PageToken, CultureInfo.InvariantCulture);
}

endDateTime = endDateTime.ToUniversalTime();
DateTimeOffset? startDateTime = request.StartTime?.ToDateTimeOffset().ToUniversalTime();

var response = new ListAlarmChangesResponse();
using (BjdireContext db = this.serviceProvider.GetRequiredService<BjdireContext>())
{
var alarmChanges = (from m in db.AlarmChanges
where m.DeviceId == id
&& (startDateTime == null || startDateTime <= m.Timestamp)
&& m.Timestamp <= endDateTime
orderby m.Timestamp descending
select m)
.Take(request.PageSize)
.ToList();
response.AlarmChanges.AddRange(alarmChanges.Select(alarmChange =>
{
var m = new GrpcAlarmChange();
m.AssignFrom(alarmChange);
return m;
}));

if (alarmChanges.Count == request.PageSize && alarmChanges.Last().Timestamp > startDateTime)
{
response.NextPageToken = alarmChanges.Last().Timestamp
.ToUniversalTime()
.ToString(CultureInfo.InvariantCulture);
}
}

return Task.FromResult(response);
}

protected virtual void Dispose(bool disposing)
Expand All @@ -281,6 +325,90 @@ protected virtual void Dispose(bool disposing)
}
}

private static IEnumerable<ModelAlarmChange> ComputeAlarmChanges(
string deviceId,
ModelAlarm lastKnownAlarm,
ModelAlarm currentAlarm)
{
if (lastKnownAlarm.LowFlowRate != currentAlarm.LowFlowRate)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.LowFlowRate,
Direction = currentAlarm.LowFlowRate
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}

if (lastKnownAlarm.HighHeaterPressure != currentAlarm.HighHeaterPressure)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.HighHeaterPressure,
Direction = currentAlarm.HighHeaterPressure
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}

if (lastKnownAlarm.LowHeaterPressure != currentAlarm.LowHeaterPressure)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.LowHeaterPressure,
Direction = currentAlarm.LowHeaterPressure
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}

if (lastKnownAlarm.NoPower != currentAlarm.NoPower)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.NoPower,
Direction = currentAlarm.NoPower
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}

if (lastKnownAlarm.HeaterOverloadedBroken != currentAlarm.HeaterOverloadedBroken)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.HeaterOverloadedBroken,
Direction = currentAlarm.HeaterOverloadedBroken
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}

if (lastKnownAlarm.ElectricalHeaterBroken != currentAlarm.ElectricalHeaterBroken)
{
yield return new ModelAlarmChange
{
DeviceId = deviceId,
Timestamp = currentAlarm.Timestamp,
Type = AlarmType.ElectricalHeaterBroken,
Direction = currentAlarm.ElectricalHeaterBroken
? AlarmChangeDirection.Appearance
: AlarmChangeDirection.Disappearance,
};
}
}

private Task<TResponse> Invoke<TRequest, TResponse>(
Func<PlcClient, TRequest, DateTime, Task<TResponse>> stub,
ByteString deviceId,
Expand Down Expand Up @@ -314,6 +442,7 @@ private async void AskPersistDeviceAlarm(object state)
try
{
byte[] id = d.ComputeIdBinary();
string deviceId = BitConverter.ToString(id);
if (this.plcManager.PlcDictionary.TryGetValue(ByteString.CopyFrom(id), out PlcClient client))
{
this.logger.LogInformation("Ask alarm for {0}({1})", d.Id, d.Name);
Expand All @@ -324,10 +453,24 @@ private async void AskPersistDeviceAlarm(object state)

var m = new ModelAlarm
{
DeviceId = BitConverter.ToString(id),
DeviceId = deviceId,
};
alarm.AssignTo(m);

ModelAlarm lastKnownAlarmInfo = (
from mm in db.Alarms
where mm.DeviceId == deviceId
orderby mm.Timestamp descending
select mm)
.FirstOrDefault();

if (lastKnownAlarmInfo == null)
{
lastKnownAlarmInfo = new ModelAlarm();
}

db.AlarmChanges.AddRange(ComputeAlarmChanges(deviceId, lastKnownAlarmInfo, m));

db.Alarms.Add(m);
}
else
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// <copyright file="20191213144330_InitialCreate.cs" company="Shuai Zhang">
// <copyright file="20191214052037_InitialCreate.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace GeothermalResearchInstitute.ServerConsole.Migrations
Expand All @@ -14,21 +13,35 @@ protected override void Up(MigrationBuilder migrationBuilder)
{
if (migrationBuilder is null)
{
throw new ArgumentNullException(nameof(migrationBuilder));
throw new System.ArgumentNullException(nameof(migrationBuilder));
}

migrationBuilder.CreateTable(
name: "AlarmChanges",
columns: table => new
{
DeviceId = table.Column<string>(nullable: false),
Timestamp = table.Column<long>(nullable: false),
Type = table.Column<byte>(nullable: false),
Direction = table.Column<byte>(nullable: false),
},
constraints: table =>
{
table.PrimaryKey("PK_AlarmChanges", x => new { x.DeviceId, x.Timestamp, x.Type });
});

migrationBuilder.CreateTable(
name: "Alarms",
columns: table => new
{
DeviceId = table.Column<string>(nullable: false),
Timestamp = table.Column<DateTimeOffset>(nullable: false),
Timestamp = table.Column<long>(nullable: false),
LowFlowRate = table.Column<bool>(nullable: false),
HighHeaterPressure = table.Column<bool>(nullable: false),
LowHeaterPressure = table.Column<bool>(nullable: false),
NoPower = table.Column<bool>(nullable: false),
HeaterOverloadedBroken = table.Column<bool>(nullable: false),
ElectricalHeaterBorken = table.Column<bool>(nullable: false),
ElectricalHeaterBroken = table.Column<bool>(nullable: false),
},
constraints: table =>
{
Expand All @@ -40,7 +53,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
columns: table => new
{
DeviceId = table.Column<string>(nullable: false),
Timestamp = table.Column<DateTimeOffset>(nullable: false),
Timestamp = table.Column<long>(nullable: false),
OutputWaterCelsiusDegree = table.Column<float>(nullable: false),
InputWaterCelsiusDegree = table.Column<float>(nullable: false),
HeaterOutputWaterCelsiusDegree = table.Column<float>(nullable: false),
Expand All @@ -60,9 +73,12 @@ protected override void Down(MigrationBuilder migrationBuilder)
{
if (migrationBuilder is null)
{
throw new ArgumentNullException(nameof(migrationBuilder));
throw new System.ArgumentNullException(nameof(migrationBuilder));
}

migrationBuilder.DropTable(
name: "AlarmChanges");

migrationBuilder.DropTable(
name: "Alarms");

Expand Down
Loading

0 comments on commit a324883

Please sign in to comment.