using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using PepperDash.Core;
using PepperDash.Core.Logging;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials.AppServer.Messengers
{
///
/// Provides messaging functionality for managing room combination scenarios and partition states in an instance. Enables external systems to interact with the room combiner via
/// predefined actions and status updates.
///
/// This class facilitates communication with an by
/// exposing actions for toggling modes, managing partitions, and setting room combination scenarios. It also
/// listens for feedback changes and broadcasts status updates to connected systems. Typical usage involves
/// registering actions for external commands and handling feedback events to synchronize state changes.
public class IEssentialsRoomCombinerMessenger : MessengerBase
{
private readonly IEssentialsRoomCombiner _roomCombiner;
///
/// Initializes a new instance of the class, which facilitates
/// messaging for an instance.
///
/// This class is designed to enable communication and interaction with an through the specified messaging path. Ensure that the parameter is not null when creating an instance.
/// The unique key identifying this messenger instance.
/// The path used for messaging operations.
/// The instance associated with this messenger.
public IEssentialsRoomCombinerMessenger(string key, string messagePath, IEssentialsRoomCombiner roomCombiner)
: base(key, messagePath, roomCombiner as IKeyName)
{
_roomCombiner = roomCombiner;
}
///
/// Registers actions and event handlers for managing room combination scenarios and partition states.
///
/// This method sets up various actions that can be triggered via specific endpoints,
/// such as toggling modes, setting room combination scenarios, and managing partition states. It also
/// subscribes to feedback events to update the status when changes occur in room combination scenarios or
/// partition states.
protected override void RegisterActions()
{
AddAction("/fullStatus", (id, content) => SendFullStatus(id));
AddAction("/combinerStatus", (id, content) => SendFullStatus(id));
AddAction("/setAutoMode", (id, content) =>
{
_roomCombiner.SetAutoMode();
});
AddAction("/setManualMode", (id, content) =>
{
_roomCombiner.SetManualMode();
});
AddAction("/toggleMode", (id, content) =>
{
_roomCombiner.ToggleMode();
});
AddAction("/togglePartitionState", (id, content) =>
{
try
{
var partitionKey = content.ToObject();
_roomCombiner.TogglePartitionState(partitionKey);
}
catch (Exception e)
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Error toggling partition state: {e}", this);
}
});
AddAction("/setRoomCombinationScenario", (id, content) =>
{
try
{
var scenarioKey = content.ToObject();
_roomCombiner.SetRoomCombinationScenario(scenarioKey);
}
catch (Exception e)
{
Debug.LogMessage(Serilog.Events.LogEventLevel.Verbose, $"Error toggling partition state: {e}", this);
}
});
_roomCombiner.RoomCombinationScenarioChanged += (sender, args) =>
{
SendFullStatus();
};
_roomCombiner.IsInAutoModeFeedback.OutputChange += (sender, args) =>
{
var message = new
{
isInAutoMode = _roomCombiner.IsInAutoModeFeedback.BoolValue
};
PostStatusMessage(JToken.FromObject(message));
};
foreach (var partition in _roomCombiner.Partitions)
{
partition.PartitionPresentFeedback.OutputChange += (sender, args) =>
{
var message = new
{
partitions = _roomCombiner.Partitions
};
PostStatusMessage(JToken.FromObject(message));
};
}
}
private void SendFullStatus(string id = null)
{
try
{
var rooms = new List();
foreach (var room in _roomCombiner.Rooms)
{
rooms.Add(new RoomCombinerRoom { Key = room.Key, Name = room.Name });
}
var message = new IEssentialsRoomCombinerStateMessage
{
DisableAutoMode = _roomCombiner.DisableAutoMode,
IsInAutoMode = _roomCombiner.IsInAutoMode,
CurrentScenario = _roomCombiner.CurrentScenario,
Rooms = rooms,
RoomCombinationScenarios = _roomCombiner.RoomCombinationScenarios,
Partitions = _roomCombiner.Partitions
};
PostStatusMessage(message, id);
}
catch (Exception e)
{
this.LogException(e, "Error sending full status");
}
}
private class RoomCombinerRoom : IKeyName
{
[JsonProperty("key")]
///
/// Gets or sets the Key
///
public string Key { get; set; }
[JsonProperty("name")]
///
/// Gets or sets the Name
///
public string Name { get; set; }
}
}
///
/// Represents the state message for a room combiner system, providing information about the current configuration,
/// operational mode, and associated rooms, partitions, and scenarios.
///
/// This class is used to encapsulate the state of a room combiner system, including its current
/// mode of operation, active room combination scenario, and the list of rooms and partitions involved. It is
/// typically serialized and transmitted to communicate the state of the system.
public class IEssentialsRoomCombinerStateMessage : DeviceStateMessageBase
{
///
/// Gets or sets a value indicating whether automatic mode is disabled.
///
[JsonProperty("disableAutoMode", NullValueHandling = NullValueHandling.Ignore)]
public bool DisableAutoMode { get; set; }
///
/// Gets or sets a value indicating whether the system is operating in automatic mode.
///
[JsonProperty("isInAutoMode", NullValueHandling = NullValueHandling.Ignore)]
public bool IsInAutoMode { get; set; }
///
/// Gets or sets the current room combination scenario.
///
[JsonProperty("currentScenario", NullValueHandling = NullValueHandling.Ignore)]
public IRoomCombinationScenario CurrentScenario { get; set; }
///
/// Gets or sets the collection of rooms associated with the entity.
///
[JsonProperty("rooms", NullValueHandling = NullValueHandling.Ignore)]
public List Rooms { get; set; }
///
/// Gets or sets the collection of room combination scenarios.
///
[JsonProperty("roomCombinationScenarios", NullValueHandling = NullValueHandling.Ignore)]
public List RoomCombinationScenarios { get; set; }
///
/// Gets or sets the collection of partition controllers.
///
[JsonProperty("partitions", NullValueHandling = NullValueHandling.Ignore)]
public List Partitions { get; set; }
}
}