Skip to content

Commit 233d605

Browse files
committed
Cache robot telemetry installationcode
1 parent 289fb3c commit 233d605

File tree

8 files changed

+113
-41
lines changed

8 files changed

+113
-41
lines changed

backend/api.test/Mocks/SignalRServiceMock.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,16 @@ T messageObject
1515
await Task.CompletedTask;
1616
}
1717

18-
public async Task SendMessageAsync(string label, Installation? installation, string message)
18+
public async Task SendMessageAsync<T>(
19+
string label,
20+
string? installationCode,
21+
T messageObject
22+
)
23+
{
24+
await Task.CompletedTask;
25+
}
26+
27+
public async Task SendMessageAsync(string label, string? installationCode, string message)
1928
{
2029
await Task.CompletedTask;
2130
}

backend/api/EventHandlers/MqttEventHandler.cs

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Api.Services.Models;
1010
using Api.Utilities;
1111
using Microsoft.EntityFrameworkCore;
12+
using Microsoft.Extensions.Caching.Memory;
1213

1314
namespace Api.EventHandlers
1415
{
@@ -23,11 +24,18 @@ public class MqttEventHandler : EventHandlerBase
2324

2425
private readonly Semaphore _updateRobotSemaphore = new(1, 1);
2526

26-
public MqttEventHandler(ILogger<MqttEventHandler> logger, IServiceScopeFactory scopeFactory)
27+
private readonly IMemoryCache _cache;
28+
29+
public MqttEventHandler(
30+
ILogger<MqttEventHandler> logger,
31+
IServiceScopeFactory scopeFactory,
32+
IMemoryCache cache
33+
)
2734
{
2835
_logger = logger;
2936
// Reason for using factory: https://www.thecodebuzz.com/using-dbcontext-instance-in-ihostedservice/
3037
_scopeFactory = scopeFactory;
38+
_cache = cache;
3139

3240
Subscribe();
3341
}
@@ -606,40 +614,77 @@ private async void OnIsarTaskUpdate(object? sender, MqttReceivedArgs mqttArgs)
606614
);
607615
}
608616

617+
private async Task<string?> GetRobotInstallationCode(string robotIsarId)
618+
{
619+
if (!_cache.TryGetValue(robotIsarId, out string? installationCode))
620+
{
621+
var robot = await RobotService.ReadByIsarId(robotIsarId);
622+
623+
if (robot == null)
624+
return null;
625+
var cacheEntryOptions = new MemoryCacheEntryOptions
626+
{
627+
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1),
628+
};
629+
_cache.Set(
630+
robotIsarId,
631+
robot.CurrentInstallation.InstallationCode,
632+
cacheEntryOptions
633+
);
634+
installationCode = robot.CurrentInstallation.InstallationCode;
635+
}
636+
return installationCode;
637+
}
638+
609639
private async void OnIsarBatteryUpdate(object? sender, MqttReceivedArgs mqttArgs)
610640
{
611641
var batteryStatus = (IsarBatteryMessage)mqttArgs.Message;
612642

613-
var robot = await RobotService.ReadByIsarId(batteryStatus.IsarId);
643+
var installationCode = await GetRobotInstallationCode(batteryStatus.IsarId);
614644

615-
if (robot == null)
645+
if (installationCode == null)
616646
return;
617647

618-
await RobotService.SendToSignalROnPropertyUpdate(
619-
robot.Id,
620-
"batteryState",
621-
batteryStatus.BatteryState
648+
await SignalRService.SendMessageAsync(
649+
"Robot telemetry updated",
650+
installationCode,
651+
new UpdateRobotTelemetryMessage
652+
{
653+
IsarId = batteryStatus.IsarId,
654+
TelemetryName = "batteryState",
655+
TelemetryValue = batteryStatus.BatteryState,
656+
}
622657
);
623-
await RobotService.SendToSignalROnPropertyUpdate(
624-
robot.Id,
625-
"batteryLevel",
626-
batteryStatus.BatteryLevel
658+
await SignalRService.SendMessageAsync(
659+
"Robot telemetry updated",
660+
installationCode,
661+
new UpdateRobotTelemetryMessage
662+
{
663+
IsarId = batteryStatus.IsarId,
664+
TelemetryName = "batteryLevel",
665+
TelemetryValue = batteryStatus.BatteryLevel,
666+
}
627667
);
628668
}
629669

630670
private async void OnIsarPressureUpdate(object? sender, MqttReceivedArgs mqttArgs)
631671
{
632672
var pressureStatus = (IsarPressureMessage)mqttArgs.Message;
633673

634-
var robot = await RobotService.ReadByIsarId(pressureStatus.IsarId);
674+
var installationCode = await GetRobotInstallationCode(pressureStatus.IsarId);
635675

636-
if (robot == null)
676+
if (installationCode == null)
637677
return;
638678

639-
await RobotService.SendToSignalROnPropertyUpdate(
640-
robot.Id,
641-
"pressureLevel",
642-
pressureStatus.PressureLevel
679+
await SignalRService.SendMessageAsync(
680+
"Robot telemetry updated",
681+
installationCode,
682+
new UpdateRobotTelemetryMessage
683+
{
684+
IsarId = pressureStatus.IsarId,
685+
TelemetryName = "pressureLevel",
686+
TelemetryValue = pressureStatus.PressureLevel,
687+
}
643688
);
644689
}
645690

backend/api/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
builder.Logging.ClearProviders();
5151
builder.Logging.AddConsole();
5252

53+
builder.Services.AddMemoryCache();
5354
builder.Services.ConfigureDatabase(builder.Configuration, builder.Environment.EnvironmentName);
5455

5556
builder.Services.ConfigureMissionLoader(builder.Configuration);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Api.Services.Models
2+
{
3+
public class UpdateRobotTelemetryMessage
4+
{
5+
public required string IsarId { get; set; }
6+
public required string TelemetryName { get; set; }
7+
public object? TelemetryValue { get; set; }
8+
}
9+
}

backend/api/Services/SignalRService.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
using Api.Services.Models;
66
using Api.SignalRHubs;
77
using Microsoft.AspNetCore.SignalR;
8-
using Microsoft.Extensions.Configuration;
98

109
namespace Api.Services
1110
{
1211
public interface ISignalRService
1312
{
1413
public Task SendMessageAsync<T>(string label, Installation? installation, T messageObject);
15-
public Task SendMessageAsync(string label, Installation? installation, string message);
14+
public Task SendMessageAsync<T>(string label, string? installationCode, T messageObject);
15+
public Task SendMessageAsync(string label, string? installationCode, string message);
1616
public void ReportDockFailureToSignalR(Robot robot, string message);
1717
public void ReportGeneralFailToSignalR(Robot robot, string title, string message);
1818
public void ReportAutoScheduleToSignalR(
@@ -44,10 +44,20 @@ T messageObject
4444
)
4545
{
4646
string json = JsonSerializer.Serialize(messageObject, _serializerOptions);
47-
await SendMessageAsync(label, installation, json);
47+
await SendMessageAsync(label, installation?.InstallationCode, json);
4848
}
4949

50-
public async Task SendMessageAsync(string label, Installation? installation, string message)
50+
public async Task SendMessageAsync<T>(
51+
string label,
52+
string? installationCode,
53+
T messageObject
54+
)
55+
{
56+
string json = JsonSerializer.Serialize(messageObject, _serializerOptions);
57+
await SendMessageAsync(label, installationCode, json);
58+
}
59+
60+
public async Task SendMessageAsync(string label, string? installationCode, string message)
5161
{
5262
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Local")
5363
{
@@ -57,23 +67,20 @@ public async Task SendMessageAsync(string label, Installation? installation, str
5767
if (localDevUser is null || localDevUser.Equals("", StringComparison.Ordinal))
5868
return;
5969

60-
if (installation != null)
70+
if (installationCode != null)
6171
await _signalRHub
6272
.Clients.Group(
63-
localDevUser
64-
+ installation.InstallationCode.ToUpper(CultureInfo.CurrentCulture)
73+
localDevUser + installationCode.ToUpper(CultureInfo.CurrentCulture)
6574
)
6675
.SendAsync(label, "all", message);
6776
else
6877
await _signalRHub.Clients.Group(localDevUser).SendAsync(label, "all", message);
6978
}
7079
else
7180
{
72-
if (installation != null)
81+
if (installationCode != null)
7382
await _signalRHub
74-
.Clients.Group(
75-
installation.InstallationCode.ToUpper(CultureInfo.CurrentCulture)
76-
)
83+
.Clients.Group(installationCode.ToUpper(CultureInfo.CurrentCulture))
7784
.SendAsync(label, "all", message);
7885
else
7986
await _signalRHub.Clients.All.SendAsync(label, "all", message);
@@ -106,7 +113,7 @@ string installationCode
106113
{
107114
_ = SendMessageAsync(
108115
"Alert",
109-
null,
116+
(string?)null,
110117
new AlertResponse(type, missionDefinitionId, message, installationCode, null)
111118
);
112119
}

frontend/src/components/Contexts/SignalRContext.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export enum SignalREventLabels {
157157
robotAdded = 'Robot added',
158158
robotUpdated = 'Robot updated',
159159
robotPropertyUpdated = 'Robot property updated',
160+
robotTelemetryUpdated = 'Robot telemetry updated',
160161
robotDeleted = 'Robot deleted',
161162
inspectionUpdated = 'Inspection updated',
162163
alert = 'Alert',

frontend/src/hooks/useRobotTelemetry.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ export const useRobotTelemetry = (robotWithoutDetails: RobotWithoutTelemetry) =>
2525

2626
useEffect(() => {
2727
if (connectionReady) {
28-
registerEvent(SignalREventLabels.robotPropertyUpdated, (username: string, message: string) => {
28+
registerEvent(SignalREventLabels.robotTelemetryUpdated, (username: string, message: string) => {
2929
const robotPropertyUpdate: RobotTelemetryPropertyUpdate = JSON.parse(message)
3030
if (robotPropertyUpdate.robotId === robotId) {
31-
if (robotPropertyUpdate.propertyName === 'batteryLevel') {
32-
setRobotBatteryLevel(robotPropertyUpdate.propertyValue as number)
31+
if (robotPropertyUpdate.telemetryName === 'batteryLevel') {
32+
setRobotBatteryLevel(robotPropertyUpdate.telemetryValue as number)
3333
clearTimeout(batteryReadingTimer)
3434
batteryReadingTimer = setTimeout(clearBatteryLevel, 30 * 1000) // Time in milliseconds
35-
} else if (robotPropertyUpdate.propertyName === 'pressureLevel') {
36-
setRobotPressureLevel(robotPropertyUpdate.propertyValue as number)
35+
} else if (robotPropertyUpdate.telemetryName === 'pressureLevel') {
36+
setRobotPressureLevel(robotPropertyUpdate.telemetryValue as number)
3737
clearTimeout(pressureReadingTimer)
3838
pressureReadingTimer = setTimeout(clearPressureLevel, 30 * 1000) // Time in milliseconds
39-
} else if (robotPropertyUpdate.propertyName === 'batteryState') {
40-
setRobotBatteryStatus(robotPropertyUpdate.propertyValue as BatteryStatus)
41-
} else if (robotPropertyUpdate.propertyName === 'pose') {
42-
setRobotPose(robotPropertyUpdate.propertyValue as Pose)
39+
} else if (robotPropertyUpdate.telemetryName === 'batteryState') {
40+
setRobotBatteryStatus(robotPropertyUpdate.telemetryValue as BatteryStatus)
41+
} else if (robotPropertyUpdate.telemetryName === 'pose') {
42+
setRobotPose(robotPropertyUpdate.telemetryValue as Pose)
4343
}
4444
}
4545
})

frontend/src/models/Robot.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,6 @@ export interface RobotPropertyUpdate {
9090
}
9191
export interface RobotTelemetryPropertyUpdate {
9292
robotId: string
93-
propertyName: keyof RobotTelemetry
94-
propertyValue: number | BatteryStatus | Pose
93+
telemetryName: keyof RobotTelemetry
94+
telemetryValue: number | BatteryStatus | Pose
9595
}

0 commit comments

Comments
 (0)