virtual protected void DisconnectADM(String port, String nodeID = null) { if (PortSharing) { //when using a shared port we connect all the boards in one go var ar = nodeID == null?RequiredBoards.Split(',') : new String[] { nodeID }; foreach (String nid in ar) { String key = port + ":" + nid; if (!ADMS.ContainsKey(key)) { continue; } Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::DisconnectADM: Attempting to disconnect board @ {0}", key); ArduinoDeviceManager adm = ADMS[key]; if (adm != null) { adm.Disconnect(); } ADMS.Remove(key); _devicesConnected.Remove(key); Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::DisconnectADM: Disconnected board @ {0}", key); } } else { if (!ADMS.ContainsKey(port)) { return; } ArduinoDeviceManager adm = ADMS[port]; if (adm != null) { adm.Disconnect(); } ADMS.Remove(port); _devicesConnected.Remove(port); Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::DisconnectADM: Board {0} on port {1} disconnected", adm.BoardID, port); Broadcast(ADMEvent.DISCONNECTED, String.Format("{0} disconnected from port {1}", adm.BoardID, port)); } }
virtual protected void ConnectADM(String port, String nodeID = null) { //turn off the sampler ... it will start again when all boards have been connected Sampler.Stop(); if (PortSharing) { if (RequiredBoards == null) { throw new Exception("If using a shared port, 'Nodes' on the port must be specified as the 'RequiredBoards' property"); } //when using a shared port we connect all the boards in one go var boards = nodeID == null?RequiredBoards.Split(',') : new String[] { nodeID }; List <Exception> exs = new List <Exception>(); foreach (String nid in boards) { String key = port + ":" + nid; if (ADMS.ContainsKey(key)) { continue; } try { //now proceed to connect ADMS[key] = null; //reserve a place (cos the connection process takes a while) Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::ConnectADM: Attempting to connect board @ {0}", key); ArduinoDeviceManager adm = ArduinoDeviceManager.Connect(nid, port, BaudRate, TryHandleADMMessage); adm.Sampler = Sampler; adm.Tracing = Tracing; ADMS[key] = adm; _devicesConnected[key] = false; Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::ConnectADM: Connected to board @ {0}", key); Broadcast(ADMEvent.CONNECTED, String.Format("ADM now Connected @ {0}", key)); //Wait here (i.e. before connecting to another board) until the adm is of status device connected while (!adm.DevicesConnected) { System.Threading.Thread.Sleep(1000); } } catch (Exception e) { ADMS.Remove(key); //TODO: remove the trace and create a single 'aggregate' exception and throw that after th eloop Tracing?.TraceEvent(TraceEventType.Error, 100, "ADMService::ConnectADM: Error connection to board @ {0}: {1}", key, e.Message); exs.Add(e); } } //end loop of all required boards } else { String key = port; if (ADMS.ContainsKey(key)) { throw new Exception("ADMService::ConnectADM: port " + port + " already has an assigned ADM"); } Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::ConnectADM: Attempting to connect board on {0} port {0}", port); try { ADMS[key] = null; //reserve a place (cos the connection process takes a while) //now connct ArduinoDeviceManager adm = ArduinoDeviceManager.Connect(port, BaudRate, TryHandleADMMessage); adm.Sampler = Sampler; adm.Tracing = Tracing; ADMS[key] = adm; _devicesConnected[key] = false; Tracing?.TraceEvent(TraceEventType.Information, 100, "ADMService::ConnectADM: Connected to board on port {0}", port); Broadcast(ADMEvent.CONNECTED, String.Format("Connected ADM to port {0}", port)); } catch (Exception e) { ADMS.Remove(key); //TODO: remove the trace and create a single 'aggregate' exception and throw that after th eloop Tracing?.TraceEvent(TraceEventType.Error, 100, "ADMService::ConnectADM: Error connection to board @ {0}: {1}", key, e.Message); } } }
override public bool HandleCommand(Connection cnn, Message message, String cmd, List <Object> args, Message response) { bool respond = true; MessageSchema schema = new ADMService.MessageSchema(response); DeviceManager devMgr; ArduinoDeviceManager adm; switch (cmd) { case "status": schema.AddADMS(ADMS); List <String> ports = ArduinoDeviceManager.GetBoardPorts(SupportedBoards, AllowedPorts, DeniedPorts); schema.AddPorts(ports); schema.AddRequiredBoards(RequiredBoards); devMgr = DeviceManager.GetInstance(); List <String> portDevices = new List <String>(); foreach (String port in ports) { List <DeviceManager.DeviceInfo> devs = devMgr.GetDevices("(" + port + ")"); foreach (DeviceManager.DeviceInfo devInfo in devs) { String s = String.Format("{0} ({1}): {2}", devInfo.Description, devInfo.InstanceID, devInfo.Status); portDevices.Add(s); } } response.AddValue("PortDevices", portDevices); break; case "disable-port": case "enable-port": case "reset-port": if (args.Count != 1 || args[0] == null || args[0].ToString() == String.Empty) { throw new Exception("No port specified"); } String devicePort = args[0].ToString().ToUpper(); devMgr = DeviceManager.GetInstance(); List <DeviceManager.DeviceInfo> ar = devMgr.GetDevices("(" + devicePort + ")"); if (ar.Count != 1) { throw new Exception("Cannot find device on port " + devicePort); } DeviceManager.DeviceInfo di = ar[0]; //first we check if there is an ADM on this port String output = ""; lock (_lockMonitorADM) { if (ADMS.ContainsKey(devicePort)) { output += String.Format("Found ADM on port {0} so disconnecting first", devicePort) + Environment.NewLine; DisconnectADM(devicePort); System.Threading.Thread.Sleep(500); if (SerialPorts.IsOpen(devicePort)) { throw new Exception("Serial port is open on " + devicePort); } } Process proc = null; if (cmd == "disable-port") { proc = devMgr.DisableDevice(di.InstanceID); } else if (cmd == "enable-port") { proc = devMgr.EnableDevice(di.InstanceID); } else { proc = devMgr.ResetDevice(di.InstanceID); } output += proc.StandardOutput.ReadToEnd(); } response.Value = output; break; default: var tgtcmd = cmd.Split(':'); if (tgtcmd.Length < 2) { throw new Exception(String.Format("ADM: Unrecognised command {0}", cmd)); } //Check that there are any boards connected if (ADMS.Count == 0) { throw new Exception("ADM: No boards connected"); } //so this is an ADM command, find the board first adm = GetADM(tgtcmd[0]); if (adm == null) { throw new Exception(String.Format("ADM: Cannot find ADM {0}", tgtcmd[0])); } if (!adm.IsConnected) { throw new Exception(String.Format("ADM: {0} is not conntected", adm.BoardID)); } //handle commands related to the board (i.e. not to a specific added device) if (tgtcmd.Length == 2) { int repeat; //frequently used var name int delay; //frequently used var name switch (tgtcmd[1].ToLower()) { case "status": AddADMRequest(adm, adm.RequestStatus(), response.Target); respond = false; break; case "ping": AddADMRequest(adm, adm.Ping(), response.Target); respond = false; break; case "pingloadtest": repeat = args != null && args.Count > 0 ? System.Convert.ToInt16(args[0]) : 10; delay = args != null && args.Count > 1 ? System.Convert.ToInt16(args[1]) : 500; Task.Run(() => { for (int i = 0; i < repeat; i++) { adm.Ping(); System.Threading.Thread.Sleep(delay); } }); respond = false; break; case "capability": var lbc = adm.ListBoardCapability(); response.AddValue("PinCount: ", lbc.Count); response.AddValue("Pins", lbc); break; case "disconnect": DisconnectADM(adm.Port); break; case "setdigitalpin": if (args.Count < 2) { throw new Exception("Insufficient arguments ... must supply a pin number and value"); } int pin = System.Convert.ToInt16(args[0]); bool val = Chetch.Utilities.Convert.ToBoolean(args[1]); if (!adm.IsPinCapable(pin, Solid.Arduino.Firmata.PinMode.DigitalOutput)) { throw new Exception(String.Format("Pin {0} is not capabale of digital output", pin)); } if (adm.GetDevicesByPin(pin) != null) { throw new Exception(String.Format("Pin {0} is being used by a device", pin)); } adm.SetDigitalPinMode(pin, Solid.Arduino.Firmata.PinMode.DigitalOutput); adm.SetDigitalPin(pin, val); break; case "setdigitalport": if (args.Count < 2) { throw new Exception("Insufficient arguments ... must supply a port number and value"); } int port = System.Convert.ToInt16(args[0]); bool enable = Chetch.Utilities.Convert.ToBoolean(args[1]); adm.SetDigitalReportMode(port, enable); //adm.G break; case "list-devices": schema.AddDevices(adm.GetDevices()); break; case "list-pins": break; default: throw new Exception(String.Format("No ADM direct command {0}", tgtcmd[1])); } } else { //handle command specific to device try { respond = HandleADMDeviceCommand(adm, tgtcmd[1], tgtcmd[2], args, response); } catch (Exception e) { Tracing?.TraceEvent(TraceEventType.Error, 0, "Exception: {0}", e.Message); throw e; } } if (response.Value == null || response.Value == String.Empty) { response.Value = "Handled " + cmd; } break; } return(respond); }