mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-08-31 19:08:29 +00:00
feat: add optional room combiner operation status lifecycle
This commit is contained in:
parent
23ffc83dea
commit
4e8514c6cc
3 changed files with 176 additions and 7 deletions
|
|
@ -17,7 +17,7 @@ namespace PepperDash.Essentials.Core
|
|||
/// combinations based on partition states and predefined scenarios. It supports both automatic and manual modes
|
||||
/// for managing room combinations. In automatic mode, the device determines the current room combination scenario
|
||||
/// based on partition sensor states. In manual mode, scenarios can be set explicitly by the user.</remarks>
|
||||
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombiner
|
||||
public class EssentialsRoomCombiner : EssentialsDevice, IEssentialsRoomCombinerWithOperationStatus
|
||||
{
|
||||
private EssentialsRoomCombinerPropertiesConfig _propertiesConfig;
|
||||
|
||||
|
|
@ -79,6 +79,13 @@ namespace PepperDash.Essentials.Core
|
|||
|
||||
private Mutex _scenarioChange = new Mutex();
|
||||
|
||||
private readonly object _combinationOperationLock = new object();
|
||||
|
||||
private CombinationOperationStatus _combinationOperation = new CombinationOperationStatus
|
||||
{
|
||||
State = CombinationOperationState.Idle
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EssentialsRoomCombiner"/> class, which manages room combination
|
||||
/// scenarios and partition states.
|
||||
|
|
@ -256,13 +263,19 @@ namespace PepperDash.Essentials.Core
|
|||
|
||||
private async Task ChangeScenario(IRoomCombinationScenario newScenario)
|
||||
{
|
||||
|
||||
if (newScenario == _currentScenario)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (newScenario == _currentScenario)
|
||||
{
|
||||
return;
|
||||
}
|
||||
SetCombinationOperationStatus(
|
||||
CombinationOperationState.InProgress,
|
||||
newScenario != null ? newScenario.Key : null,
|
||||
null,
|
||||
true);
|
||||
|
||||
try
|
||||
{
|
||||
// Deactivate the old scenario first
|
||||
if (_currentScenario != null)
|
||||
{
|
||||
|
|
@ -281,7 +294,22 @@ namespace PepperDash.Essentials.Core
|
|||
|
||||
RoomCombinationScenarioChanged?.Invoke(this, new EventArgs());
|
||||
|
||||
|
||||
SetCombinationOperationStatus(
|
||||
CombinationOperationState.Completed,
|
||||
_currentScenario != null ? _currentScenario.Key : null,
|
||||
null,
|
||||
false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.LogException(ex, "Error changing room combination scenario");
|
||||
|
||||
SetCombinationOperationStatus(
|
||||
CombinationOperationState.Failed,
|
||||
newScenario != null ? newScenario.Key : null,
|
||||
"Combination operation failed",
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
#region IEssentialsRoomCombiner Members
|
||||
|
|
@ -293,6 +321,11 @@ namespace PepperDash.Essentials.Core
|
|||
/// changes. Subscribers can use this event to update their logic or UI based on the new scenario.</remarks>
|
||||
public event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the room combination operation status changes.
|
||||
/// </summary>
|
||||
public event EventHandler<EventArgs> CombinationOperationStatusChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current room combination scenario.
|
||||
/// </summary>
|
||||
|
|
@ -304,6 +337,20 @@ namespace PepperDash.Essentials.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current room combination operation status.
|
||||
/// </summary>
|
||||
public CombinationOperationStatus CombinationOperation
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_combinationOperationLock)
|
||||
{
|
||||
return CloneCombinationOperationStatus(_combinationOperation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IsInAutoModeFeedback
|
||||
/// </summary>
|
||||
|
|
@ -455,6 +502,53 @@ namespace PepperDash.Essentials.Core
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void SetCombinationOperationStatus(
|
||||
CombinationOperationState state,
|
||||
string scenarioKey,
|
||||
string message,
|
||||
bool resetStartedUtc)
|
||||
{
|
||||
lock (_combinationOperationLock)
|
||||
{
|
||||
if (resetStartedUtc)
|
||||
{
|
||||
_combinationOperation = new CombinationOperationStatus
|
||||
{
|
||||
OperationId = Guid.NewGuid().ToString(),
|
||||
ScenarioKey = scenarioKey,
|
||||
StartedUtc = DateTime.UtcNow.ToString("o"),
|
||||
State = state,
|
||||
Message = message
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
_combinationOperation.ScenarioKey = scenarioKey ?? _combinationOperation.ScenarioKey;
|
||||
_combinationOperation.State = state;
|
||||
_combinationOperation.Message = message;
|
||||
}
|
||||
}
|
||||
|
||||
CombinationOperationStatusChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private static CombinationOperationStatus CloneCombinationOperationStatus(CombinationOperationStatus status)
|
||||
{
|
||||
if (status == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new CombinationOperationStatus
|
||||
{
|
||||
OperationId = status.OperationId,
|
||||
ScenarioKey = status.ScenarioKey,
|
||||
StartedUtc = status.StartedUtc,
|
||||
State = status.State,
|
||||
Message = status.Message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -16,12 +16,14 @@ namespace PepperDash.Essentials.Core
|
|||
/// </summary>
|
||||
event EventHandler<EventArgs> RoomCombinationScenarioChanged;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The current room combination scenario
|
||||
/// </summary>
|
||||
[JsonProperty("currentScenario")]
|
||||
IRoomCombinationScenario CurrentScenario { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// When true, indicates the current mode is auto mode
|
||||
/// </summary>
|
||||
|
|
@ -85,6 +87,56 @@ namespace PepperDash.Essentials.Core
|
|||
void SetRoomCombinationScenario(string scenarioKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Optional extension for room combiners that provide operation lifecycle status.
|
||||
/// </summary>
|
||||
public interface IEssentialsRoomCombinerWithOperationStatus : IEssentialsRoomCombiner
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the room combination operation status has changed.
|
||||
/// </summary>
|
||||
event EventHandler<EventArgs> CombinationOperationStatusChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current room combination operation status.
|
||||
/// </summary>
|
||||
[JsonProperty("combinationOperation")]
|
||||
CombinationOperationStatus CombinationOperation { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines lifecycle states for a room combination operation.
|
||||
/// </summary>
|
||||
public enum CombinationOperationState
|
||||
{
|
||||
Idle,
|
||||
InProgress,
|
||||
Completed,
|
||||
Failed,
|
||||
TimedOut
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents room combination operation status details.
|
||||
/// </summary>
|
||||
public class CombinationOperationStatus
|
||||
{
|
||||
[JsonProperty("operationId", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string OperationId { get; set; }
|
||||
|
||||
[JsonProperty("scenarioKey", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string ScenarioKey { get; set; }
|
||||
|
||||
[JsonProperty("startedUtc", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string StartedUtc { get; set; }
|
||||
|
||||
[JsonProperty("state")]
|
||||
public CombinationOperationState State { get; set; }
|
||||
|
||||
[JsonProperty("message", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a scenario for combining rooms, including activation, deactivation, and associated state.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||
{
|
||||
private readonly IEssentialsRoomCombiner _roomCombiner;
|
||||
|
||||
private readonly IEssentialsRoomCombinerWithOperationStatus _roomCombinerWithOperationStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IEssentialsRoomCombinerMessenger"/> class, which facilitates
|
||||
/// messaging for an <see cref="IEssentialsRoomCombiner"/> instance.
|
||||
|
|
@ -35,6 +37,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||
: base(key, messagePath, roomCombiner as IKeyName)
|
||||
{
|
||||
_roomCombiner = roomCombiner;
|
||||
_roomCombinerWithOperationStatus = roomCombiner as IEssentialsRoomCombinerWithOperationStatus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -98,6 +101,19 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||
SendFullStatus();
|
||||
};
|
||||
|
||||
if (_roomCombinerWithOperationStatus != null)
|
||||
{
|
||||
_roomCombinerWithOperationStatus.CombinationOperationStatusChanged += (sender, args) =>
|
||||
{
|
||||
var message = new
|
||||
{
|
||||
combinationOperation = _roomCombinerWithOperationStatus.CombinationOperation
|
||||
};
|
||||
|
||||
PostStatusMessage(JToken.FromObject(message));
|
||||
};
|
||||
}
|
||||
|
||||
_roomCombiner.IsInAutoModeFeedback.OutputChange += (sender, args) =>
|
||||
{
|
||||
var message = new
|
||||
|
|
@ -138,6 +154,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||
DisableAutoMode = _roomCombiner.DisableAutoMode,
|
||||
IsInAutoMode = _roomCombiner.IsInAutoMode,
|
||||
CurrentScenario = _roomCombiner.CurrentScenario,
|
||||
CombinationOperation = _roomCombinerWithOperationStatus != null ? _roomCombinerWithOperationStatus.CombinationOperation : null,
|
||||
Rooms = rooms,
|
||||
RoomCombinationScenarios = _roomCombiner.RoomCombinationScenarios,
|
||||
Partitions = _roomCombiner.Partitions
|
||||
|
|
@ -194,6 +211,12 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
|||
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public IRoomCombinationScenario CurrentScenario { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the room combination operation status.
|
||||
/// </summary>
|
||||
[JsonProperty("combinationOperation", NullValueHandling = NullValueHandling.Ignore)]
|
||||
public CombinationOperationStatus CombinationOperation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of rooms associated with the entity.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue