Skip to content

Commit 69beeb1

Browse files
committed
v1.47.0 - Updates for Touch Portal API versions 7-10.
1 parent a84505e commit 69beeb1

File tree

11 files changed

+284
-42
lines changed

11 files changed

+284
-42
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,16 @@ Since `oddbear's` TouchPortalSDK v 0.30.0 release version, the paths have diverg
5353

5454
### New Features & Change Log
5555

56+
#### v 1.47.0
57+
Updates for Touch Portal API versions 7-10.
58+
* Added `TriggerEvent(string eventId, Dictionary<string, object> states)` method & `TriggerEventCommand` type.
59+
* Added `StateListUpdate(string stateId, string[] values)` method & `StateListUpdateCommand` type.
60+
* Added `forceUpdate` option to `CreateState()` method and `CreateStateCommand.ForceUpdate` member.
61+
* Added `ListChangeEvent.Values` property for `listChangeEvent` incoming message. This is a `Dictionary<string, string>` type.
62+
* Added `InfoEvent.CurrentPagePathMainDevice` and `InfoIevent.CurrentPagePathSecondaryDevices` properties for `info` incoming message type.
63+
* Added `PreviousPageName`, `DeviceIP`, `DeviceName`, and `DeviceID` to `BroadcastEvent` incoming message type.
64+
* Added & improved some documentation comments.
65+
5666
#### v 1.46.1
5767
* Updated for .NET8 and dropped .NET5 support.
5868
* Updated dependencies to 8.x versions (also fixes a security issue in the `System.Text.Json` library).

TouchPortalSDK/Clients/TouchPortalClient.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Concurrent;
33
using System.Runtime.CompilerServices;
44
using System.Text.Json;
@@ -144,10 +144,10 @@ bool ICommandHandler.SettingUpdate(string name, string value)
144144
}
145145

146146
/// <inheritdoc cref="ICommandHandler" />
147-
bool ICommandHandler.CreateState(string stateId, string desc, string defaultValue, string parentGroup)
147+
bool ICommandHandler.CreateState(string stateId, string desc, string defaultValue, string parentGroup, bool forceUpdate)
148148
{
149149
try {
150-
return SendCommand(new CreateStateCommand(stateId, desc, defaultValue, parentGroup));
150+
return SendCommand(new CreateStateCommand(stateId, desc, defaultValue, parentGroup, forceUpdate));
151151
}
152152
catch (ArgumentException e) {
153153
_logger?.LogWarning(e, "CreateStateCommand() validation failed.");
@@ -239,6 +239,37 @@ bool ICommandHandler.ConnectorUpdateShort(string shortId, int value)
239239
}
240240
}
241241

242+
/// <inheritdoc cref="ICommandHandler" />
243+
bool ICommandHandler.TriggerEvent(string eventId, TriggerEventStates states)
244+
{
245+
try {
246+
return SendCommand(new TriggerEventCommand(eventId, states));
247+
}
248+
catch (ArgumentException e) {
249+
_logger?.LogWarning(e, "TriggerEvent() validation failed.");
250+
return false;
251+
}
252+
}
253+
254+
/// <inheritdoc cref="ICommandHandler" />
255+
bool ICommandHandler.StateListUpdate(string stateId, string[] values)
256+
{
257+
try {
258+
return SendCommand(new StateListUpdateCommand(stateId, values));
259+
}
260+
catch (ArgumentException e) {
261+
_logger?.LogWarning(e, "StateListUpdate() validation failed.");
262+
return false;
263+
}
264+
265+
}
266+
267+
/// <summary>
268+
/// Send a Command directly to Touch Portal. All the other command sending methods are conveniences for this one.
269+
/// </summary>
270+
/// <typeparam name="TCommand">A type implementing from `ITouchPortalMessage`</typeparam>
271+
/// <param name="command">One of `TouchPortalSDK.Messages.Commands` types.</param>
272+
/// <returns></returns>
242273
public bool SendCommand<TCommand>(TCommand command, [CallerMemberName]string callerMemberName = "")
243274
where TCommand : ITouchPortalMessage
244275
{

TouchPortalSDK/Configuration/MessageResolver.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Collections.Generic;
1+
using System.Collections.Generic;
22
using System.Collections.ObjectModel;
33
using System.Text.Json;
44
using TouchPortalSDK.Interfaces;
@@ -31,10 +31,12 @@ internal enum TpEventName : byte
3131
// RemoveState,
3232
// StateUpdate,
3333
// UpdateActionData,
34-
// SettingsUpdate
34+
// SettingsUpdate,
35+
// TriggerEventCommand,
36+
// StateListUpdate
3537
}
3638

