mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-07-02 10:38:16 +00:00
feat: enhance IHasDirectoryMessenger with new actions and state messaging for directory management
feat: update MobileControlConfig to enable messenger subscriptions by default fix: improve HandleBatchDeviceFullStatus to support granular device status requests and enhance error handling
This commit is contained in:
parent
77c78af74b
commit
8748157362
4 changed files with 93 additions and 28 deletions
|
|
@ -50,7 +50,7 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendCurrentSourceStatus(string id = null)
|
private void SendCurrentSourceStatus(string id)
|
||||||
{
|
{
|
||||||
var message = new CurrentSourcesStateMessage
|
var message = new CurrentSourcesStateMessage
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,16 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
|
|
||||||
AddAction("/getDirectory", (id, content) => GetDirectoryRoot());
|
AddAction("/getDirectory", (id, content) => GetDirectoryRoot());
|
||||||
|
|
||||||
|
AddAction("/setCurrentDirectoryToRoot", (id, content) => _directory.SetCurrentDirectoryToRoot());
|
||||||
|
|
||||||
AddAction("/directoryById", (id, content) =>
|
AddAction("/directoryById", (id, content) =>
|
||||||
{
|
{
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||||
GetDirectory(msg.Value);
|
GetDirectory(msg.Value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AddAction("/getDirectoryPareentFolderContents", (id, content) => _directory.GetDirectoryParentFolderContents());
|
||||||
|
|
||||||
AddAction("/directorySearch", (id, content) =>
|
AddAction("/directorySearch", (id, content) =>
|
||||||
{
|
{
|
||||||
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
var msg = content.ToObject<MobileControlSimpleContent<string>>();
|
||||||
|
|
@ -52,6 +56,14 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
|
|
||||||
_directory.DirectoryResultReturned += DirectoryResultReturned;
|
_directory.DirectoryResultReturned += DirectoryResultReturned;
|
||||||
_directory.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
|
_directory.PhonebookSyncState.InitialSyncCompleted += PhonebookSyncState_InitialSyncCompleted;
|
||||||
|
|
||||||
|
_directory.CurrentDirectoryResultIsNotDirectoryRoot.OutputChange += (s, e) =>
|
||||||
|
{
|
||||||
|
PostStatusMessage(new IHasDirectoryStateMessage
|
||||||
|
{
|
||||||
|
DirectorySelectedFolderIsNotRoot = _directory.CurrentDirectoryResultIsNotDirectoryRoot?.BoolValue
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
private void DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
||||||
|
|
@ -125,16 +137,22 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
{
|
{
|
||||||
PostStatusMessage(new IHasDirectoryStateMessage
|
PostStatusMessage(new IHasDirectoryStateMessage
|
||||||
{
|
{
|
||||||
|
DirectoryRoot = _directory.DirectoryRoot,
|
||||||
CurrentDirectory = _directory.CurrentDirectoryResult,
|
CurrentDirectory = _directory.CurrentDirectoryResult,
|
||||||
InitialPhonebookSyncComplete = _directory.PhonebookSyncState.InitialSyncComplete,
|
InitialPhonebookSyncComplete = _directory.PhonebookSyncState.InitialSyncComplete,
|
||||||
HasDirectory = true,
|
HasDirectory = true,
|
||||||
HasDirectorySearch = true,
|
HasDirectorySearch = true,
|
||||||
|
DirectorySelectedFolderName = _directory.CurrentDirectoryResult?.CurrentDirectoryResults?.Count > 0 ? _directory.CurrentDirectoryResult.CurrentDirectoryResults[0].Name : null,
|
||||||
|
DirectorySelectedFolderIsNotRoot = _directory.CurrentDirectorResultIsNotDirectoryRoot?.BoolValue
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class IHasDirectoryStateMessage : DeviceStateMessageBase
|
public class IHasDirectoryStateMessage : DeviceStateMessageBase
|
||||||
{
|
{
|
||||||
|
[JsonProperty("directoryRoot", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public CodecDirectory DirectoryRoot { get; set; }
|
||||||
|
|
||||||
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("currentDirectory", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public CodecDirectory CurrentDirectory { get; set; }
|
public CodecDirectory CurrentDirectory { get; set; }
|
||||||
|
|
||||||
|
|
@ -153,5 +171,8 @@ namespace PepperDash.Essentials.AppServer.Messengers
|
||||||
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
|
[JsonProperty("directorySelectedFolderName", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public string DirectorySelectedFolderName { get; set; }
|
public string DirectorySelectedFolderName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("directorySelectedFolderIsNotRoot", NullValueHandling = NullValueHandling.Ignore)]
|
||||||
|
public bool? DirectorySelectedFolderIsNotRoot { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,11 @@ namespace PepperDash.Essentials
|
||||||
public bool EnableApiServer { get; set; } = true;
|
public bool EnableApiServer { get; set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable subscriptions for Messengers
|
/// Enable subscriptions for Messengers.
|
||||||
|
/// Defaults to true for v3.x+
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty("enableMessengerSubscriptions")]
|
[JsonProperty("enableMessengerSubscriptions")]
|
||||||
public bool EnableMessengerSubscriptions { get; set; }
|
public bool EnableMessengerSubscriptions { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1501,8 +1501,14 @@ namespace PepperDash.Essentials
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles a batch request for full status of multiple devices.
|
/// Handles a batch request for device status. Supports two content formats:
|
||||||
/// Triggers all registered messengers for each device key in parallel,
|
/// <para>
|
||||||
|
/// Granular format: <c>{ "devices": { "deviceKey": ["/fullStatus", "/layoutStatus"], ... } }</c>
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// Legacy format: <c>{ "deviceKeys": ["deviceKey1", "deviceKey2"] }</c> (equivalent to /fullStatus for each)
|
||||||
|
/// </para>
|
||||||
|
/// Triggers the specified action paths for each device in parallel,
|
||||||
/// then sends an /system/initialSyncComplete message after all have been processed.
|
/// then sends an /system/initialSyncComplete message after all have been processed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleBatchDeviceFullStatus(string clientId, JToken content)
|
private void HandleBatchDeviceFullStatus(string clientId, JToken content)
|
||||||
|
|
@ -1513,11 +1519,23 @@ namespace PepperDash.Essentials
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build a dictionary of deviceKey -> list of action paths
|
||||||
|
Dictionary<string, List<string>> deviceActionPaths;
|
||||||
|
|
||||||
|
var devicesToken = content.SelectToken("devices");
|
||||||
|
if (devicesToken != null)
|
||||||
|
{
|
||||||
|
// Granular format: { "devices": { "key": ["/path1", "/path2"], ... } }
|
||||||
|
deviceActionPaths = devicesToken.ToObject<Dictionary<string, List<string>>>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Legacy format: { "deviceKeys": ["key1", "key2"] } -> each gets /fullStatus
|
||||||
var deviceKeys = content.SelectToken("deviceKeys")?.ToObject<List<string>>();
|
var deviceKeys = content.SelectToken("deviceKeys")?.ToObject<List<string>>();
|
||||||
|
|
||||||
if (deviceKeys == null || deviceKeys.Count == 0)
|
if (deviceKeys == null || deviceKeys.Count == 0)
|
||||||
{
|
{
|
||||||
this.LogWarning("BatchDeviceFullStatus: No device keys provided");
|
this.LogWarning("BatchDeviceFullStatus: No device keys or devices provided");
|
||||||
SendMessageObject(new MobileControlMessage
|
SendMessageObject(new MobileControlMessage
|
||||||
{
|
{
|
||||||
Type = "/system/initialSyncComplete",
|
Type = "/system/initialSyncComplete",
|
||||||
|
|
@ -1526,22 +1544,46 @@ namespace PepperDash.Essentials
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.LogInformation("BatchDeviceFullStatus: Processing {count} device keys", deviceKeys.Count);
|
deviceActionPaths = deviceKeys.ToDictionary(k => k, _ => new List<string> { "/fullStatus" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceActionPaths == null || deviceActionPaths.Count == 0)
|
||||||
|
{
|
||||||
|
this.LogWarning("BatchDeviceFullStatus: Empty devices dictionary");
|
||||||
|
SendMessageObject(new MobileControlMessage
|
||||||
|
{
|
||||||
|
Type = "/system/initialSyncComplete",
|
||||||
|
ClientId = clientId
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.LogInformation("BatchDeviceFullStatus: Processing {count} devices", deviceActionPaths.Count);
|
||||||
|
|
||||||
var tasks = new List<Task>();
|
var tasks = new List<Task>();
|
||||||
|
|
||||||
foreach (var deviceKey in deviceKeys)
|
foreach (var kvp in deviceActionPaths)
|
||||||
{
|
{
|
||||||
var fullStatusPath = $"/device/{deviceKey}/fullStatus";
|
var deviceKey = kvp.Key;
|
||||||
|
var actionPaths = kvp.Value;
|
||||||
|
|
||||||
|
if (actionPaths == null || actionPaths.Count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var actionPath in actionPaths)
|
||||||
|
{
|
||||||
|
var fullPath = $"/device/{deviceKey}{actionPath}";
|
||||||
|
|
||||||
var handlers = _actionDictionary
|
var handlers = _actionDictionary
|
||||||
.Where(kv => fullStatusPath.StartsWith(kv.Key + "/"))
|
.Where(kv => fullPath.StartsWith(kv.Key + "/"))
|
||||||
.SelectMany(kv => kv.Value)
|
.SelectMany(kv => kv.Value)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (handlers.Count == 0)
|
if (handlers.Count == 0)
|
||||||
{
|
{
|
||||||
this.LogDebug("BatchDeviceFullStatus: No handlers for {deviceKey}", deviceKey);
|
this.LogDebug("BatchDeviceFullStatus: No handlers for {deviceKey} at path {actionPath}", deviceKey, actionPath);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1551,15 +1593,16 @@ namespace PepperDash.Essentials
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
handler.Action(fullStatusPath, clientId, JToken.FromObject(new { deviceKey }));
|
handler.Action(fullPath, clientId, JToken.FromObject(new { deviceKey }));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
this.LogError("BatchDeviceFullStatus: Exception in handler for {deviceKey}: {message}", deviceKey, ex.Message);
|
this.LogError("BatchDeviceFullStatus: Exception in handler for {deviceKey} at {actionPath}: {message}", deviceKey, actionPath, ex.Message);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// After all handlers have completed and enqueued their responses, send sync complete
|
// After all handlers have completed and enqueued their responses, send sync complete
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue