Record last time an environmental device reported

This commit is contained in:
2024-05-28 13:53:02 -04:00
parent d69d69bf68
commit b1a9230f91
12 changed files with 181 additions and 5 deletions

View File

@@ -0,0 +1,45 @@
using ChrisKaczor.HomeMonitor.Environment.Service.Data;
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Device;
using Microsoft.AspNetCore.Mvc;
namespace ChrisKaczor.HomeMonitor.Environment.Service.Controllers;
[Route("[controller]")]
[ApiController]
public class DeviceController(Database database, IConfiguration configuration) : ControllerBase
{
[HttpGet()]
public async Task<ActionResult<List<Device>>> GetDevices()
{
return (await database.GetDevicesAsync()).ToList();
}
[HttpGet("{name}")]
public async Task<ActionResult<Device>> GetDevice(string name)
{
var device = await database.GetDeviceAsync(name);
if (device == null)
return NotFound();
return device;
}
[HttpPost()]
public async Task<ActionResult> AddDevice(Device device)
{
HttpContext.Request.Headers.TryGetValue("Authorization", out var authorizationHeader);
if (authorizationHeader != "Bearer " + configuration["AuthorizationToken"])
return Unauthorized();
var existingDevice = await database.GetDeviceAsync(device.Name);
if (existingDevice != null)
return BadRequest("Device already exists");
await database.SetDeviceLastUpdatedAsync(device.Name, device.LastUpdated);
return Ok();
}
}

View File

@@ -1,4 +1,5 @@
using ChrisKaczor.HomeMonitor.Environment.Service.Models;
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Device;
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Indoor;
using Dapper;
using DbUp;
@@ -80,4 +81,31 @@ public class Database(IConfiguration configuration)
return await connection.QueryAsync<ReadingsAggregate>(query, new { Start = start, End = end }).ConfigureAwait(false);
}
public async Task<IEnumerable<Device>> GetDevicesAsync()
{
await using var connection = CreateConnection();
var query = ResourceReader.GetString("ChrisKaczor.HomeMonitor.Environment.Service.Data.Queries.GetDevices.psql");
return await connection.QueryAsync<Device>(query).ConfigureAwait(false);
}
public async Task<Device?> GetDeviceAsync(string deviceName)
{
await using var connection = CreateConnection();
var query = ResourceReader.GetString("ChrisKaczor.HomeMonitor.Environment.Service.Data.Queries.GetDevice.psql");
return await connection.QueryFirstOrDefaultAsync<Device>(query, new { Name = deviceName }).ConfigureAwait(false);
}
public async Task SetDeviceLastUpdatedAsync(string deviceName, DateTimeOffset? lastUpdated)
{
await using var connection = CreateConnection();
var query = ResourceReader.GetString("ChrisKaczor.HomeMonitor.Environment.Service.Data.Queries.SetDeviceLastUpdated.psql");
await connection.ExecuteAsync(query, new { Name = deviceName, LastUpdated = lastUpdated }).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,7 @@
SELECT
name AS Name,
last_updated AS LastUpdated
FROM
device
WHERE
name = @Name

View File

@@ -0,0 +1,5 @@
SELECT
name AS Name,
last_updated AS LastUpdated
FROM
device

View File

@@ -0,0 +1,11 @@
INSERT INTO device(
name,
last_updated
)
VALUES (
@Name,
@LastUpdated
)
ON CONFLICT (name)
DO UPDATE
SET last_updated = EXCLUDED.last_updated

View File

@@ -0,0 +1,5 @@
CREATE TABLE device(
name text NOT NULL,
last_updated timestamptz NULL,
CONSTRAINT device_pk PRIMARY KEY (name)
);

View File

@@ -17,3 +17,55 @@ Accept: application/json
GET {{Environment_HostAddress}}/readings/aggregate?start=2024-03-11T00:00&end=2024-03-12T00:00
Accept: application/json
###
GET {{Environment_HostAddress}}/device
Accept: application/json
###
GET {{Environment_HostAddress}}/device/main
Accept: application/json
###
GET {{Environment_HostAddress}}/device/test
Accept: application/json
###
POST {{Environment_HostAddress}}/device
Content-Type: application/json
Authorization: Bearer test-token
Accept: application/json
{ "name": "test" }
###
POST {{Environment_HostAddress}}/device
Content-Type: application/json
Authorization: Bearer test-token
Accept: application/json
{ }
###
POST {{Environment_HostAddress}}/device
Content-Type: application/json
Authorization: Bearer foo
Accept: application/json
{ "name": "test" }
###
POST {{Environment_HostAddress}}/device
Content-Type: application/json
Accept: application/json
{ "name": "test" }
###

View File

@@ -77,6 +77,8 @@ public class MessageHandler : IHostedService
await _database.StoreMessageAsync(message);
await _database.SetDeviceLastUpdatedAsync(message.Name, message.Timestamp);
await SendMessage(message);
}

View File

@@ -0,0 +1,7 @@
namespace ChrisKaczor.HomeMonitor.Environment.Service.Models.Device;
public class Device
{
public required string Name { get; set; }
public DateTimeOffset? LastUpdated { get; set; }
}

View File

@@ -14,7 +14,11 @@
<None Remove="Data\Queries\GetReadingsAggregate.psql" />
<None Remove="Data\Queries\GetReadingsHistoryGrouped.psql" />
<None Remove="Data\Queries\GetRecentReadings.psql" />
<None Remove="Data\Queries\GetDevices.psql" />
<None Remove="Data\Queries\GetDevice.psql" />
<None Remove="Data\Queries\SetDeviceLastUpdated.psql" />
<None Remove="Data\Schema\1-Initial Schema.psql" />
<None Remove="Data\Schema\2-Device Table.psql" />
</ItemGroup>
<ItemGroup>
@@ -22,7 +26,11 @@
<EmbeddedResource Include="Data\Queries\GetReadingsHistoryGrouped.psql" />
<EmbeddedResource Include="Data\Queries\GetRecentReadings.psql" />
<EmbeddedResource Include="Data\Queries\CreateReading.psql" />
<EmbeddedResource Include="Data\Queries\GetDevices.psql" />
<EmbeddedResource Include="Data\Queries\GetDevice.psql" />
<EmbeddedResource Include="Data\Queries\SetDeviceLastUpdated.psql" />
<EmbeddedResource Include="Data\Schema\1-Initial Schema.psql" />
<EmbeddedResource Include="Data\Schema\2-Device Table.psql" />
</ItemGroup>
<ItemGroup>

View File

@@ -11,14 +11,15 @@
"Environment": {
"Database": {
"Host": "localhost",
"User": "sa",
"Password": "newpassword",
"Port": 1433,
"User": "postgres",
"Password": "postgres",
"Port": 5432,
"Name": "Environment",
"TrustServerCertificate": true
},
"Hub": {
"Url": "http://localhost:8080/environment"
}
}
},
"AuthorizationToken": "test-token"
}

View File

@@ -112,6 +112,11 @@ spec:
key: password
- name: Environment__Hub__Url
value: http://hub-service/environment
- name: AuthorizationToken
valueFrom:
secretKeyRef:
name: authorization
key: token
resources:
limits:
cpu: 1000m