mirror of
https://github.com/ckaczor/HomeMonitor.git
synced 2026-02-16 10:58:32 -05:00
Update Environment to TimescaleDB
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
using System.Reflection;
|
using Dapper;
|
||||||
using Dapper;
|
|
||||||
using DbUp;
|
using DbUp;
|
||||||
using Microsoft.Data.SqlClient;
|
using Npgsql;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
namespace ChrisKaczor.HomeMonitor.Environment.Service.Data;
|
namespace ChrisKaczor.HomeMonitor.Environment.Service.Data;
|
||||||
|
|
||||||
@@ -9,12 +9,13 @@ public class Database(IConfiguration configuration)
|
|||||||
{
|
{
|
||||||
private string GetConnectionString()
|
private string GetConnectionString()
|
||||||
{
|
{
|
||||||
var connectionStringBuilder = new SqlConnectionStringBuilder
|
var connectionStringBuilder = new NpgsqlConnectionStringBuilder
|
||||||
{
|
{
|
||||||
DataSource = $"{configuration["Environment:Database:Host"]},{configuration["Environment:Database:Port"]}",
|
Host = configuration["Environment:Database:Host"],
|
||||||
UserID = configuration["Environment:Database:User"],
|
Port = configuration.GetValue<int>("Environment:Database:Port"),
|
||||||
|
Username = configuration["Environment:Database:User"],
|
||||||
Password = configuration["Environment:Database:Password"],
|
Password = configuration["Environment:Database:Password"],
|
||||||
InitialCatalog = configuration["Environment:Database:Name"],
|
Database = configuration["Environment:Database:Name"],
|
||||||
TrustServerCertificate = bool.Parse(configuration["Environment:Database:TrustServerCertificate"] ?? "false")
|
TrustServerCertificate = bool.Parse(configuration["Environment:Database:TrustServerCertificate"] ?? "false")
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,16 +26,16 @@ public class Database(IConfiguration configuration)
|
|||||||
{
|
{
|
||||||
var connectionString = GetConnectionString();
|
var connectionString = GetConnectionString();
|
||||||
|
|
||||||
DbUp.EnsureDatabase.For.SqlDatabase(connectionString);
|
DbUp.EnsureDatabase.For.PostgresqlDatabase(connectionString);
|
||||||
|
|
||||||
var upgradeEngine = DeployChanges.To.SqlDatabase(connectionString).WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains(".Schema.")).LogToConsole().Build();
|
var upgradeEngine = DeployChanges.To.PostgresqlDatabase(connectionString).WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains(".Schema.")).LogToConsole().Build();
|
||||||
|
|
||||||
upgradeEngine.PerformUpgrade();
|
upgradeEngine.PerformUpgrade();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SqlConnection CreateConnection()
|
private NpgsqlConnection CreateConnection()
|
||||||
{
|
{
|
||||||
var connection = new SqlConnection(GetConnectionString());
|
var connection = new NpgsqlConnection(GetConnectionString());
|
||||||
connection.Open();
|
connection.Open();
|
||||||
|
|
||||||
return connection;
|
return connection;
|
||||||
|
|||||||
@@ -1,25 +1,30 @@
|
|||||||
BEGIN TRANSACTION
|
INSERT INTO
|
||||||
|
reading
|
||||||
INSERT Reading
|
(
|
||||||
(Timestamp, Name, Model, Temperature, Pressure, Humidity, Luminance, GasResistance, ColorTemperature, AirQualityIndex)
|
time,
|
||||||
SELECT
|
name,
|
||||||
@Timestamp,
|
model,
|
||||||
@Name,
|
temperature,
|
||||||
@Model,
|
pressure,
|
||||||
@Temperature,
|
humidity,
|
||||||
@Pressure,
|
luminance,
|
||||||
@Humidity,
|
gas_resistance,
|
||||||
@Luminance,
|
color_temperature,
|
||||||
@GasResistance,
|
air_quality_index
|
||||||
@ColorTemperature,
|
)
|
||||||
@AirQualityIndex
|
VALUES
|
||||||
WHERE NOT EXISTS
|
(
|
||||||
(
|
@Timestamp,
|
||||||
SELECT
|
@Name,
|
||||||
1
|
@Model,
|
||||||
FROM
|
@Temperature,
|
||||||
Reading WITH (UPDLOCK, SERIALIZABLE)
|
@Pressure,
|
||||||
WHERE Timestamp = @Timestamp AND Name = @Name AND Model = @Model
|
@Humidity,
|
||||||
)
|
@Luminance,
|
||||||
|
@GasResistance,
|
||||||
COMMIT TRANSACTION
|
@ColorTemperature,
|
||||||
|
@AirQualityIndex
|
||||||
|
)
|
||||||
|
ON CONFLICT
|
||||||
|
ON CONSTRAINT reading_pk
|
||||||
|
DO NOTHING
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
CREATE TABLE Reading
|
CREATE TABLE
|
||||||
(
|
reading (
|
||||||
Timestamp datetimeoffset NOT NULL,
|
time timestamptz NOT NULL,
|
||||||
Name nvarchar(50) NOT NULL,
|
name text NOT NULL,
|
||||||
Model nvarchar(50) NOT NULL,
|
model text NOT NULL,
|
||||||
Temperature decimal(5, 2) NOT NULL,
|
temperature DECIMAL NOT NULL,
|
||||||
Pressure decimal(6, 2) NOT NULL,
|
pressure DECIMAL NOT NULL,
|
||||||
Humidity decimal(5, 2) NOT NULL,
|
humidity DECIMAL NOT NULL,
|
||||||
Luminance int NOT NULL,
|
luminance INT NOT NULL,
|
||||||
GasResistance int NOT NULL,
|
gas_resistance INT NOT NULL,
|
||||||
ColorTemperature int NOT NULL,
|
color_temperature INT NOT NULL,
|
||||||
AirQualityIndex decimal(4, 1) NOT NULL,
|
air_quality_index DECIMAL NOT NULL,
|
||||||
CONSTRAINT reading_pk PRIMARY KEY (Timestamp, Name, Model)
|
CONSTRAINT reading_pk PRIMARY KEY (time, name, model)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
create_hypertable('reading', by_range('time'));
|
||||||
@@ -14,7 +14,7 @@ public class MessageHandler : IHostedService
|
|||||||
|
|
||||||
private readonly MqttFactory _mqttFactory;
|
private readonly MqttFactory _mqttFactory;
|
||||||
private readonly string _topic;
|
private readonly string _topic;
|
||||||
private readonly HubConnection _hubConnection;
|
private readonly HubConnection? _hubConnection;
|
||||||
|
|
||||||
public MessageHandler(IConfiguration configuration, Database database)
|
public MessageHandler(IConfiguration configuration, Database database)
|
||||||
{
|
{
|
||||||
@@ -33,12 +33,16 @@ public class MessageHandler : IHostedService
|
|||||||
|
|
||||||
_mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceivedAsync;
|
_mqttClient.ApplicationMessageReceivedAsync += OnApplicationMessageReceivedAsync;
|
||||||
|
|
||||||
_hubConnection = new HubConnectionBuilder().WithUrl(configuration["Environment:Hub:Url"] ?? string.Empty).Build();
|
var hubUrl = configuration["Environment:Hub:Url"];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(hubUrl))
|
||||||
|
_hubConnection = new HubConnectionBuilder().WithUrl(hubUrl).Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StartAsync(CancellationToken cancellationToken)
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await _hubConnection.StartAsync(cancellationToken);
|
if (_hubConnection != null)
|
||||||
|
await _hubConnection.StartAsync(cancellationToken);
|
||||||
|
|
||||||
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(_configuration["Mqtt:Server"]).Build();
|
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(_configuration["Mqtt:Server"]).Build();
|
||||||
await _mqttClient.ConnectAsync(mqttClientOptions, cancellationToken);
|
await _mqttClient.ConnectAsync(mqttClientOptions, cancellationToken);
|
||||||
@@ -51,7 +55,8 @@ public class MessageHandler : IHostedService
|
|||||||
{
|
{
|
||||||
await _mqttClient.DisconnectAsync(new MqttClientDisconnectOptionsBuilder().Build(), cancellationToken);
|
await _mqttClient.DisconnectAsync(new MqttClientDisconnectOptionsBuilder().Build(), cancellationToken);
|
||||||
|
|
||||||
await _hubConnection.StopAsync(cancellationToken);
|
if (_hubConnection != null)
|
||||||
|
await _hubConnection.StopAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
|
private async Task OnApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
|
||||||
@@ -75,6 +80,9 @@ public class MessageHandler : IHostedService
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (_hubConnection == null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (_hubConnection.State == HubConnectionState.Disconnected)
|
if (_hubConnection.State == HubConnectionState.Disconnected)
|
||||||
await _hubConnection.StartAsync();
|
await _hubConnection.StartAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ChrisKaczor.Common.OpenTelemetry" Version="1.0.1" />
|
<PackageReference Include="ChrisKaczor.Common.OpenTelemetry" Version="1.0.2" />
|
||||||
<PackageReference Include="Dapper" Version="2.1.28" />
|
<PackageReference Include="Dapper" Version="2.1.28" />
|
||||||
<PackageReference Include="dbup-sqlserver" Version="5.0.37" />
|
<PackageReference Include="dbup-postgresql" Version="5.0.40" />
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.1" />
|
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.1" />
|
||||||
<PackageReference Include="MQTTnet.AspNetCore" Version="4.3.3.952" />
|
<PackageReference Include="MQTTnet.AspNetCore" Version="4.3.3.952" />
|
||||||
|
|||||||
@@ -15,9 +15,9 @@
|
|||||||
"Host": "",
|
"Host": "",
|
||||||
"User": "",
|
"User": "",
|
||||||
"Password": "",
|
"Password": "",
|
||||||
"Name": "Environment",
|
"Name": "environment",
|
||||||
"TrustServerCertificate": true,
|
"TrustServerCertificate": true,
|
||||||
"Port": 1435
|
"Port": 5432
|
||||||
},
|
},
|
||||||
"Hub": {
|
"Hub": {
|
||||||
"Url": "http://hub-server/environment"
|
"Url": "http://hub-server/environment"
|
||||||
|
|||||||
@@ -19,27 +19,31 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
containers:
|
containers:
|
||||||
- name: environment-database
|
- name: environment-database
|
||||||
image: mcr.microsoft.com/mssql/server
|
image: timescale/timescaledb:latest-pg16
|
||||||
terminationMessagePath: "/dev/termination-log"
|
|
||||||
terminationMessagePolicy: File
|
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
env:
|
env:
|
||||||
- name: SA_PASSWORD
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: environment-database-credentials
|
||||||
|
key: username
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
valueFrom:
|
valueFrom:
|
||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: environment-database-credentials
|
name: environment-database-credentials
|
||||||
key: password
|
key: password
|
||||||
- name: ACCEPT_EULA
|
- name: POSTGRES_DB
|
||||||
value: "Y"
|
value: environment
|
||||||
- name: MSSQL_PID
|
|
||||||
value: Express
|
|
||||||
- name: MSSQL_TCP_PORT
|
|
||||||
value: "1435"
|
|
||||||
- name: TZ
|
|
||||||
value: America/New_York
|
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: data
|
- name: data
|
||||||
mountPath: /var/opt/mssql
|
mountPath: /var/lib/postgresql/data
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1000m
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
terminationGracePeriodSeconds: 30
|
terminationGracePeriodSeconds: 30
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
@@ -63,7 +67,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
- name: client
|
- name: client
|
||||||
port: 1435
|
port: 5432
|
||||||
selector:
|
selector:
|
||||||
app: environment-database
|
app: environment-database
|
||||||
type: LoadBalancer
|
type: LoadBalancer
|
||||||
@@ -108,6 +112,13 @@ spec:
|
|||||||
key: password
|
key: password
|
||||||
- name: Environment__Hub__Url
|
- name: Environment__Hub__Url
|
||||||
value: http://hub-service/environment
|
value: http://hub-service/environment
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 1
|
||||||
|
memory: 1Gi
|
||||||
|
requests:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
restartPolicy: Always
|
restartPolicy: Always
|
||||||
terminationGracePeriodSeconds: 30
|
terminationGracePeriodSeconds: 30
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
|
|||||||
Reference in New Issue
Block a user