forked from amkovkov/GranuSightSoftware2
feat: минорые изменения после тестирования
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
|
||||||
<PackageReference Include="System.Device.Gpio" Version="4.0.1" />
|
<PackageReference Include="System.Device.Gpio" Version="4.0.1" />
|
||||||
|
<PackageReference Include="Iot.Device.Bindings" Version="4.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ public class LightsService
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Ping(CancellationToken cancellationToken = default) => SendRequest(_client.Ping, new Empty(), cancellationToken);
|
public void Ping(CancellationToken cancellationToken = default) => SendRequest(_client.Ping, new Empty(), cancellationToken);
|
||||||
|
public void Disconnect(CancellationToken cancellationToken = default) => SendRequest(_client.Disconnect, new Empty(), cancellationToken);
|
||||||
public void Off(CancellationToken cancellationToken = default) => SendRequest(_client.SetOff, new Empty(), cancellationToken);
|
public void Off(CancellationToken cancellationToken = default) => SendRequest(_client.SetOff, new Empty(), cancellationToken);
|
||||||
public void StaticColor(double brightness, Color color, CancellationToken cancellationToken = default) => SendRequest(_client.SetStaticColor, new StaticColorRequest
|
public void StaticColor(double brightness, Color color, CancellationToken cancellationToken = default) => SendRequest(_client.SetStaticColor, new StaticColorRequest
|
||||||
{
|
{
|
||||||
@@ -274,6 +275,7 @@ public class LightsService
|
|||||||
}, cancellationToken);
|
}, cancellationToken);
|
||||||
|
|
||||||
public async Task PingAsync(CancellationToken cancellationToken = default) => await SendRequestAsync(_client.PingAsync, new Empty(), cancellationToken);
|
public async Task PingAsync(CancellationToken cancellationToken = default) => await SendRequestAsync(_client.PingAsync, new Empty(), cancellationToken);
|
||||||
|
public async Task DisconnectAsync(CancellationToken cancellationToken = default) => await SendRequestAsync(_client.DisconnectAsync, new Empty(), cancellationToken);
|
||||||
public async Task OffAsync(CancellationToken cancellationToken = default) => await SendRequestAsync(_client.SetOffAsync, new Empty(), cancellationToken);
|
public async Task OffAsync(CancellationToken cancellationToken = default) => await SendRequestAsync(_client.SetOffAsync, new Empty(), cancellationToken);
|
||||||
public async Task StaticColorAsync(double brightness, Color color, CancellationToken cancellationToken = default) => await SendRequestAsync(_client.SetStaticColorAsync, new StaticColorRequest
|
public async Task StaticColorAsync(double brightness, Color color, CancellationToken cancellationToken = default) => await SendRequestAsync(_client.SetStaticColorAsync, new StaticColorRequest
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ public class TemperatureHumidityService : IDisposable
|
|||||||
{
|
{
|
||||||
public static TemperatureHumidityServiceConfiguration Default => new TemperatureHumidityServiceConfiguration
|
public static TemperatureHumidityServiceConfiguration Default => new TemperatureHumidityServiceConfiguration
|
||||||
{
|
{
|
||||||
Bus = 0,
|
Bus = 6,
|
||||||
Address = 0x44
|
Address = 0x45
|
||||||
};
|
};
|
||||||
|
|
||||||
public int Bus { get; set; }
|
public int Bus { get; set; }
|
||||||
@@ -54,7 +54,7 @@ public class TemperatureHumidityService : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(double temperature, double relativeHumidity)> MeasureAsync(int measurementsCount = 1, CancellationToken cancellationToken = default)
|
public (double temperature, double relativeHumidity) Measure(int measurementsCount = 1, bool checkCrc = true, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// В соответствии с даташитом на SHT45-AD1B-R2 псевдокод измерения с высокой точностью следующий:
|
// В соответствии с даташитом на SHT45-AD1B-R2 псевдокод измерения с высокой точностью следующий:
|
||||||
// i2c_write(i2c_addr=0x44, tx_bytes=[0xFD])
|
// i2c_write(i2c_addr=0x44, tx_bytes=[0xFD])
|
||||||
@@ -90,19 +90,19 @@ public class TemperatureHumidityService : IDisposable
|
|||||||
// Отправляем команду
|
// Отправляем команду
|
||||||
_sensor.Write(command);
|
_sensor.Write(command);
|
||||||
// 10 мс ожидания
|
// 10 мс ожидания
|
||||||
await Task.Delay(10, cancellationToken);
|
Task.Delay(10, cancellationToken);
|
||||||
// Читаем данные
|
// Читаем данные
|
||||||
_sensor.Read(data);
|
_sensor.Read(data);
|
||||||
|
|
||||||
// Распаковываем данные [2 * 8-bit T-data; 8-bit CRC; 2 * 8-bit RH-data; 8-bit CRC]
|
// Распаковываем данные [2 * 8-bit T-data; 8-bit CRC; 2 * 8-bit RH-data; 8-bit CRC]
|
||||||
ushort temperatureTicks = BitConverter.ToUInt16(data.ToArray(), 0);
|
|
||||||
byte temperatureChecksum = data[2];
|
byte temperatureChecksum = data[2];
|
||||||
int relativeHumidityTicks = BitConverter.ToUInt16(data.ToArray(), 3);
|
|
||||||
byte relativeHumidityChecksum = data[5];
|
byte relativeHumidityChecksum = data[5];
|
||||||
|
ushort temperatureTicks = BitConverter.ToUInt16(data.Slice(0, 2));
|
||||||
|
int relativeHumidityTicks = BitConverter.ToUInt16(data.Slice(3, 2));
|
||||||
|
|
||||||
// Проверка по CRC
|
// Проверка по CRC
|
||||||
if (!CheckCrc(data.Slice(0, 2), temperatureChecksum) ||
|
if (checkCrc && (!CheckCrc(data.Slice(0, 2), temperatureChecksum) ||
|
||||||
!CheckCrc(data.Slice(3, 2), relativeHumidityChecksum))
|
!CheckCrc(data.Slice(3, 2), relativeHumidityChecksum)))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Temperature and humidity sensor CRC error");
|
_logger.LogWarning("Temperature and humidity sensor CRC error");
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ LED_COUNT=9
|
|||||||
LED_PIN=23
|
LED_PIN=23
|
||||||
|
|
||||||
GAMMA=2.2
|
GAMMA=2.2
|
||||||
TIMEOUT=5
|
TIMEOUT_SECONDS=300
|
||||||
|
|
||||||
IDLE_BRIGHTNESS=0.30
|
IDLE_BRIGHTNESS=0.30
|
||||||
IDLE_R=0
|
IDLE_R=0
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
!.env
|
!.env
|
||||||
|
venv
|
||||||
@@ -34,7 +34,7 @@ LED_PIN_NUM = get_env_int("LED_PIN")
|
|||||||
LED_PIN = getattr(board, f"D{LED_PIN_NUM}")
|
LED_PIN = getattr(board, f"D{LED_PIN_NUM}")
|
||||||
|
|
||||||
GAMMA = get_env_float("GAMMA")
|
GAMMA = get_env_float("GAMMA")
|
||||||
TIMEOUT = get_env_float("TIMEOUT")
|
TIMEOUT_SECONDS = get_env_float("TIMEOUT_SECONDS")
|
||||||
|
|
||||||
IDLE_SPEED = get_env_float("IDLE_SPEED")
|
IDLE_SPEED = get_env_float("IDLE_SPEED")
|
||||||
IDLE_BRIGHTNESS = get_env_float("IDLE_BRIGHTNESS")
|
IDLE_BRIGHTNESS = get_env_float("IDLE_BRIGHTNESS")
|
||||||
@@ -579,7 +579,7 @@ class LightsDaemon(lights_pb2_grpc.LightsServicer):
|
|||||||
def loop(self):
|
def loop(self):
|
||||||
while self._running:
|
while self._running:
|
||||||
with self._lock:
|
with self._lock:
|
||||||
if self._control_mode and time.time() - self._last_ping > TIMEOUT:
|
if self._control_mode and time.time() - self._last_ping > TIMEOUT_SECONDS:
|
||||||
self._control_mode = False
|
self._control_mode = False
|
||||||
self._pixels.brightness = IDLE_BRIGHTNESS
|
self._pixels.brightness = IDLE_BRIGHTNESS
|
||||||
self._animation = IdleAnimation()
|
self._animation = IdleAnimation()
|
||||||
@@ -597,6 +597,13 @@ class LightsDaemon(lights_pb2_grpc.LightsServicer):
|
|||||||
self._control_mode = True
|
self._control_mode = True
|
||||||
self._last_ping = time.time()
|
self._last_ping = time.time()
|
||||||
|
|
||||||
|
def Disconnect(self, request, context):
|
||||||
|
with self._lock:
|
||||||
|
self._control_mode = False
|
||||||
|
self._pixels.brightness = IDLE_BRIGHTNESS
|
||||||
|
self._animation = IdleAnimation()
|
||||||
|
return lights_pb2.Empty()
|
||||||
|
|
||||||
def Ping(self, request, context):
|
def Ping(self, request, context):
|
||||||
self._update_last_ping()
|
self._update_last_ping()
|
||||||
return lights_pb2.Empty()
|
return lights_pb2.Empty()
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -39,6 +39,11 @@ class LightsStub(object):
|
|||||||
request_serializer=lights__pb2.Empty.SerializeToString,
|
request_serializer=lights__pb2.Empty.SerializeToString,
|
||||||
response_deserializer=lights__pb2.Empty.FromString,
|
response_deserializer=lights__pb2.Empty.FromString,
|
||||||
_registered_method=True)
|
_registered_method=True)
|
||||||
|
self.Disconnect = channel.unary_unary(
|
||||||
|
'/GSS2.LightsControl.Lights/Disconnect',
|
||||||
|
request_serializer=lights__pb2.Empty.SerializeToString,
|
||||||
|
response_deserializer=lights__pb2.Empty.FromString,
|
||||||
|
_registered_method=True)
|
||||||
self.SetOff = channel.unary_unary(
|
self.SetOff = channel.unary_unary(
|
||||||
'/GSS2.LightsControl.Lights/SetOff',
|
'/GSS2.LightsControl.Lights/SetOff',
|
||||||
request_serializer=lights__pb2.Empty.SerializeToString,
|
request_serializer=lights__pb2.Empty.SerializeToString,
|
||||||
@@ -145,6 +150,12 @@ class LightsServicer(object):
|
|||||||
context.set_details('Method not implemented!')
|
context.set_details('Method not implemented!')
|
||||||
raise NotImplementedError('Method not implemented!')
|
raise NotImplementedError('Method not implemented!')
|
||||||
|
|
||||||
|
def Disconnect(self, request, context):
|
||||||
|
"""Missing associated documentation comment in .proto file."""
|
||||||
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||||
|
context.set_details('Method not implemented!')
|
||||||
|
raise NotImplementedError('Method not implemented!')
|
||||||
|
|
||||||
def SetOff(self, request, context):
|
def SetOff(self, request, context):
|
||||||
"""Missing associated documentation comment in .proto file."""
|
"""Missing associated documentation comment in .proto file."""
|
||||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||||
@@ -267,6 +278,11 @@ def add_LightsServicer_to_server(servicer, server):
|
|||||||
request_deserializer=lights__pb2.Empty.FromString,
|
request_deserializer=lights__pb2.Empty.FromString,
|
||||||
response_serializer=lights__pb2.Empty.SerializeToString,
|
response_serializer=lights__pb2.Empty.SerializeToString,
|
||||||
),
|
),
|
||||||
|
'Disconnect': grpc.unary_unary_rpc_method_handler(
|
||||||
|
servicer.Disconnect,
|
||||||
|
request_deserializer=lights__pb2.Empty.FromString,
|
||||||
|
response_serializer=lights__pb2.Empty.SerializeToString,
|
||||||
|
),
|
||||||
'SetOff': grpc.unary_unary_rpc_method_handler(
|
'SetOff': grpc.unary_unary_rpc_method_handler(
|
||||||
servicer.SetOff,
|
servicer.SetOff,
|
||||||
request_deserializer=lights__pb2.Empty.FromString,
|
request_deserializer=lights__pb2.Empty.FromString,
|
||||||
@@ -400,6 +416,33 @@ class Lights(object):
|
|||||||
metadata,
|
metadata,
|
||||||
_registered_method=True)
|
_registered_method=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def Disconnect(request,
|
||||||
|
target,
|
||||||
|
options=(),
|
||||||
|
channel_credentials=None,
|
||||||
|
call_credentials=None,
|
||||||
|
insecure=False,
|
||||||
|
compression=None,
|
||||||
|
wait_for_ready=None,
|
||||||
|
timeout=None,
|
||||||
|
metadata=None):
|
||||||
|
return grpc.experimental.unary_unary(
|
||||||
|
request,
|
||||||
|
target,
|
||||||
|
'/GSS2.LightsControl.Lights/Disconnect',
|
||||||
|
lights__pb2.Empty.SerializeToString,
|
||||||
|
lights__pb2.Empty.FromString,
|
||||||
|
options,
|
||||||
|
channel_credentials,
|
||||||
|
insecure,
|
||||||
|
call_credentials,
|
||||||
|
compression,
|
||||||
|
wait_for_ready,
|
||||||
|
timeout,
|
||||||
|
metadata,
|
||||||
|
_registered_method=True)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def SetOff(request,
|
def SetOff(request,
|
||||||
target,
|
target,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package GSS2.LightsControl;
|
|||||||
|
|
||||||
service Lights {
|
service Lights {
|
||||||
rpc Ping (Empty) returns (Empty);
|
rpc Ping (Empty) returns (Empty);
|
||||||
|
rpc Disconnect (Empty) returns (Empty);
|
||||||
|
|
||||||
rpc SetOff (Empty) returns (Empty);
|
rpc SetOff (Empty) returns (Empty);
|
||||||
|
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ public class Program
|
|||||||
var configuration = serviceProvider.GetService<IConfiguration>();
|
var configuration = serviceProvider.GetService<IConfiguration>();
|
||||||
if (configuration is null)
|
if (configuration is null)
|
||||||
throw new Exception("Cannot get configuration");
|
throw new Exception("Cannot get configuration");
|
||||||
var serviceConfiguration = configuration.GetValue<LightsService.LightsServiceConfiguration>("Lights");
|
var serviceConfiguration = configuration.GetSection("Hardware:Lights").Get<LightsService.LightsServiceConfiguration>();
|
||||||
if (serviceConfiguration is null)
|
if (serviceConfiguration is null)
|
||||||
throw new InvalidConfigurationException("Cannot get configuration (Lights)");
|
throw new InvalidConfigurationException("Cannot get configuration (Hardware:Lights)");
|
||||||
var logger = serviceProvider.GetService<ILogger<LightsService>>();
|
var logger = serviceProvider.GetService<ILogger<LightsService>>();
|
||||||
if (logger is null)
|
if (logger is null)
|
||||||
throw new Exception("Cannot get logger");
|
throw new Exception("Cannot get logger");
|
||||||
@@ -41,9 +41,9 @@ public class Program
|
|||||||
var configuration = serviceProvider.GetService<IConfiguration>();
|
var configuration = serviceProvider.GetService<IConfiguration>();
|
||||||
if (configuration is null)
|
if (configuration is null)
|
||||||
throw new Exception("Cannot get configuration");
|
throw new Exception("Cannot get configuration");
|
||||||
var serviceConfiguration = configuration.GetValue<TemperatureHumidityService.TemperatureHumidityServiceConfiguration>("TemperatureHumidity");
|
var serviceConfiguration = configuration.GetSection("Hardware:TemperatureHumidity").Get<TemperatureHumidityService.TemperatureHumidityServiceConfiguration>();
|
||||||
if (serviceConfiguration is null)
|
if (serviceConfiguration is null)
|
||||||
throw new InvalidConfigurationException("Cannot get configuration (TemperatureHumidity)");
|
throw new InvalidConfigurationException("Cannot get configuration (Hardware:TemperatureHumidity)");
|
||||||
var logger = serviceProvider.GetService<ILogger<TemperatureHumidityService>>();
|
var logger = serviceProvider.GetService<ILogger<TemperatureHumidityService>>();
|
||||||
if (logger is null)
|
if (logger is null)
|
||||||
throw new Exception("Cannot get logger");
|
throw new Exception("Cannot get logger");
|
||||||
|
|||||||
+2
-6
@@ -7,23 +7,19 @@ namespace GSS2.Test;
|
|||||||
public class Worker(
|
public class Worker(
|
||||||
ILogger<Worker> logger,
|
ILogger<Worker> logger,
|
||||||
AmineContentCalibrationContext calibrationContext,
|
AmineContentCalibrationContext calibrationContext,
|
||||||
LightsService lightsService,
|
LightsService lightsService
|
||||||
TemperatureHumidityService temperatureHumidity
|
|
||||||
) : BackgroundService
|
) : BackgroundService
|
||||||
{
|
{
|
||||||
private readonly ILogger<Worker> _logger = logger;
|
private readonly ILogger<Worker> _logger = logger;
|
||||||
private readonly AmineContentCalibrationContext _calibrationContext = calibrationContext;
|
private readonly AmineContentCalibrationContext _calibrationContext = calibrationContext;
|
||||||
private readonly LightsService _lightsService = lightsService;
|
private readonly LightsService _lightsService = lightsService;
|
||||||
private readonly TemperatureHumidityService _temperatureHumidity = temperatureHumidity;
|
|
||||||
|
|
||||||
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
protected override async Task ExecuteAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_ = _lightsService.Run(cancellationToken);
|
_ = _lightsService.Run(cancellationToken);
|
||||||
await _lightsService.SnowfallAsync(0.3, 1, Color.Aqua, cancellationToken);
|
_ = _lightsService.SnowfallAsync(0.3, 1, Color.Aqua, cancellationToken);
|
||||||
while (!cancellationToken.IsCancellationRequested)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
var (temperature, humidity) = await _temperatureHumidity.MeasureAsync();
|
|
||||||
_logger.LogInformation("Temperature: {}, RelativeHumidity: {}", temperature, humidity);
|
|
||||||
await Task.Delay(5000);
|
await Task.Delay(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@
|
|||||||
"MaxUv365PwmDuty": 1.0
|
"MaxUv365PwmDuty": 1.0
|
||||||
},
|
},
|
||||||
"TemperatureHumidity": {
|
"TemperatureHumidity": {
|
||||||
"Bus": 0,
|
"Bus": 6,
|
||||||
"Address": 68
|
"Address": 69
|
||||||
},
|
},
|
||||||
"Lights": {
|
"Lights": {
|
||||||
"ServerAddress": "localhost:50051"
|
"ServerAddress": "http://127.0.0.1:50051"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user