mirror of
https://github.com/ckaczor/HomeMonitor.git
synced 2026-01-14 01:25:38 -05:00
Record last time an environmental device reported
This commit is contained in:
45
Environment/Service/Controllers/DeviceController.cs
Normal file
45
Environment/Service/Controllers/DeviceController.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using ChrisKaczor.HomeMonitor.Environment.Service.Models;
|
using ChrisKaczor.HomeMonitor.Environment.Service.Models;
|
||||||
|
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Device;
|
||||||
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Indoor;
|
using ChrisKaczor.HomeMonitor.Environment.Service.Models.Indoor;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using DbUp;
|
using DbUp;
|
||||||
@@ -80,4 +81,31 @@ public class Database(IConfiguration configuration)
|
|||||||
|
|
||||||
return await connection.QueryAsync<ReadingsAggregate>(query, new { Start = start, End = end }).ConfigureAwait(false);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
7
Environment/Service/Data/Queries/GetDevice.psql
Normal file
7
Environment/Service/Data/Queries/GetDevice.psql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SELECT
|
||||||
|
name AS Name,
|
||||||
|
last_updated AS LastUpdated
|
||||||
|
FROM
|
||||||
|
device
|
||||||
|
WHERE
|
||||||
|
name = @Name
|
||||||
5
Environment/Service/Data/Queries/GetDevices.psql
Normal file
5
Environment/Service/Data/Queries/GetDevices.psql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
SELECT
|
||||||
|
name AS Name,
|
||||||
|
last_updated AS LastUpdated
|
||||||
|
FROM
|
||||||
|
device
|
||||||
11
Environment/Service/Data/Queries/SetDeviceLastUpdated.psql
Normal file
11
Environment/Service/Data/Queries/SetDeviceLastUpdated.psql
Normal 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
|
||||||
5
Environment/Service/Data/Schema/2-Device Table.psql
Normal file
5
Environment/Service/Data/Schema/2-Device Table.psql
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
CREATE TABLE device(
|
||||||
|
name text NOT NULL,
|
||||||
|
last_updated timestamptz NULL,
|
||||||
|
CONSTRAINT device_pk PRIMARY KEY (name)
|
||||||
|
);
|
||||||
@@ -17,3 +17,55 @@ Accept: application/json
|
|||||||
|
|
||||||
GET {{Environment_HostAddress}}/readings/aggregate?start=2024-03-11T00:00&end=2024-03-12T00:00
|
GET {{Environment_HostAddress}}/readings/aggregate?start=2024-03-11T00:00&end=2024-03-12T00:00
|
||||||
Accept: application/json
|
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" }
|
||||||
|
|
||||||
|
###
|
||||||
@@ -77,6 +77,8 @@ public class MessageHandler : IHostedService
|
|||||||
|
|
||||||
await _database.StoreMessageAsync(message);
|
await _database.StoreMessageAsync(message);
|
||||||
|
|
||||||
|
await _database.SetDeviceLastUpdatedAsync(message.Name, message.Timestamp);
|
||||||
|
|
||||||
await SendMessage(message);
|
await SendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
Environment/Service/Models/Device/Device.cs
Normal file
7
Environment/Service/Models/Device/Device.cs
Normal 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; }
|
||||||
|
}
|
||||||
@@ -14,7 +14,11 @@
|
|||||||
<None Remove="Data\Queries\GetReadingsAggregate.psql" />
|
<None Remove="Data\Queries\GetReadingsAggregate.psql" />
|
||||||
<None Remove="Data\Queries\GetReadingsHistoryGrouped.psql" />
|
<None Remove="Data\Queries\GetReadingsHistoryGrouped.psql" />
|
||||||
<None Remove="Data\Queries\GetRecentReadings.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\1-Initial Schema.psql" />
|
||||||
|
<None Remove="Data\Schema\2-Device Table.psql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -22,7 +26,11 @@
|
|||||||
<EmbeddedResource Include="Data\Queries\GetReadingsHistoryGrouped.psql" />
|
<EmbeddedResource Include="Data\Queries\GetReadingsHistoryGrouped.psql" />
|
||||||
<EmbeddedResource Include="Data\Queries\GetRecentReadings.psql" />
|
<EmbeddedResource Include="Data\Queries\GetRecentReadings.psql" />
|
||||||
<EmbeddedResource Include="Data\Queries\CreateReading.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\1-Initial Schema.psql" />
|
||||||
|
<EmbeddedResource Include="Data\Schema\2-Device Table.psql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -11,14 +11,15 @@
|
|||||||
"Environment": {
|
"Environment": {
|
||||||
"Database": {
|
"Database": {
|
||||||
"Host": "localhost",
|
"Host": "localhost",
|
||||||
"User": "sa",
|
"User": "postgres",
|
||||||
"Password": "newpassword",
|
"Password": "postgres",
|
||||||
"Port": 1433,
|
"Port": 5432,
|
||||||
"Name": "Environment",
|
"Name": "Environment",
|
||||||
"TrustServerCertificate": true
|
"TrustServerCertificate": true
|
||||||
},
|
},
|
||||||
"Hub": {
|
"Hub": {
|
||||||
"Url": "http://localhost:8080/environment"
|
"Url": "http://localhost:8080/environment"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"AuthorizationToken": "test-token"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,11 @@ spec:
|
|||||||
key: password
|
key: password
|
||||||
- name: Environment__Hub__Url
|
- name: Environment__Hub__Url
|
||||||
value: http://hub-service/environment
|
value: http://hub-service/environment
|
||||||
|
- name: AuthorizationToken
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: authorization
|
||||||
|
key: token
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 1000m
|
cpu: 1000m
|
||||||
|
|||||||
Reference in New Issue
Block a user