Originally, I wanted to make Part 4 similar to the program in Part 3, just showing how to do it with a DMPS instead. But testing it means I have to get a DMPS setup in my lab and I don’t feel like doing that just yet. So instead, we’ll take a step back and look at how to gather information about the processor we’re running on.
Add a new project to the current solution by right clicking in the solution explorer and selecting Add > New Project.

Name this new project Part4:

Trim ControlSystem.cs back to its essentials:
using System;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharpPro.Diagnostics;
using Crestron.SimplSharpPro.DeviceSupport;
namespace Part4
{
public class ControlSystem : CrestronControlSystem
{
public ControlSystem()
: base()
{
try
{
Thread.MaxNumberOfUserThreads = 20;
}
catch (Exception e)
{
ErrorLog.Error("Error in ControlSystem constructor: {0}", e.StackTrace);
}
}
public override void InitializeSystem()
{
try
{
}
catch (Exception e)
{
ErrorLog.Error("Error in InitializeSystem: {0}", e.StackTrace);
}
}
}
}
If you press Shift+F6, it will only compile the current project (Part4) instead of the whole solution (Part3 and Part4). So far so good! It would be nice if we could add some ways to debug our program while it’s running. We can’t use SIMPL Debugger (since we’re not programming SIMPL anymore), and getting the Visual Studio debugger connected to our processor is a topic we’ll save for later (probably around Part 9 or so). In the meantime, lets add some console commands so we can request information on the spot. Update InitializeSystem with the following:
public override void InitializeSystem()
{
try
{
if (!CrestronConsole.AddNewConsoleCommand(ControlSystemInfo,
"controllerinfo", "Print information about this control system",
ConsoleAccessLevelEnum.AccessOperator))
{
ErrorLog.Error("Unable to add 'controllerinfo' command to console");
}
}
catch (Exception e)
{
ErrorLog.Error("Error in InitializeSystem: {0}", e.StackTrace);
}
}
Here we’re adding a new controllerinfo
command that will call the ControlSystemInfo method. We give a short help text and specify that users only need to have Operator access level to run it. Now we need to define the ControlSystemInfo method just below:
public void ControlSystemInfo(string parms)
{
if (parms == "?")
{
CrestronConsole.ConsoleCommandResponse("CONTROLLERINFO\n\r\tNo parameters needed.\n\r");
}
else
{
}
}
Also note that we’re using the ConsoleCommandResponse method instead of PrintLine. This will print to the console as a response to the command we issued. The line endings are a little different from PrintLine, too. You’ll notice we have to use \n\r
to move the cursor to a newline and restore it to the left column. parms
is a string with all the parameters passed in that the user types after our command. We’ll check to see if they requested help ("?"
)and respond that this command doesn’t take any arguments.
What things do we want to know about our processor? First off, maybe which one it is. Also, every processor I can think of has at least 1 serial and 1 IR output port on it, but it would be nice to know how many:
public void ControlSystemInfo(string parms)
{
if (parms == "?")
{
CrestronConsole.ConsoleCommandResponse("CONTROLLERINFO\n\r\tNo parameters needed.\n\r");
}
else
{
CrestronConsole.ConsoleCommandResponse("Controller prompt: {0}\n\r", this.ControllerPrompt);
CrestronConsole.ConsoleCommandResponse("Number of serial ports: {0}\n\r", this.NumberOfComPorts);
CrestronConsole.ConsoleCommandResponse("Number of IR ports: {0}\n\r", this.NumberOfIROutputPorts);
}
}
Build this program, upload to your processor, and type in the controllerinfo
command in Text Console:

But some controllers have different device support built-in. For example, the MC3 has a built-in RF gateway. The DMPS series has a built-in switcher. How do we detect if we have access to those features? Add the following code:
public void ControlSystemInfo(string parms)
{
if (parms == "?")
{
CrestronConsole.ConsoleCommandResponse("CONTROLLERINFO\n\r\tNo parameters needed.\n\r");
}
else
{
CrestronConsole.ConsoleCommandResponse("Controller prompt: {0}\n\r", this.ControllerPrompt);
CrestronConsole.ConsoleCommandResponse("Number of serial ports: {0}\n\r", this.NumberOfComPorts);
CrestronConsole.ConsoleCommandResponse("Number of IR ports: {0}\n\r", this.NumberOfIROutputPorts);
if (this.SupportsRelay)
CrestronConsole.ConsoleCommandResponse("Number of relay ports: {0}\n\r", this.NumberOfRelayPorts);
if (this.SupportsDigitalInput)
CrestronConsole.ConsoleCommandResponse("Number of digital inputs: {0}\n\r", this.NumberOfDigitalInputPorts);
if (this.SupportsVersiport)
CrestronConsole.ConsoleCommandResponse("Number of versiports: {0}\n\r", this.NumberOfVersiPorts);
CrestronConsole.ConsoleCommandResponse("Internal RF Gateway: {0}\n\r", this.SupportsInternalRFGateway ? "YES" : "NO");
// Check if built-in DM switcher
if (this.SystemControl != null)
{
CrestronConsole.ConsoleCommandResponse("System ID: {0}\n\r", this.SystemControl.SystemId);
if (this.SupportsSwitcherInputs)
CrestronConsole.ConsoleCommandResponse("Number of switcher inputs: {0}\n\r", this.NumberOfSwitcherInputs);
if (this.SupportsSwitcherOutputs)
CrestronConsole.ConsoleCommandResponse("Number of switcher outputs: {0}\n\r", this.NumberOfSwitcherOutputs);
}
}
}
We add checks to see if our controller supports certain hardware by checking Boolean properties (i.e.: SupportsRelay, SupportsDigitalInput, SupportsVersiport, etc). Detecting if we’re running on a DMPS is similar, but we first check to see if the SystemControl member is defined. Then we can similarly check SupportsSwitcherInputs and SupportsSwitcherOutputs. Our new results:

And if we run the same program on a CP3, we get similar results:

I guess I’ll get that DMPS setup now since the next part will need it anyway:

I’m not exactly sure why I get Unsupported Sig.
for System ID, that might be something to explore further. Checking Ethernet Settings in EasyConfig, I see it’s set to 1.
And this is the value of adding the ControlSystemInfo method, we can inspect values at run-time, as long as we add code to do it. We could probably come up with a more general way to inspect what’s going on in our program, but for now this is a good start. We’ll continue adding custom commands to help us debug in future parts as well.
Summary
In this part we covered:
- Adding console commands to Text Console
- Debugging without needing to go through Visual Studio’s debugger
- Checking for various hardware support at run-time
- How to tell if we’re running on a DMPS or not
See you next time when we start building a standard conference room program. It will take several parts to complete. And as always, source code is available on GitHub: https://github.com/kielthecoder/SimplSharpPrimer