Exemplo n.º 1
0
        /// <summary>
        /// Called by a timer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        protected virtual void MonitorADM(Object sender, ElapsedEventArgs eventArgs)
        {
            _admtimer.Stop();

            try
            {
                lock (_lockMonitorADM)
                {
                    //get all current ports that have boards connected
                    List <String> ports = ArduinoDeviceManager.GetBoardPorts(SupportedBoards, AllowedPorts, DeniedPorts);

                    //build a list of any ADMs that are no longer connected to one of these ports (e.g. USB has been yanked out)
                    List <ArduinoDeviceManager> adms = ADMS.Values.ToList();
                    foreach (ArduinoDeviceManager adm in adms)
                    {
                        if (adm == null)
                        {
                            continue;
                        }

                        if (!ports.Contains(adm.Port))
                        {
                            //if for some reason (config change?) the port for the ADM is not a possible board port
                            DisconnectADM(adm.Port);
                        }
                    }

                    //now we try and connect all the boards that we have not just disconnected but have not yet been connected
                    if (ports.Count > 0 && ADMS.Count < RequiredBoardsCount)
                    {
                        _noPortsFoundWarning = false;
                        foreach (String port in ports)
                        {
                            try
                            {
                                ConnectADM(port);
                            }
                            catch (System.IO.IOException e)
                            {
                                switch (e.HResult)
                                {
                                case Win32.ERROR_ATTACHED_DEVICE_NOT_FUNCTIONING:
                                    ResetPort(port, e);
                                    break;
                                }
                                Tracing?.TraceEvent(TraceEventType.Error, 100, "ADMService::MonitorADM: Connecting ADM to port {0} produced IOException {1} ({2}): {3}", port, e.GetType().ToString(), e.HResult, e.Message);
                            }
                            catch (Exception e)
                            {
                                Tracing?.TraceEvent(TraceEventType.Error, 100, "ADMService::MonitorADM: Connecting ADM to port {0} produced Exception {1} ({2}): {3}", port, e.GetType().ToString(), e.HResult, e.Message);
                            }
                        }
                    }
                    else if (ADMS.Count < RequiredBoardsCount)
                    {
                        if (!_noPortsFoundWarning)
                        {
                            Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADMService::MonitorADM: No boards connected to any port");
                            _noPortsFoundWarning = true;
                        }
                    }


                    //Finally we check on the state of the ADM
                    foreach (ArduinoDeviceManager adm in adms)
                    {
                        if (adm == null)
                        {
                            continue;
                        }

                        if (!adm.IsConnected)
                        {
                            //TODO: how do we handle this?
                            Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADM (BDID={0}) @ {1} is of state", adm.State);
                        }
                        else if (ADMInactivityTimeout > 0)
                        {
                            //if there has been a suspicioius lack of activity...
                            long msQuiet = (DateTime.Now.Ticks - adm.LastMessageReceivedOn.Ticks) / TimeSpan.TicksPerMillisecond;
                            if (msQuiet > ADMInactivityTimeout)
                            {
                                OnADMInactivityTimeout(adm, msQuiet);
                            }
                        }
                    }
                } //end of monitor lock
            } catch (Exception e)
            {
                Tracing?.TraceEvent(TraceEventType.Error, 100, "Unknown exception in MonitorADM: {0}, {1}", e.GetType().ToString(), e.Message);
            }

            _admtimer.Start();
        }
Exemplo n.º 2
0
        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);
        }