├── IntegrationDemo.deck
├── res
├── demo-enter-pin.png
└── authorize-app-popup.png
├── .gitignore
├── demos
├── net_wrapper
│ ├── lib
│ │ ├── MatricIntegration.dll
│ │ └── MatricIntegration.pdb
│ ├── packages.config
│ ├── App.config
│ ├── IntegrationDemoCSWrapper.csproj.user
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── IntegrationDemoCSWrapper.csproj
│ └── Program.cs
└── raw
│ ├── packages.config
│ ├── App.config
│ ├── DemoRaw.csproj.user
│ ├── Properties
│ └── AssemblyInfo.cs
│ ├── DemoRaw.csproj
│ ├── Program.cs
│ └── DemoIntegrationHelper.cs
├── DemoCommon.cs
├── IntegrationDemo.sln
└── README.md
/IntegrationDemo.deck:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgudelj/MATRICIntegrationDemo/HEAD/IntegrationDemo.deck
--------------------------------------------------------------------------------
/res/demo-enter-pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgudelj/MATRICIntegrationDemo/HEAD/res/demo-enter-pin.png
--------------------------------------------------------------------------------
/res/authorize-app-popup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgudelj/MATRICIntegrationDemo/HEAD/res/authorize-app-popup.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /packages
2 | /demos/net_wrapper/obj
3 | /demos/net_wrapper/bin
4 | /demos/raw/bin
5 | /demos/raw/obj
6 | .vs
7 |
--------------------------------------------------------------------------------
/demos/net_wrapper/lib/MatricIntegration.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgudelj/MATRICIntegrationDemo/HEAD/demos/net_wrapper/lib/MatricIntegration.dll
--------------------------------------------------------------------------------
/demos/net_wrapper/lib/MatricIntegration.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tgudelj/MATRICIntegrationDemo/HEAD/demos/net_wrapper/lib/MatricIntegration.pdb
--------------------------------------------------------------------------------
/demos/raw/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/demos/net_wrapper/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/demos/raw/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demos/net_wrapper/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demos/raw/DemoRaw.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ProjectFiles
5 |
6 |
--------------------------------------------------------------------------------
/demos/net_wrapper/IntegrationDemoCSWrapper.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ShowAllFiles
5 |
6 |
--------------------------------------------------------------------------------
/DemoCommon.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace IntegrationDemo {
3 | public static class CONST
4 | {
5 | public static string DEMO_DECK_ID = "7f18056c-7a2a-46ac-9956-662e7d0b78ec";
6 | public static string SMILE_WINK = "😉";
7 | public static string APP_NAME = "MATRIC Integration Demo";
8 | public static int API_PORT = 50300;
9 | public static string PIN = "0450";
10 | }
11 |
12 | public static class DemoPages
13 | {
14 | public static string SEMAPHORE = "00d9c649-f2df-405f-abfd-06d38f8626be";
15 | public static string SHIELDS_AND_WEAPONS = "16856457-d2f8-405e-927e-749b1dc7d7ec";
16 | public static string DEMO_COMPLETE = "b0a0b559-9e2c-42af-9c64-95951ef09cbd";
17 | }
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/demos/raw/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("IntegrationDemo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("IntegrationDemo")]
13 | [assembly: AssemblyCopyright("Copyright © 2022")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d84ec5c4-6daa-4131-b2e3-5edadc5d3b32")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.1.0.0")]
36 | [assembly: AssemblyFileVersion("1.1.0.0")]
37 |
--------------------------------------------------------------------------------
/demos/net_wrapper/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("IntegrationDemo")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("IntegrationDemo")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("d84ec5c4-6daa-4131-b2e3-5edadc5d3b32")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/IntegrationDemo.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.32112.339
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoRaw", "demos\raw\DemoRaw.csproj", "{99839985-31B8-4FD2-947E-CD66E76046E5}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntegrationDemoCSWrapper", "demos\net_wrapper\IntegrationDemoCSWrapper.csproj", "{D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9F8AC669-FE67-4F4D-94C8-6455C61D6ACD}"
11 | ProjectSection(SolutionItems) = preProject
12 | DemoCommon.cs = DemoCommon.cs
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Debug|x64 = Debug|x64
19 | Release|Any CPU = Release|Any CPU
20 | Release|x64 = Release|x64
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Debug|x64.ActiveCfg = Debug|x64
26 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Debug|x64.Build.0 = Debug|x64
27 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
28 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Release|Any CPU.Build.0 = Release|Any CPU
29 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Release|x64.ActiveCfg = Release|x64
30 | {99839985-31B8-4FD2-947E-CD66E76046E5}.Release|x64.Build.0 = Release|x64
31 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Debug|x64.ActiveCfg = Debug|x64
34 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Debug|x64.Build.0 = Debug|x64
35 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Release|x64.ActiveCfg = Release|x64
38 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}.Release|x64.Build.0 = Release|x64
39 | EndGlobalSection
40 | GlobalSection(SolutionProperties) = preSolution
41 | HideSolutionNode = FALSE
42 | EndGlobalSection
43 | GlobalSection(ExtensibilityGlobals) = postSolution
44 | SolutionGuid = {15101259-A543-4F92-A4A0-580D6D497CE7}
45 | EndGlobalSection
46 | EndGlobal
47 |
--------------------------------------------------------------------------------
/demos/raw/DemoRaw.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {99839985-31B8-4FD2-947E-CD66E76046E5}
8 | Exe
9 | IntegrationDemo
10 | IntegrationDemo
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 | true
38 | bin\x64\Debug\
39 | DEBUG;TRACE
40 | full
41 | x64
42 | 7.3
43 | prompt
44 | true
45 |
46 |
47 | bin\x64\Release\
48 | TRACE
49 | true
50 | pdbonly
51 | x64
52 | 7.3
53 | prompt
54 | true
55 |
56 |
57 |
58 | ..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | DemoCommon.cs
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/demos/net_wrapper/IntegrationDemoCSWrapper.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {D84EC5C4-6DAA-4131-B2E3-5EDADC5D3B32}
8 | Exe
9 | IntegrationDemo
10 | IntegrationDemo
11 | v4.8
12 | 512
13 | true
14 | true
15 |
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 | true
38 | bin\x64\Debug\
39 | DEBUG;TRACE
40 | full
41 | x64
42 | 7.3
43 | prompt
44 | true
45 |
46 |
47 | bin\x64\Release\
48 | TRACE
49 | true
50 | pdbonly
51 | x64
52 | 7.3
53 | prompt
54 | true
55 |
56 |
57 |
58 | False
59 | lib\MatricIntegration.dll
60 |
61 |
62 | ..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | DemoCommon.cs
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/demos/raw/Program.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Linq;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using static IntegrationDemo.DemoIntegrationHelper;
7 |
8 | namespace IntegrationDemo {
9 |
10 |
11 | class Program {
12 | public static string DEMO_DECK_ID = CONST.DEMO_DECK_ID;
13 | public static string PIN = CONST.PIN;
14 | public static string CLIENT_ID;
15 | public static DemoIntegrationHelper mtrx;
16 | static void Main(string[] args)
17 | {
18 | Console.Title = "MATRIC Integration Demo";
19 | mtrx = new DemoIntegrationHelper();
20 | Console.WriteLine("Authorize connection in MATRIC, then enter PIN:");
21 | //mtrx.Connect();
22 | //PIN = Console.ReadLine();
23 | mtrx.GetConnectedClients();
24 | Console.ReadLine();
25 | }
26 |
27 | private static void StartDemo() {
28 | string GRAY = "#111111";
29 | string YELLOW = "yellow";
30 | string GREEN = "green";
31 | string RED = "red";
32 | string BLACK = "black";
33 | string WHITE = "white";
34 |
35 | mtrx.SetDeck(CLIENT_ID, DEMO_DECK_ID, DemoPages.SEMAPHORE);
36 | Thread.Sleep(800);
37 |
38 | List listOn = new List();
39 | //we will refer to the buttons by name rather then id
40 | listOn.Add(new VisualStateItem(null, "on", buttonName: "BTN_GREEN"));
41 | listOn.Add(new VisualStateItem(null, "on", buttonName: "BTN_YELLOW"));
42 | listOn.Add(new VisualStateItem(null, "on", buttonName: "BTN_RED"));
43 |
44 | List listOff = new List();
45 | listOff.Add(new VisualStateItem(null, "off", buttonName: "BTN_GREEN"));
46 | listOff.Add(new VisualStateItem(null, "off", buttonName: "BTN_YELLOW"));
47 | listOff.Add(new VisualStateItem(null, "off", buttonName: "BTN_RED"));
48 |
49 | mtrx.SetButtonsVisualState(CLIENT_ID, listOn);
50 | Thread.Sleep(800);
51 | mtrx.SetButtonsVisualState(CLIENT_ID, listOff);
52 | Thread.Sleep(800);
53 | mtrx.SetButtonsVisualState(CLIENT_ID, listOn);
54 | Thread.Sleep(800);
55 | mtrx.SetButtonsVisualState(CLIENT_ID, listOff);
56 | Thread.Sleep(800);
57 |
58 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_GREEN", backgroundcolorOff: GREEN);
59 | Thread.Sleep(800);
60 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_GREEN", backgroundcolorOff: GRAY);
61 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_YELLOW", backgroundcolorOff: YELLOW);
62 | Thread.Sleep(800);
63 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_GREEN", backgroundcolorOff: GRAY);
64 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_YELLOW", backgroundcolorOff: GRAY);
65 | mtrx.SetButtonProperties(CLIENT_ID, "BTN_RED", backgroundcolorOff: RED);
66 | Thread.Sleep(1000);
67 |
68 | mtrx.SetActivePage(CLIENT_ID, DemoPages.SHIELDS_AND_WEAPONS);
69 | Thread.Sleep(1500);
70 | //simulate battle
71 | int ammo = 500;
72 | int shields = 100;
73 | for (int i = 0; i < 100; i++) {
74 | mtrx.SetControlsState(CLIENT_ID, new List {
75 | new SetControlStateItem(null, $"{{value: {shields}}}", "SHIELDS_SLIDER")
76 | });
77 | if (shields < 30)
78 | {
79 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_CRITICAL", textcolorOff: BLACK, backgroundcolorOff: RED);
80 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: RED, text: $@"{shields}%");
81 | }
82 | else if (shields < 50)
83 | {
84 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: YELLOW, text: $@"{shields}%");
85 | }
86 | else {
87 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: GREEN, text: $@"{shields}%");
88 | }
89 | mtrx.SetButtonProperties(CLIENT_ID, "AMMO_COUNT", backgroundcolorOff: GRAY, textcolorOff: WHITE, text: $@"{ammo}");
90 | shields--;
91 | ammo = ammo -5;
92 | Thread.Sleep(100);
93 | }
94 |
95 | //flash critical shields
96 | bool criticalOn = true;
97 | for (int i = 0; i < 10; i++) {
98 | if (criticalOn)
99 | {
100 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_CRITICAL", textcolorOff: GRAY, backgroundcolorOff: BLACK);
101 | }
102 | else {
103 | mtrx.SetButtonProperties(CLIENT_ID, "SHIELDS_CRITICAL", textcolorOff: GRAY, backgroundcolorOff: RED);
104 | }
105 | criticalOn = !criticalOn;
106 | Thread.Sleep(400);
107 | }
108 |
109 | mtrx.SetActivePage(CLIENT_ID, DemoPages.DEMO_COMPLETE);
110 | Thread.Sleep(1000);
111 | mtrx.SetButtonProperties(CLIENT_ID, "WINK_BUTTON", text: CONST.SMILE_WINK);
112 | Console.WriteLine("Demo complete");
113 | //mtrx.SetDeck(CLIENT_ID, DEMO_DECK_ID, DemoPages.SEMAPHORE);
114 |
115 | }
116 |
117 | public static void ParseMessage(string json) {
118 | JObject obj = JObject.Parse(json);
119 | string messageType = obj.GetValue("MessageType").ToString();
120 | switch (messageType) {
121 | case "ClientList":
122 | UpdateClientsList(obj.GetValue("MessageData").ToString());
123 | break;
124 | case "ControlInteraction":
125 | OnControlInteraction(obj.GetValue("MessageData").ToString());
126 | break;
127 | }
128 | }
129 | public static void OnControlInteraction(string data)
130 | {
131 | Console.WriteLine("Control interaction:");
132 | Console.WriteLine(data);
133 | }
134 |
135 | public static void UpdateClientsList(string json) {
136 | JArray connectedClients = (JArray)JsonConvert.DeserializeObject(json);
137 | if (connectedClients.Count == 0)
138 | {
139 | Console.WriteLine("No connected devices found, make sure your smartphone/tablet is connected\nPress any key to exit");
140 | Console.ReadKey();
141 | Environment.Exit(0);
142 | }
143 | Console.WriteLine("Found devices:");
144 | foreach (JObject client in connectedClients)
145 | {
146 | Console.WriteLine($@"{client.GetValue("Hash")} {client.GetValue("Name")}");
147 | }
148 | CLIENT_ID = ((JObject)connectedClients[0]).GetValue("clientId").ToString();
149 | Console.WriteLine("Starting demo on first device");
150 | StartDemo();
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/demos/raw/DemoIntegrationHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 | using System.Net.Sockets;
5 | using System.Text;
6 |
7 | namespace IntegrationDemo {
8 | public class DemoIntegrationHelper {
9 |
10 | UdpClient udpClient;
11 | IPEndPoint serverEP = new IPEndPoint(IPAddress.Loopback, API_PORT);
12 | public static int API_PORT = CONST.API_PORT;
13 | public static int UDP_LISTENER_PORT = 50301;
14 | private string APP_NAME = CONST.APP_NAME;
15 |
16 | public DemoIntegrationHelper() {
17 | udpClient = new UdpClient(UDP_LISTENER_PORT);
18 | udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
19 | }
20 |
21 |
22 | public void ReceiveCallback(IAsyncResult ar){
23 | IPEndPoint ep = new IPEndPoint(serverEP.Address, serverEP.Port);
24 | byte[] receiveBytes = udpClient.EndReceive(ar, ref ep);
25 | string receiveString = Encoding.ASCII.GetString(receiveBytes);
26 |
27 | Program.ParseMessage(receiveString);
28 | udpClient.BeginReceive(new AsyncCallback(ReceiveCallback), null);
29 | }
30 |
31 |
32 |
33 | ///
34 | /// Initiates the connection
35 | ///
36 | public void Connect() {
37 | string msg = $@"
38 | {{""command"":""CONNECT"",
39 | ""appName"":""{APP_NAME}""}}
40 | ";
41 | UDPSend(msg);
42 | }
43 |
44 | ///
45 | ///Requests the list of connected MATRIC clients
46 | ///
47 | public void GetConnectedClients()
48 | {
49 | string msg = $@"
50 | {{""command"":""GETCONNECTEDCLIENTS"",
51 | ""appName"":""{APP_NAME}"",
52 | ""appPIN"":""{Program.PIN}""}}
53 | ";
54 | UDPSend(msg);
55 | }
56 |
57 | ///
58 | /// Sets various button properties
59 | ///
60 | /// Target client id
61 | /// Id of the button we want to change
62 | /// Button text to set
63 | /// Button text color in pressed state
64 | /// Button text color in normal state
65 | /// Button background color in normal state
66 | /// Button background color in pressed state
67 | /// Button relative font size - string: small, medium, large, xlarge, xxlarge, xxxlarge
68 | /// Button image in pressed state
69 | /// Button image in normal state
70 | /// Button name (preferred way to reference buttons, rather then by id)
71 | public void SetButtonProperties(string clientId, string buttonName, string text = null, string textcolorOn = null, string textcolorOff = null,
72 | string backgroundcolorOff = null, string backgroundcolorOn = null, string imageOn = null, string imageOff = null, string fontSize = null, string buttonId = null)
73 | {
74 | //Remark: if we do not want to change a particular property, we will send it as null
75 | string msg = $@"
76 | {{""command"":""SETBUTTONPROPS"",
77 | ""appName"":""{APP_NAME}"",
78 | ""appPIN"":""{Program.PIN}"",
79 | ""clientId"":""{clientId}"",
80 | ""buttonId"":""{buttonId}"",
81 | ""buttonName"": ""{buttonName}"",
82 | ""data"":{{
83 | ""imageOff"": { (imageOff == null ? "null" : "\"" + imageOff + "\"") },
84 | ""imageOn"": { (imageOn == null ? "null" : "\"" + imageOff + "\"") },
85 | ""textcolorOn"": { (textcolorOn == null ? "null" : "\"" + textcolorOn + "\"")},
86 | ""textcolorOff"":{ (textcolorOff == null ? "null" : "\"" + textcolorOff + "\"")},
87 | ""backgroundcolorOn"": { (backgroundcolorOn == null ? "null" : "\"" + backgroundcolorOn + "\"")},
88 | ""backgroundcolorOff"":{ (backgroundcolorOff == null ? "null" : "\"" + backgroundcolorOff + "\"")},
89 | ""fontSize"":{ (fontSize == null ? "null" : "\"" + fontSize + "\"")},
90 | ""text"":{ (text == null ? "null" : "\"" + text + "\"")}
91 | }}
92 | }}";
93 | UDPSend(msg);
94 | }
95 |
96 | ///
97 | /// Sets the active page
98 | ///
99 | /// Target client id
100 | /// Page id
101 | public void SetActivePage(string clientId, string pageId)
102 | {
103 | string msg = $@"
104 | {{""command"":""SETACTIVEPAGE"",
105 | ""appName"":""{APP_NAME}"",
106 | ""appPIN"":""{Program.PIN}"",
107 | ""clientId"":""{clientId}"",
108 | ""pageId"":""{pageId}""}}
109 | ";
110 | UDPSend(msg);
111 | }
112 |
113 | ///
114 | /// Sets deck and optionally page
115 | ///
116 | /// Target client id
117 | /// deck id
118 | /// page id
119 | public void SetDeck(string clientId, string deckId, string pageId) {
120 | string msg = $@"
121 | {{""command"":""SETDECK"",
122 | ""appName"":""{APP_NAME}"",
123 | ""appPIN"":""{Program.PIN}"",
124 | ""clientId"":""{clientId}"",
125 | ""deckId"":""{deckId}"",
126 | ""pageId"":""{pageId}""}}
127 | ";
128 | UDPSend(msg);
129 | }
130 |
131 | public class SetControlStateItem
132 | {
133 | public string controlId;
134 | public string controlName;
135 | public string state;
136 |
137 | public SetControlStateItem(string _controlId, string state, string _controlName = null)
138 | {
139 | this.controlId = _controlId;
140 | this.state = state;
141 | this.controlName = _controlName;
142 | }
143 | }
144 |
145 | public class VisualStateItem {
146 | public string buttonId;
147 | public string buttonName;
148 | public string state;
149 |
150 | public VisualStateItem(string buttonId, string state, string buttonName = null)
151 | {
152 | this.buttonId = buttonId;
153 | this.state = state;
154 | this.buttonName = buttonName;
155 | }
156 | }
157 |
158 | public void SetButtonsVisualState(string clientId, List list) {
159 | string btnList = "";
160 |
161 | for (int i = 0; i < list.Count; i++) {
162 | VisualStateItem item = list[i];
163 | if (i != 0) {
164 | btnList += ",";
165 | }
166 | btnList += $@"{{""buttonId"":""{ item.buttonId}"", ""buttonName"": ""{item.buttonName}"", ""state"":""{item.state}""}}";
167 | }
168 |
169 | string msg = $@"
170 | {{""command"":""SETBUTTONSVISUALSTATE"",
171 | ""appName"":""{APP_NAME}"",
172 | ""appPIN"":""{Program.PIN}"",
173 | ""clientId"":""{clientId}"",
174 | ""data"":[{btnList}]
175 | }}
176 | ";
177 | UDPSend(msg);
178 | }
179 |
180 | public void SetControlsState(string clientId, List list)
181 | {
182 | string ctlList = "";
183 |
184 | for (int i = 0; i < list.Count; i++)
185 | {
186 | SetControlStateItem item = list[i];
187 | if (i != 0)
188 | {
189 | ctlList += ",";
190 | }
191 | ctlList += $@"{{""controlId"":""{ item.controlId}"", ""controlName"": ""{item.controlName}"", ""state"":{item.state}}}";
192 | }
193 |
194 | string msg = $@"
195 | {{""command"":""SETCONTROLSSTATE"",
196 | ""appName"":""{APP_NAME}"",
197 | ""appPIN"":""{Program.PIN}"",
198 | ""clientId"":""{clientId}"",
199 | ""data"":[{ctlList}]
200 | }}
201 | ";
202 | UDPSend(msg);
203 | }
204 |
205 | ///
206 | /// Sends UDP message to Matric server
207 | ///
208 | void UDPSend(string message)
209 | {
210 | byte[] bytes = Encoding.UTF8.GetBytes(message);
211 | udpClient.Send(bytes, bytes.Length, serverEP);
212 | }
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MATRIC Integration API Demo
2 | This project is a simple demo of MATRIC integration API
3 |
4 | MATRIC (https://matricapp.com) can be used as an input device (controlling PC applications from smartphone or tablet) by emulating keyboard and mouse, but can also be used to display data from 3rd party applications by utilizing Integration API.
5 |
6 | Integration API enables 3rd party applications to use MATRIC as an output device. Perhaps it is best illustrated by use-case example:
7 | Let's say we have a flight simulator game, and we are using MATRIC as a virtual cockpit button board. But what if we want to reflect the game state to MATRIC, e.g. we want to indicate remaining fuel or low fuel warning. We can do that using Integration API to push changes to MATRIC deck from our flight sim, e.g. we will change the fuel button text to indicate remaining fuel and maybe set its color to red if the fuel is low.
8 |
9 | ## API Basics
10 |
11 | Integration API uses simple JSON text commands which 3rd party app sends via UDP to matric server (default port for Integration API is 50300 and it always listens on loopback address 127.0.0.1).
12 |
13 | c# API wrapper is also available to make things easier
14 |
15 | ## How to use the demo
16 | Prerequisites:
17 | - Enable integration API by editing /Documents/.matric/config.json, set "EnableIntegrationAPI" to **true**
18 | - Import demo deck (IntegrationDemo.deck) from this repository by double clicking it.
19 |
20 | ## Running the integration demo
21 | 1) Start MATRIC, connect with smartphone/tablet
22 | 2) Start demo
23 | 3) MATRIC will display a popup messsage similar to this one:
24 |
25 | 
26 |
27 | 4) Click Yes on the MATRIC popup and then type the PIN into demo console:
28 |
29 | 
30 |
31 | 5) The demos will run switching the deck on the first connected client to demo deck and dynamically changing button visuals. The demo is not ment to illustrate any programming best practices, instead it is made to be as simple and minimalistic as possible.
32 |
33 | ## Integration API commands (if you do not want to use the convenient .Net wrapper)
34 |
35 | ### Common properties
36 |
37 | | Property | Type | |
38 | |---|---|---|
39 | | command | string | The command we want to execute (see below) |
40 | | appName | string | The name to identify the app sending the integration commands |
41 | | appPIN | string | PIN assigned to app sending the integration commands |
42 | | clientId | string | client Id of the client we want to target. If set to null commands will be sent to all connected clients |
43 |
44 | ### CONNECT
45 |
46 | Triggers authorization popup on PC. User will be prompted to allow access to Integration API to 3rd party application and shown a PIN number which must be entered into 3rd party application. Typically you'd do this only once and save the PIN.
47 |
48 | Example request:
49 |
50 | ```
51 | {
52 | "command":"CONNECT",
53 | "appName":"Integration demo"
54 | }
55 | ```
56 |
57 | ### GETCONNECTEDCLIENTS
58 |
59 | Returns a list of connected clients.
60 |
61 | Example request:
62 |
63 | ```
64 | {
65 | "command":"GETCONNECTEDCLIENTS",
66 | "appName":"Integration demo",
67 | "appPIN":"0186"
68 | }
69 | ```
70 |
71 | Example response:
72 |
73 | ```
74 | [
75 | {"Name":"Joe's Galaxy S10",
76 | "IP":"192.168.8.45",
77 | "Id":"iQyGDYxja7Zm2yuLt9MJ9Yld+aQCVXX60KV71XPpIJA=",
78 | "MatricVersion":2,
79 | "LastContact":"2019-08-29T15:28:38.1185368+02:00"}
80 | ]
81 | ```
82 |
83 | ### SETDECK
84 |
85 | Instructs the client (specified by clientId) to load deck (specified by deckId) and (optionally) switch to page in deck (specified by pageId).
86 |
87 | Example request:
88 |
89 | ```
90 | {
91 | "command":"SETDECK",
92 | "appName":"Integration demo",
93 | "appPIN":"0186",
94 | "clientId":"iQyGDYxja7Zm2yuLt9MJ9Yld+aQCVXX60KV71XPpIJA=",
95 | "deckId":"7f18056c-7a2a-46ac-9956-662e7d0b78ec",
96 | "pageId":"00d9c649-f2df-405f-abfd-06d38f8626be"
97 | }
98 | ```
99 |
100 | ### SETACTIVEPAGE
101 |
102 | Instructs the client to switch to page specified by pageId.
103 |
104 | Example request:
105 |
106 | ```
107 | {
108 | "command":"SETACTIVEPAGE",
109 | "appName":"Integration demo",
110 | "appPIN":"0186",
111 | "clientId":"iQyGDYxja7Zm2yuLt9MJ9Yld+aQCVXX60KV71XPpIJA=",
112 | "pageId":"00d9c649-f2df-405f-abfd-06d38f8626be"
113 | }
114 | ```
115 |
116 | ### SETBUTTONPROPS
117 | Modifies the properties of a button specified by buttonId or buttonName. Note that you can change button visual properties but not it's function. This is behaviour by design. Note also that changes are not persisted, integration commands does not alter the button definition in deck on MATRIC server (PC).
118 |
119 | Example request:
120 |
121 | ```
122 | {
123 | "command":"SETBUTTONPROPS",
124 | "appName":"Integration demo",
125 | "appPIN":"0186",
126 | "clientId":"iQyGDYxja7Zm2yuLt9MJ9Yld+aQCVXX60KV71XPpIJA=",
127 | "buttonId":"cf3cd93c-e43c-4649-9f47-5441555ca7ce",
128 | "buttonName":"BIG_RED_BUTTON",
129 | "data":{
130 | "imageOff": null,
131 | "imageOn": null,
132 | "textcolorOn": null,
133 | "textcolorOff":null,
134 | "backgroundcolorOn": null,
135 | "backgroundcolorOff":"green",
136 | "fontSize":null,
137 | "text":null
138 | }
139 | }
140 | ```
141 |
142 | ### SETBUTTONPROPSEX
143 | Modifies the properties of multiple buttons. Note that you can change button visual properties but not it's function. This is behaviour by design. Note also that changes are not persisted, integration commands does not alter the button definition in deck on MATRIC server (PC).
144 |
145 | IMPORTANT: This method is available in version 1.22 and higher!
146 |
147 | Example request:
148 | ```
149 | {
150 | "appName": "MATRIC4DCS",
151 | "appPin": "9087",
152 | "clientId": "twQd9g6COnWeT7SPaInvcTk2xdvBW7lN8+b+a9QQRfk=",
153 | "command": "SETBUTTONPROPSEX",
154 | "data": [ {
155 | "buttonId": "7eec29e4-1f59-47d2-bdd5-9b599d375fc9",
156 | "imageOff": "8e7b4b9f-3e18-4009-bae1-445b1f3aa81f.png",
157 | "textcolorOff": "white"
158 | }, {
159 | "buttonName": "BIG_RED_ONE",
160 | "imageOff": "8e7b4b9f-3e18-4009-bae1-445b1f3aa81f.png",
161 | "textcolorOff": "white"
162 | }, {
163 | "buttonId": "404e46c7-8b8e-48dd-89dd-276a408fcf4b",
164 | "imageOff": "8e7b4b9f-3e18-4009-bae1-445b1f3aa81f.png",
165 | "textcolorOff": "white"
166 | }, {
167 | "buttonId": "d6c9836c-7986-48bc-b4a8-1cb52407bb5d",
168 | "imageOff": "8e7b4b9f-3e18-4009-bae1-445b1f3aa81f.png",
169 | "textcolorOff": "white"
170 | }, {
171 | "buttonId": "2dee5490-bc3e-4c48-a6d2-144f37800993",
172 | "imageOff": "8e7b4b9f-3e18-4009-bae1-445b1f3aa81f.png",
173 | "textcolorOff": "white"
174 | } ]
175 | }
176 | ```
177 |
178 | ### SETBUTTONSVISUALSTATE
179 | Sets the visual state of multiple buttons defined by their ids or names. It sets predefined properties defined in MATRIC editor for "on" (pressed) and "off" (not pressed). It is easier to use then SETBUTTONPROPS and SETBUTTONPROPSEX as you do not need to define all the properties in the command but instead just set the state to on or off.
180 |
181 | IMPORTANT: This method is available in version 1.26 and higher!
182 |
183 | Example request:
184 | ```
185 | {
186 | "appName": "MATRIC4DCS",
187 | "appPin": "9087",
188 | "clientId": "twQd9g6COnWeT7SPaInvcTk2xdvBW7lN8+b+a9QQRfk=",
189 | "command": "SETBUTTONSVISUALSTATE",
190 | "data": [ {
191 | "buttonId": "7eec29e4-1f59-47d2-bdd5-9b599d375fc9",
192 | "state": "on"
193 | }, {
194 | "buttonName": "BIG_RED_ONE",
195 | "state": off"
196 | }, {
197 | "buttonId": "404e46c7-8b8e-48dd-89dd-276a408fcf4b",
198 | "state": "off"
199 | }, {
200 | "buttonId": "d6c9836c-7986-48bc-b4a8-1cb52407bb5d",
201 | "state": "on"
202 | }]
203 | }
204 | ```
205 |
206 | ### SETCONTROLSSTATE
207 | Sets the state of multiple controls defined by their ids or names.
208 | State object depends on control type:
209 | for buttons : {pressed: boolean}
210 | for sliders: {value: number}
211 | for rotary: {pressed: boolean, value: number}
212 | for rotary encoder: {pressed: boolean}
213 |
214 | IMPORTANT: This method is available in version 2.0 and higher!
215 |
216 | Example request:
217 | ```
218 | {
219 | "appName": "MATRIC4DCS",
220 | "appPin": "9087",
221 | "clientId": "twQd9g6COnWeT7SPaInvcTk2xdvBW7lN8+b+a9QQRfk=",
222 | "command": "SETCONTROLSSTATE",
223 | "data": [ {
224 | "controlId": "7eec29e4-1f59-47d2-bdd5-9b599d375fc9",
225 | "state": {pressed: true}
226 | }, {
227 | "controlName": "SOME_SLIDER",
228 | "state": { value: 50}
229 | }, {
230 | "controlName": "SOME_ROTARY",
231 | "state": { pressed: true, value: 30}
232 | }]
233 | }
234 | ```
235 | State object depends on the control type, given in the table below:
236 | | Control | State object example| Description |
237 | |---------|--------------|-------------|
238 | |Button | {pressed: true } | pressed: set button state to pressed or "normal" |
239 | |Slider | {value: 50} | | value: - integer (0-100) which determines the slider position
240 | |Rotary | {pressed: true, value: 50} | pressed: set button state to pressed or "normal" value: - integer (0-100) which determines the slider position |
241 | |Multi position switch | {position: 2} | position: integer specifying switch position. Note position starts from 1 |
242 | |Encoder| {pressed: true} | pressed: set button state to pressed or "normal" |
243 |
244 | ## Integration API .Net wrapper
245 |
246 | .Net wrapper is made to make integration with .Net applications easier, please refer to [C# demo](demos/net_wrapper).
247 | A more detailed reference will be available soon.
248 |
--------------------------------------------------------------------------------
/demos/net_wrapper/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading;
4 | using Matric.Integration;
5 |
6 | namespace IntegrationDemo {
7 |
8 |
9 | class Program {
10 |
11 | public static string DEMO_DECK_ID = CONST.DEMO_DECK_ID;
12 | public static string PIN = CONST.PIN;
13 | public static string CLIENT_ID;
14 | static Matric.Integration.Matric matric;
15 |
16 | static void Main(string[] args)
17 | {
18 | Console.Title = "MATRIC Integration Demo .Net";
19 | //Console.WriteLine("Authorize connection in MATRIC, then enter PIN:");
20 | //New using integration library
21 | matric = new Matric.Integration.Matric(CONST.APP_NAME, CONST.PIN, CONST.API_PORT);
22 | //matric.RequestAuthorizePrompt();
23 | //PIN = Console.ReadLine();
24 | matric.PIN = PIN;
25 | matric.OnError += Matric_OnError;
26 | matric.OnConnectedClientsReceived += Matric_OnConnectedClientsReceived;
27 | matric.OnControlInteraction += Matric_OnControlInteraction;
28 | matric.OnVariablesChanged += Matric_OnVariablesChanged;
29 | Console.WriteLine("Press any key to start demo");
30 | Console.ReadKey();
31 | Console.WriteLine("Trying to get connected clients");
32 | matric.GetConnectedClients();
33 | Console.WriteLine("Press any key to exit");
34 | Console.ReadKey();
35 | }
36 |
37 | private static void Matric_OnVariablesChanged(object sender, ServerVariablesChangedEventArgs data) {
38 | Console.WriteLine("Server variables changed");
39 | foreach (string varName in data.ChangedVariables) {
40 | Console.WriteLine($"{varName}: {data.Variables[varName].Value}");
41 | }
42 | }
43 |
44 | private static void Matric_OnError(Exception ex)
45 | {
46 | Console.WriteLine(ex.Message);
47 | }
48 |
49 | private static void Matric_OnControlInteraction(object sender, object data)
50 | {
51 | Console.WriteLine("Control interaction:");
52 | Console.WriteLine(data.ToString());
53 | }
54 |
55 | private static void Matric_OnConnectedClientsReceived(object source, List clients) {
56 | UpdateClientsList(clients);
57 | }
58 |
59 | private static void StartDemo() {
60 | string GRAY = "#111111";
61 | string YELLOW = "yellow";
62 | string GREEN = "green";
63 | string RED = "red";
64 | string BLACK = "black";
65 | string WHITE = "white";
66 |
67 | ServerVariable vString = new ServerVariable() {
68 | Name = "demo_string",
69 | VariableType = ServerVariable.ServerVariableType.STRING,
70 | Value = "Initial string"
71 | };
72 | ServerVariable vBool = new ServerVariable() {
73 | Name = "demo_bool",
74 | VariableType = ServerVariable.ServerVariableType.BOOL,
75 | Value = true
76 | };
77 | ServerVariable vNumber = new ServerVariable() {
78 | Name = "demo_number",
79 | VariableType = ServerVariable.ServerVariableType.NUMBER,
80 | Value = 1
81 | };
82 | ServerVariable vJsonObject = new ServerVariable() {
83 | Name = "demo_number",
84 | VariableType = ServerVariable.ServerVariableType.JSONOBJECT,
85 | Value = @"{""propNumber"":""1"", ""propString"":""Hello from demo""}"
86 | };
87 |
88 | List variables = new List() {
89 | vString, vBool, vNumber, vJsonObject
90 | };
91 |
92 | matric.SetVariables(variables);
93 | Thread.Sleep(5000);
94 | vString.Value = "New value...";
95 | vBool.Value = !((bool)vBool.Value);
96 | vNumber.Value = ((int)vNumber.Value) + 1;
97 | vJsonObject.Value = @"{""propNumber"":""999"", ""propString"":""Is it working?""}";
98 | matric.SetVariables(variables);
99 | Thread.Sleep(5000);
100 |
101 | matric.SetDeck(CLIENT_ID, DEMO_DECK_ID, DemoPages.SEMAPHORE);
102 | Thread.Sleep(800);
103 |
104 | List listOn = new List();
105 | //we will refer to the buttons by name rather then id
106 | listOn.Add(new SetButtonsVisualStateArgs(state:"on", buttonName: "BTN_GREEN"));
107 | listOn.Add(new SetButtonsVisualStateArgs(state:"on", buttonName: "BTN_YELLOW"));
108 | listOn.Add(new SetButtonsVisualStateArgs(state:"on", buttonName: "BTN_RED"));
109 |
110 | List listOff = new List();
111 | listOff.Add(new SetButtonsVisualStateArgs(state:"off", buttonName: "BTN_GREEN"));
112 | listOff.Add(new SetButtonsVisualStateArgs(state:"off", buttonName: "BTN_YELLOW"));
113 | listOff.Add(new SetButtonsVisualStateArgs(state:"off", buttonName: "BTN_RED"));
114 |
115 | matric.SetButtonsVisualState(CLIENT_ID, listOn);
116 | Thread.Sleep(300);
117 | matric.SetButtonsVisualState(CLIENT_ID, listOff);
118 | Thread.Sleep(300);
119 | matric.SetButtonsVisualState(CLIENT_ID, listOn);
120 | Thread.Sleep(300);
121 | matric.SetButtonsVisualState(CLIENT_ID, listOff);
122 | Thread.Sleep(300);
123 | matric.SetButtonsVisualState(CLIENT_ID, listOn);
124 | Thread.Sleep(300);
125 | matric.SetButtonsVisualState(CLIENT_ID, listOff);
126 |
127 |
128 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: GREEN, buttonName: "BTN_GREEN");
129 | Thread.Sleep(800);
130 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: GRAY, buttonName: "BTN_GREEN");
131 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: YELLOW, buttonName: "BTN_YELLOW");
132 | Thread.Sleep(800);
133 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: GRAY, buttonName: "BTN_GREEN");
134 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: GRAY, buttonName: "BTN_YELLOW");
135 | matric.SetButtonProperties(CLIENT_ID, backgroundcolorOff: RED, buttonName: "BTN_RED");
136 | Thread.Sleep(800);
137 | matric.SetButtonProperties(CLIENT_ID, fontSize: "10", buttonName: "BTN_GREEN");
138 | Thread.Sleep(500);
139 | matric.SetButtonProperties(CLIENT_ID, fontSize: "20", buttonName: "BTN_GREEN");
140 | Thread.Sleep(500);
141 | matric.SetButtonProperties(CLIENT_ID, fontSize: "30", buttonName: "BTN_GREEN");
142 | Thread.Sleep(500);
143 | matric.SetButtonProperties(CLIENT_ID, fontSize: "40", buttonName: "BTN_GREEN");
144 | Thread.Sleep(500);
145 |
146 | matric.SetButtonPropertiesEx(null, new List {
147 | new SetButtonPropsArgsEx
148 | {
149 | text="RED!!!", ButtonName = "BTN_RED"
150 | },
151 | new SetButtonPropsArgsEx
152 | {
153 | text="YELLOW!!!", ButtonName = "BTN_YELLOW"
154 | },
155 | new SetButtonPropsArgsEx
156 | {
157 | text="GREEN!!!", ButtonName = "BTN_GREEN"
158 | }
159 | });
160 | Thread.Sleep(2000);
161 | matric.SetActivePage(CLIENT_ID, DemoPages.SHIELDS_AND_WEAPONS);
162 | Thread.Sleep(1500);
163 | matric.SetControlsState(null, new List {
164 | new SetControlsStateArgs
165 | {
166 | ControlId=null, ControlName="MULTI_POS_5", State = new { position = 5}
167 | }
168 | });
169 | //simulate battle
170 | int ammo = 500;
171 | int shields = 100;
172 | for (int i = 0; i < 100; i++) {
173 | matric.SetControlsState(null, new List {
174 | new SetControlsStateArgs
175 | {
176 | ControlId=null, ControlName="SHIELDS_SLIDER", State = new { value = shields}
177 | }
178 | });
179 | if (shields < 30)
180 | {
181 | matric.SetControlsState(null, new List {
182 | new SetControlsStateArgs
183 | {
184 | ControlId=null, ControlName="MULTI_POS_5", State = new { position = 3}
185 | }
186 | });
187 | matric.SetButtonProperties(CLIENT_ID, buttonName:"SHIELDS_CRITICAL", textcolorOff: BLACK, backgroundcolorOff: RED);
188 | matric.SetButtonProperties(CLIENT_ID, buttonName:"SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: RED, text: $@"{shields}%");
189 | }
190 | else if (shields < 50)
191 | {
192 | matric.SetControlsState(null, new List {
193 | new SetControlsStateArgs
194 | {
195 | ControlId=null, ControlName="MULTI_POS_5", State = new { position = 4}
196 | }
197 | });
198 | matric.SetButtonProperties(CLIENT_ID, buttonName: "SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: YELLOW, text: $@"{ shields}%");
199 | }
200 | else {
201 | matric.SetButtonProperties(CLIENT_ID, buttonName: "SHIELDS_PERCENT", backgroundcolorOff: GRAY, textcolorOff: GREEN, text: $@"{ shields}%");
202 | }
203 | matric.SetButtonProperties(CLIENT_ID, buttonName: "AMMO_COUNT", backgroundcolorOff: GRAY, textcolorOff: WHITE, text: $@"{ ammo}");
204 | shields--;
205 | ammo = ammo -5;
206 | Thread.Sleep(100);
207 | }
208 |
209 | //flash critical shields
210 | matric.SetControlsState(null, new List {
211 | new SetControlsStateArgs
212 | {
213 | ControlId=null, ControlName="MULTI_POS_5", State = new { position = 2}
214 | }
215 | });
216 | bool criticalOn = true;
217 | for (int i = 0; i < 10; i++) {
218 | if (criticalOn)
219 | {
220 | matric.SetButtonProperties(CLIENT_ID, buttonName: "SHIELDS_CRITICAL", textcolorOff: GRAY, backgroundcolorOff: BLACK);
221 | }
222 | else {
223 | matric.SetButtonProperties(CLIENT_ID, buttonName: "SHIELDS_CRITICAL", textcolorOff: GRAY, backgroundcolorOff: RED);
224 | }
225 | criticalOn = !criticalOn;
226 | Thread.Sleep(400);
227 | }
228 |
229 | matric.SetActivePage(CLIENT_ID, DemoPages.DEMO_COMPLETE);
230 | Thread.Sleep(1000);
231 | matric.SetButtonProperties(CLIENT_ID, buttonName: "WINK_BUTTON", text: CONST.SMILE_WINK);
232 | Console.WriteLine("Demo complete");
233 |
234 | }
235 |
236 |
237 | public static void UpdateClientsList(List connectedClients) {
238 | if (connectedClients.Count == 0)
239 | {
240 | Console.WriteLine("No connected devices found, make sure your smartphone/tablet is connected\nPress any key to exit");
241 | Console.ReadKey();
242 | Environment.Exit(0);
243 | }
244 | Console.WriteLine("Found devices:");
245 | foreach (ClientInfo client in connectedClients)
246 | {
247 | Console.WriteLine($@"{client.Id} {client.Name}");
248 | }
249 | CLIENT_ID = connectedClients[0].Id;
250 | Console.WriteLine("Starting demo on first device");
251 | StartDemo();
252 | }
253 | }
254 | }
255 |
--------------------------------------------------------------------------------