The .NET/Mono/NETMF Monitor and Command is a Visual Studio solution hosted on Codeplex building client/server libraries providing "monitor and command" messaging for embedded projects using .NET/NETMF/Mono. The intent is to make it easy for a .NET engineer to develop PC/Tablet/Phone UIs to monitor and command embedded projects using Mono (e.g. Raspberry Pi) or NETMF (e.g. FEZ, Gadgeteer, Netduino).
Following the acquisition of Xamarin by Microsoft and the integration of the Xamarin toolset into Visual Studio, the solution has been upgraded to VS2015 Community Edition to allow developers to reference the .NET client library in applications targeting Android & iOS devices.
C++/Wiring client code for Particle's Photon is available on GitHub.
Client devices publish and subscribe to commands and data routed by the Server among devices, based on a routing table built from all subscriptions and publications. Clients can be any PC/device supporting .NET/Mono, NETMF, Windows Phone 8, Windows 8, or C++/Wiring. Server can be any PC/device supporting .NET/Mono.
Extending the server's functionalityThe server's functionality can be extended through inheritance to had special processing of the messages after the routing functionality. This can be used, for instance, to define state machines that will, based on the messages received, compute states and trigger commands sent to the connected devices.
DemonstrationIn the video:
- A Raspberry Pi 2 with Mono installed runs the .NET/Mono server;
- Three Photons running C++/Wiring client code subscribe to commands acting on the states of their RGB, green and red LEDs and publish the corresponding states, as well temperature/humidity measures generated by a DHT11;
- Windows and Android phones publish commands acting on the states of the Photons' RGB, green and red LEDs;
- Phones and Surface RT tablet subscribe to the states of the Photons' RGB, green and red LEDS and temperature/humidity measures;
- a Raspberry Pi with a Pibrella board subscribes to a state computed by the server based on the number of lighted on red LEDs, resulting in commands to control the board's green, yellow and red LEDs.
For a given LED, the monitor/command process is fairly simple:
- Photon X publishes data "
LEDStatus
" and subscribes to Command "ToggleLED
";
- Phone Y publishes command "
ToggleLED
" and subscribes to data "LEDStatus
";
- Reacting on a UI event, phone Y sends command "
ToggleLED
" to photon X;
- Photon X receives command "
ToggleLED
" and acts on it, changing the LED's state;
- Photon X sends data "
LEDStatus
" new state/value;
- Phone Y receives data "
LEDStatus
" and acts on it, for instance displaying it on the UI.
The same process can be used to monitor/command any discrete or continuous parameter of your devices.
Other demonstration videos are available on YouTube and the code running those video is available in the solution.
The .NET/Mono serverThe server is running on a Raspberry Pi 2 having Mono installed. It's a simple console application referencing the Core.Server library from the VS2015CE solution started with the following command.
> nohup sudo mono ServerConsole.exe &
Internally, we just instantiate a MessageListener
class and call its StartListening()
method.
MessageListener messageListener = new MessageListener(ipAddress, portNumber, isMessageServiceActivated);
messageListener.StartListening();
The C++/Wiring client for PhotonPhotons connect and register to the server using the MCClient class available on GitHub.
MCClient* client = new MCClient(&tcpClient);
if (client->Connect(IPfromBytes, portNumber)) {
client->Register(DeviceName);
...
}
They then publish/subscribe data and command, as follows:
client->SubscribeToCommand("*", "RedLED", "ToggleLED");
client->PublishData("*", "RedLED", "LEDStatus");
Once done, inside the loop()
function, they pool the TCPBuffer to extract received messages.
void loop() {
...
int result = client->ProcessTCPBuffer();
if (result == MCClient::BUFFER_READY) {
//When a message is available, we process it
message = client->Receive();
if (message != NULL) {
ProcessReceivedMessage();
...
}
...
}
If any message is received, it's extracted and processed, for instance to change the state of the RGB or green/red LEDs. If changed successfully, they send back the corresponding data to the server, that will route them to the subscribing devices.
client->SendData("*", "RedLED", "LEDStatus", redLEDIsOn ? "On" : "Off");
The .NET/Mono/NETMF & WindowsPhone/Windows8 client librariesSimilarly, the Surface RT tablet and Windows and Android phones connect and register to the server using similar methods.
Client = new MessageClient(Devices.ANDROID_PHONE);
Client.DataReceived += Client_DataReceived;
Client.Start(ipAddress, portNumber);
They subscribe to data and publish commands for the Photons.
Client.SubscribeToData(PHOTON_A, Photon.OBJECT_RED_LED, Photon.DATA_LED_STATUS);
Client.PublishCommand(PHOTON_A, Photon.OBJECT_RED_LED, Photon.COMMAND_TOGGLE_LED);
Based on some user's action on the phones UIs, the send commands to the Photons.
Client.SendCommand(deviceName, objectName, Photon.COMMAND_TOGGLE_LED, String.Empty);
Is the command is successfully received and executed, they receive back from the Photons data they can use to update their UIs.
protected void Client_DataReceived(object sender, MessageEventArgs e)
{
Models.Message message = new Models.Message(e.SendingDevice, e.FromDevice, e.ToDevice, e.ContentType, e.Name, e.Parameter, e.Content);
receivedMessages.Enqueue(message);
}
Comments
Please log in or sign up to comment.