37-
// Map the event name enums to the corresponding types. (Benchamrked against using an Attribute on the enums and a dict lookup is several magnitudes faster.)
39+
// Map the event name enums to the corresponding types. (Benchmarked against using an Attribute on the enums and a dict lookup is several magnitudes faster.)
3840
private static readonly ReadOnlyDictionary<TpEventName, System.Type> eventTypeMap = new ReadOnlyDictionary<TpEventName, System.Type>(
3941
new Dictionary<TpEventName, System.Type>() {
4042
{ TpEventName.Action, typeof(ActionEvent) },
@@ -58,7 +60,7 @@ private class TouchPortalMessageType
5860
/// <summary>
5961
/// Resolves and parses a JSON string from byte array into a <see cref="ITouchPortalMessage"/> event Type.
6062
/// </summary>
61-
/// <param name="message">byte array of UTF8-encdoed chars.</param>
63+
/// <param name="message">byte array of UTF8-encoded chars.</param>
6264
/// <returns>A resolved <see cref="ITouchPortalMessage"/> type or <c>null</c> if the event type is unknown.</returns>
6365
/// <exception cref="JsonException">In case of any JSON string parsing errors.</exception>
6466
internal static ITouchPortalMessage ResolveMessage(System.ReadOnlySpan<byte> message)
Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,59 @@
1-
using TouchPortalSDK.Messages.Models;
1+
using TouchPortalSDK.Messages.Models;
22
using TouchPortalSDK.Messages.Models.Enums;
33

44
namespace TouchPortalSDK.Interfaces
55
{
66
public interface ICommandHandler
77
{
88
/// <summary>
9-
/// Send a custom command. There is no state tracking for this.
9+
/// Send a custom command to Touch Portal. The message must be properly encoded JSON format.
1010
/// </summary>
11-
/// <param name="message"></param>
12-
/// <returns></returns>
11+
/// <param name="message">A JSON message to send. A terminating newline will be added automatically when the message is sent.</param>
12+
/// <returns>true on successful sending of the message, false otherwise.</returns>
1313
bool SendMessage(string message);
1414

1515
/// <summary>
1616
/// Creates a dynamic state in Touch Portal Memory.
1717
/// This state will disappear when restarting Touch Portal.
1818
/// You will need to persist them yourself and reload them on plugin load.
1919
/// </summary>
20-
/// <param name="stateId"></param>
20+
/// <param name="stateId">A unique ID for the new state.</param>
2121
/// <param name="desc">Description of the created state (name in menus).</param>
2222
/// <param name="defaultValue">Default value of this state, default is empty string.</param>
2323
/// <param name="parentGroup">Parent group of this state (TP API v6). Default is an empty string.</param>
24-
/// <returns></returns>
25-
bool CreateState(string stateId, string desc, string defaultValue = "", string parentGroup = "");
24+
/// <param name="forceUpate">
25+
/// This will force the update of the state if it is already created or existing and will trigger the state
26+
/// changed event even if the value is the same as the already existing one.
27+
/// Since TP API v7.
28+
/// </param>
29+
/// <returns>true on successful sending of the message, false otherwise.</returns>
30+
bool CreateState(string stateId, string desc, string defaultValue = "", string parentGroup = "", bool forceUpate = false);
2631

2732
/// <summary>
2833
/// Updates a setting in Touch Portal.
2934
/// </summary>
30-
/// <param name="name"></param>
31-
/// <param name="value"></param>
32-
/// <returns></returns>
35+
/// <param name="name">Setting name</param>
36+
/// <param name="value">New value for the setting</param>
37+
/// <returns>true on successful sending of the message, false otherwise.</returns>
3338
bool SettingUpdate(string name, string value = "");
3439

3540
/// <summary>
3641
/// Removes the dynamic state from Touch Portal.
3742
/// </summary>
38-
/// <param name="stateId"></param>
39-
/// <returns></returns>
43+
/// <param name="stateId">ID of the state to remove.</param>
44+
/// <returns>true on successful sending of the message, false otherwise.</returns>
4045
bool RemoveState(string stateId);
4146

4247
/// <summary>
4348
/// Value that can be displayed, or an event can trigger on.
44-
/// Values are not persisted, and will fallback to default value on restart.
49+
/// Values are not persisted, and will fall back to default value on restart.
4550
/// - Plugin: Defined in the Entry.tp
4651
/// - Dynamic: Created or removed at runtime. (in memory only)
4752
/// - Global: Defined in the Touch Portal UI. (state definition persisted in %AppData%\TouchPortal\states.tp)
4853
/// </summary>
49-
/// <param name="stateId"></param>
50-
/// <param name="value"></param>
51-
/// <returns></returns>
54+
/// <param name="stateId">ID of the state to update.</param>
55+
/// <param name="value">The new value to set for the state. Must be a string.</param>
56+
/// <returns>true on successful sending of the message, false otherwise.</returns>
5257
bool StateUpdate(string stateId, string value = "");
5358

5459
/// <summary>
@@ -58,7 +63,7 @@ public interface ICommandHandler
5863
/// <param name="choiceId">Id of UI dropdown.</param>
5964
/// <param name="values">Values as string array that you can choose from.</param>
6065
/// <param name="instanceId">if set (fetched from listChange event), this will only update this particular list.</param>
61-
/// <returns></returns>
66+
/// <returns>true on successful sending of the message, false otherwise.</returns>
6267
bool ChoiceUpdate(string choiceId, string[] values, string instanceId = default);
6368

6469
/// <summary>
@@ -69,7 +74,7 @@ public interface ICommandHandler
6974
/// <param name="maxValue">Max value the field can be.</param>
7075
/// <param name="dataType">Type of the data field.</param>
7176
/// <param name="instanceId">if set (fetched from listChange event), this will only update this particular list.</param>
72-
/// <returns></returns>
77+
/// <returns>true on successful sending of the message, false otherwise.</returns>
7378
bool UpdateActionData(string dataId, double minValue, double maxValue, ActionDataType dataType, string instanceId = default);
7479

7580
/// <summary>
@@ -78,7 +83,7 @@ public interface ICommandHandler
7883
/// <param name="notificationId">If of the notification.</param>
7984
/// <param name="title">Title on the notification shown to the user.</param>
8085
/// <param name="message">Text / description of the notification shown to the user.</param>
81-
/// <returns></returns>
86+
/// <returns>true on successful sending of the message, false otherwise.</returns>
8287
bool ShowNotification(string notificationId, string title, string message, NotificationOptions[] notificationOptions);
8388

8489
/// <summary>
@@ -87,15 +92,34 @@ public interface ICommandHandler
8792
/// <param name="connectorId">The long ID of the connector to update. The string "pc_{pluginId}_" is automatically prepended
8893
/// before sending to TP. The total length must not exceed 200 chars.</param>
8994
/// <param name="value">The value to send, must be between 0 and 100, inclusive.</param>
90-
/// <returns>true on success, false otherwise.</returns>
95+
/// <returns>true on successful sending of the message, false otherwise.</returns>
9196
bool ConnectorUpdate(string connectorId, int value);
9297

9398
/// <summary>
9499
/// Sends a connector value update to Touch Portal using the short form of the connector ID.
95100
/// </summary>
96101
/// <param name="shortId">The short ID of the connector to update. This is obtained from a <see cref="ShortConnectorIdNotification"/> event.</param>
97102
/// <param name="value">The value to send, must be between 0 and 100, inclusive.</param>
98-
/// <returns>true on success, false otherwise.</returns>
103+
/// <returns>true on successful sending of the message, false otherwise.</returns>
99104
bool ConnectorUpdateShort(string shortId, int value);
105+
106+
/// <summary>
107+
/// Trigger predefined Events by sending a message to Touch Portal with the given eventId and additional data.
108+
/// Since TP API v7.
109+
/// </summary>
110+
/// <param name="eventId">The event id to trigger. This event must be defined in the plugin's entry.tp declaration.</param>
111+
/// <param name="states">This gets serialized to a JSON Object that holds key value pairs of data that are used within Touch Portal as Local States.</param>
112+
/// <returns>true on successful sending of the message, false otherwise.</returns>
113+
bool TriggerEvent(string eventId, Messages.Commands.TriggerEventStates states = null);
114+
115+
/// <summary>
116+
/// You can also update state lists in Touch Portal. These state lists needs to be defined in the entry file.
117+
/// Since TP API v7.
118+
/// </summary>
119+
/// <param name="stateId">The state id to set/update.</param>
120+
/// <param name="values">The collection of texts that should be the new list to display for this given choice list id. </param>
121+
/// <returns>true on successful sending of the message, false otherwise.</returns>
122+
bool StateListUpdate(string stateId, string[] values);
123+
100124
}
101125
}

TouchPortalSDK/Messages/Commands/CreateStateCommand.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,48 @@
1-
using System;
1+
using System;
22
using TouchPortalSDK.Interfaces;
33
using TouchPortalSDK.Messages.Models;
44

55
namespace TouchPortalSDK.Messages.Commands
66
{
7+
/// <summary>
8+
/// States can be created on runtime using by sending a "createState" message to Touch Portal with the given information.
9+
/// </summary>
710
public class CreateStateCommand : ITouchPortalMessage
811
{
912
public string Type => "createState";
1013

14+
/// <summary>
15+
/// The id of the newly created plug-in state. Please ensure unique names, otherwise you may corrupt other plug-ins.
16+
/// </summary>
1117
public string Id { get; set; }
1218

19+
/// <summary> The displayed name within Touch Portal which represents the state. </summary>
1320
public string Desc { get; set; }
1421

22+
/// <summary> The default value the state will have on creation. </summary>
1523
public string DefaultValue { get; set; }
1624

25+
/// <summary>
26+
/// The name of the parent group of this state. The parent group of this state will be used to group the state in
27+
/// the menus used throughout Touch Portal. Every state belonging to the same parent group name will be in the same selection menu.
28+
/// Since TP API v6.
29+
/// </summary>
1730
public string ParentGroup { get; set; }
1831

19-
public CreateStateCommand(string stateId, string desc, string defaultValue = "", string parentGroup = "")
20-
{
32+
/// <summary>
33+
/// This will force the update of the state if it is already created or existing and will trigger the state
34+
/// changed event even if the value is the same as the already existing one.
35+
/// Since TP API v7.
36+
/// </summary>
37+
public bool ForceUpdate { get; set; } = false;
38+
39+
public CreateStateCommand(
40+
string stateId,
41+
string desc,
42+
string defaultValue = "",
43+
string parentGroup = "",
44+
bool forceUpdate = false
45+
) {
2146
if (TouchPortalOptions.ValidateCommandParameters) {
2247
if (string.IsNullOrWhiteSpace(stateId))
2348
throw new ArgumentNullException(nameof(stateId));
@@ -29,6 +54,7 @@ public CreateStateCommand(string stateId, string desc, string defaultValue = "",
2954
Desc = desc;
3055
DefaultValue = defaultValue ?? string.Empty;
3156
ParentGroup = parentGroup ?? string.Empty;
57+
ForceUpdate = forceUpdate;
3258
}
3359

3460
/// <inheritdoc cref="ITouchPortalMessage" />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using TouchPortalSDK.Interfaces;
3+
using TouchPortalSDK.Messages.Models;
4+
5+
namespace TouchPortalSDK.Messages.Commands
6+
{
7+
/// <summary>
8+
/// You can also update state lists in Touch Portal. These state lists needs to be defined in the entry file.
9+
/// Since TP API v7.
10+
/// </summary>
11+
public class StateListUpdateCommand : ITouchPortalMessage
12+
{
13+
14+
/// <inheritdoc cref="ITouchPortalMessage" />
15+
public string Type => "stateListUpdate";
16+
17+
/// <summary> The state id to set/update. </summary>
18+
public string Id { get; set; }
19+
20+
/// <summary>The collection of texts that should be the new list to display for this given choice list id. </summary>
21+
public string[] Value { get; set; }
22+
23+
public StateListUpdateCommand(string stateId, string[] value)
24+
{
25+
if (TouchPortalOptions.ValidateCommandParameters && string.IsNullOrWhiteSpace(stateId))
26+
throw new ArgumentNullException(nameof(stateId));
27+
28+
Id = stateId;
29+
Value = value ?? Array.Empty<string>();
30+
}
31+
32+
/// <inheritdoc cref="ITouchPortalMessage" />
33+
public Identifier GetIdentifier()
34+
=> new Identifier(Type, Id, default);
35+
}
36+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using TouchPortalSDK.Interfaces;
4+
using TouchPortalSDK.Messages.Models;
5+
using TouchPortalSDK.Messages.Models.Enums;
6+
7+
namespace TouchPortalSDK.Messages.Commands
8+
{
9+
/// <summary>
10+
/// You can trigger predefined Events by sending a message to Touch Portal with the given eventId and additional data.
11+
/// Since: TP API v7
12+
/// </summary>
13+
public class TriggerEventCommand : ITouchPortalMessage
14+
{
15+
/// <inheritdoc cref="ITouchPortalMessage.Type" />
16+
public string Type => "triggerEvent";
17+
18+
/// <summary> The event id to trigger. This event must be defined in the plugin's entry.tp declaration.</summary>
19+
public string EventId;
20+
/// <summary> This gets serialized to a JSON Object that holds key value pairs of data that are used within Touch Portal as Local States. </summary>
21+
public TriggerEventStates States = null;
22+
23+
public TriggerEventCommand(string eventId, TriggerEventStates states = null)
24+
{
25+
if (TouchPortalOptions.ValidateCommandParameters && string.IsNullOrWhiteSpace(eventId))
26+
throw new ArgumentNullException(nameof(eventId));
27+
28+
EventId = eventId;
29+
States = states;
30+
}
31+
32+
/// <inheritdoc cref="ITouchPortalMessage.GetIdentifier" />
33+
public Identifier GetIdentifier()
34+
=> new Identifier(Type, EventId, default);
35+
}
36+
37+
38+
/// <summary>
39+
/// This is a `Dictionary&lt;string, object&gt;` typedef for usage in TriggerEventCommand.States message value.
40+
/// </summary>
41+
public sealed class TriggerEventStates : System.Collections.Generic.Dictionary<string, object>
42+
{ }
43+
44+
}

0 commit comments

Comments
 (0)