@ -26,36 +26,49 @@ namespace hass_workstation_service.Data
{
public ICollection < AbstractSensor > ConfiguredSensors { get ; private set ; }
public ICollection < AbstractCommand > ConfiguredCommands { get ; private set ; }
public GeneralSettings GeneralSettings { get ; private set ; }
public Action < IManagedMqttClientOptions > MqqtConfigChangedHandler { get ; set ; }
public Action < string > NamePrefixChangedHandler { get ; set ; }
private readonly DeviceConfigModel _deviceConfigModel ;
private bool BrokerSettingsFileLocked { get ; set ; }
private bool SensorsSettingsFileLocked { get ; set ; }
private bool CommandSettingsFileLocked { get ; set ; }
private bool GeneralSettingsFileLocked { get ; set ; }
private bool _sensorsLoading { get ; set ; }
private readonly string path = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) , "Hass Workstation Service" ) ;
private const string MQTT_SETTINGS_FILENAME = "mqttbroker.json" ;
private const string SENSORS_SETTINGS_FILENAME = "configured-sensors.json" ;
private const string COMMANDS_SETTINGS_FILENAME = "configured-commands.json" ;
private const string GENERAL_SETTINGS_FILENAME = "general-settings.json" ;
public ConfigurationService ( DeviceConfigModel deviceConfigModel )
{
this . _deviceConfigModel = deviceConfigModel ;
if ( ! File . Exists ( Path . Combine ( path , "mqttbroker.json" ) ) )
if ( ! File . Exists ( Path . Combine ( path , MQTT_SETTINGS_FILENAME ) ) )
{
File . Create ( Path . Combine ( path , "mqttbroker.json" ) ) . Close ( ) ;
File . Create ( Path . Combine ( path , MQTT_SETTINGS_FILENAME ) ) . Close ( ) ;
}
if ( ! File . Exists ( Path . Combine ( path , "configured-sensors.json" ) ) )
if ( ! File . Exists ( Path . Combine ( path , SENSORS_SETTINGS_FILENAME ) ) )
{
File . Create ( Path . Combine ( path , "configured-sensors.json" ) ) . Close ( ) ;
File . Create ( Path . Combine ( path , SENSORS_SETTINGS_FILENAME ) ) . Close ( ) ;
}
if ( ! File . Exists ( Path . Combine ( path , "configured-commands.json" ) ) )
if ( ! File . Exists ( Path . Combine ( path , COMMANDS_SETTINGS_FILENAME ) ) )
{
File . Create ( Path . Combine ( path , COMMANDS_SETTINGS_FILENAME ) ) . Close ( ) ;
}
if ( ! File . Exists ( Path . Combine ( path , GENERAL_SETTINGS_FILENAME ) ) )
{
File . Create ( Path . Combine ( path , "configured-commands.json" ) ) . Close ( ) ;
File . Create ( Path . Combine ( path , GENERAL_SETTINGS_FILENAME ) ) . Close ( ) ;
}
ConfiguredSensors = new List < AbstractSensor > ( ) ;
ConfiguredCommands = new List < AbstractCommand > ( ) ;
this . ReadGeneralSettings ( ) ;
}
public async void ReadSensorSettings ( MqttPublisher publisher )
@ -67,7 +80,7 @@ namespace hass_workstation_service.Data
}
this . SensorsSettingsFileLocked = true ;
List < ConfiguredSensor > sensors = new List < ConfiguredSensor > ( ) ;
using ( var stream = new FileStream ( Path . Combine ( path , "configured-sensors.json" ) , FileMode . Open ) )
using ( var stream = new FileStream ( Path . Combine ( path , SENSORS_SETTINGS_FILENAME ) , FileMode . Open ) )
{
Log . Logger . Information ( $"reading configured sensors from: {stream.Name}" ) ;
if ( stream . Length > 0 )
@ -155,7 +168,7 @@ namespace hass_workstation_service.Data
}
this . CommandSettingsFileLocked = true ;
List < ConfiguredCommand > commands = new List < ConfiguredCommand > ( ) ;
using ( var stream = new FileStream ( Path . Combine ( path , "configured-commands.json" ) , FileMode . Open ) )
using ( var stream = new FileStream ( Path . Combine ( path , COMMANDS_SETTINGS_FILENAME ) , FileMode . Open ) )
{
Log . Logger . Information ( $"reading configured commands from: {stream.Name}" ) ;
if ( stream . Length > 0 )
@ -215,6 +228,70 @@ namespace hass_workstation_service.Data
}
}
public async Task < GeneralSettings > ReadGeneralSettings ( )
{
while ( this . GeneralSettingsFileLocked )
{
await Task . Delay ( 500 ) ;
}
this . GeneralSettingsFileLocked = true ;
GeneralSettings settings = new GeneralSettings ( ) ;
using ( var stream = new FileStream ( Path . Combine ( path , GENERAL_SETTINGS_FILENAME ) , FileMode . Open ) )
{
Log . Logger . Information ( $"reading general settings from: {stream.Name}" ) ;
if ( stream . Length > 0 )
{
settings = await JsonSerializer . DeserializeAsync < GeneralSettings > ( stream ) ;
}
stream . Close ( ) ;
this . GeneralSettings = settings ;
this . GeneralSettingsFileLocked = false ;
return settings ;
}
}
/// <summary>
/// Writes provided settings to the config file and reconfigures all sensors and commands if the nameprefix changed
/// </summary>
/// <param name="settings"></param>
public async void WriteGeneralSettingsAsync ( GeneralSettings settings )
{
while ( this . GeneralSettingsFileLocked )
{
await Task . Delay ( 500 ) ;
}
this . GeneralSettingsFileLocked = true ;
using ( FileStream stream = new FileStream ( Path . Combine ( path , GENERAL_SETTINGS_FILENAME ) , FileMode . Open ) )
{
stream . SetLength ( 0 ) ;
Log . Logger . Information ( $"writing general settings to: {stream.Name}" ) ;
await JsonSerializer . SerializeAsync ( stream , settings ) ;
stream . Close ( ) ;
}
this . GeneralSettingsFileLocked = false ;
// if the nameprefix changed, we need to update all sensors and commands to reflect the new name
if ( settings . NamePrefix ! = this . GeneralSettings . NamePrefix )
{
// notify the mqtt publisher of the new prefix
this . NamePrefixChangedHandler . Invoke ( settings . NamePrefix ) ;
foreach ( AbstractSensor sensor in this . ConfiguredSensors )
{
await sensor . UnPublishAutoDiscoveryConfigAsync ( ) ;
sensor . PublishAutoDiscoveryConfigAsync ( ) ;
}
foreach ( AbstractCommand command in this . ConfiguredCommands )
{
await command . UnPublishAutoDiscoveryConfigAsync ( ) ;
command . PublishAutoDiscoveryConfigAsync ( ) ;
}
}
}
public async Task < IManagedMqttClientOptions > GetMqttClientOptionsAsync ( )
{
ConfiguredMqttBroker configuredBroker = await ReadMqttSettingsAsync ( ) ;
@ -257,7 +334,7 @@ namespace hass_workstation_service.Data
}
this . BrokerSettingsFileLocked = true ;
ConfiguredMqttBroker configuredBroker = null ;
using ( FileStream stream = new FileStream ( Path . Combine ( path , "mqttbroker.json" ) , FileMode . Open ) )
using ( FileStream stream = new FileStream ( Path . Combine ( path , MQTT_SETTINGS_FILENAME ) , FileMode . Open ) )
{
Log . Logger . Information ( $"reading configured mqttbroker from: {stream.Name}" ) ;
if ( stream . Length > 0 )
@ -279,7 +356,7 @@ namespace hass_workstation_service.Data
}
this . SensorsSettingsFileLocked = true ;
List < ConfiguredSensor > configuredSensorsToSave = new List < ConfiguredSensor > ( ) ;
using ( FileStream stream = new FileStream ( Path . Combine ( path , "configured-sensors.json" ) , FileMode . Open ) )
using ( FileStream stream = new FileStream ( Path . Combine ( path , SENSORS_SETTINGS_FILENAME ) , FileMode . Open ) )
{
stream . SetLength ( 0 ) ;
Log . Logger . Information ( $"writing configured sensors to: {stream.Name}" ) ;
@ -316,7 +393,7 @@ namespace hass_workstation_service.Data
}
this . CommandSettingsFileLocked = true ;
List < ConfiguredCommand > configuredCommandsToSave = new List < ConfiguredCommand > ( ) ;
using ( FileStream stream = new FileStream ( Path . Combine ( path , "configured-commands.json" ) , FileMode . Open ) )
using ( FileStream stream = new FileStream ( Path . Combine ( path , COMMANDS_SETTINGS_FILENAME ) , FileMode . Open ) )
{
stream . SetLength ( 0 ) ;
Log . Logger . Information ( $"writing configured commands to: {stream.Name}" ) ;
@ -374,6 +451,11 @@ namespace hass_workstation_service.Data
WriteCommandSettingsAsync ( ) ;
}
/// <summary>
///
/// </summary>
/// <param name="id">The Id of the sensor to replace</param>
/// <param name="sensor">The new sensor</param>
public async void UpdateConfiguredSensor ( Guid id , AbstractSensor sensor )
{
await DeleteSensor ( id ) ;
@ -438,7 +520,7 @@ namespace hass_workstation_service.Data
await Task . Delay ( 500 ) ;
}
this . BrokerSettingsFileLocked = true ;
using ( FileStream stream = new FileStream ( Path . Combine ( path , "mqttbroker.json" ) , FileMode . Open ) )
using ( FileStream stream = new FileStream ( Path . Combine ( path , MQTT_SETTINGS_FILENAME ) , FileMode . Open ) )
{
stream . SetLength ( 0 ) ;
Log . Logger . Information ( $"writing configured mqttbroker to: {stream.Name}" ) ;