예제 #1
0
        virtual protected bool HandleADMDeviceCommand(ArduinoDeviceManager adm, String deviceID, String command, List <Object> args, Message response)
        {
            if (adm == null)
            {
                throw new Exception("No ADM provided");
            }

            if (!adm.HasDevice(deviceID))
            {
                throw new Exception(String.Format("Device {0} has not been added to ADM", deviceID));
            }

            bool          respond = true;
            ArduinoDevice device  = null;
            MessageSchema schema  = new ADMService.MessageSchema(response);

            switch (command)
            {
            case "list-commands":
                device = adm.GetDevice(deviceID);
                schema.AddDeviceCommands(device);
                break;

            case "status":
                device = adm.GetDevice(deviceID);
                if (device.BoardID == 0)
                {
                    throw new Exception(String.Format("Device {0} does not have a board ID", deviceID));
                }
                AddADMRequest(adm, adm.RequestStatus(device.BoardID), response.Target);
                respond = false;
                break;

            default:
                var commands = command.Split(',');
                foreach (var cmd in commands)
                {
                    var tcmd = cmd.Trim();
                    if (tcmd.ToLower().IndexOf("wait") == 0)
                    {
                        int delay = tcmd.Length > 4 ? System.Convert.ToInt16(tcmd.Substring(4, tcmd.Length - 4)) : 200;
                        System.Threading.Thread.Sleep(delay);
                    }
                    else
                    {
                        byte tag = adm.IssueCommand(deviceID, tcmd, args);
                        if (tag > 0)
                        {
                            AddADMRequest(adm, tag, response.Target);
                            respond = false;
                        }
                    }
                }
                break;
            }
            return(respond);
        }
예제 #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);
        }
예제 #3
0
        virtual protected void HandleADMMessage(ADMMessage message, ArduinoDeviceManager adm)
        {
            switch (message.Type)
            {
            case MessageType.ERROR:
                ErrorCode errCode = message.HasValue("ErrorCode") ? message.GetEnum <ErrorCode>("ErrorCode") : ErrorCode.ERROR_UNKNOWN;
                Tracing?.TraceEvent(TraceEventType.Error, 100, "ADM {0} produced error: {1}", adm.BoardID, errCode);
                switch (errCode)
                {
                case ErrorCode.ERROR_ADM_NOT_INITIALISED:
                    ReconnectADM(adm);
                    break;

                default:
                    //currently do nothing
                    break;
                }
                break;

            case MessageType.WARNING:
                Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADM {0} produced warning: {1}", adm.BoardID, message.Value);
                break;

            case MessageType.STATUS_RESPONSE:
                if (!PortSharing && !IsRequiredBoard(adm.BoardID))
                {
                    Tracing?.TraceEvent(TraceEventType.Warning, 100, "ADM {0} is not one of the required boards ({1}).  Disconnecting from port {2}...", adm.BoardID, RequiredBoards, adm.Port);
                    DisconnectADM(adm.Port);
                    break;
                }

                if (adm.State == ADMState.DEVICE_READY)
                {
                    Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: Ready to add devices to {0} on port {1} ...", adm.BoardID, adm.PortAndNodeID);
                    AddADMDevices(adm, message);
                    Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: {0} devices added to {1} on port {2}. Now configure board", adm.DeviceCount, adm.BoardID, adm.PortAndNodeID);
                    adm.Configure();
                }
                else if (adm.State == ADMState.DEVICE_CONNECTED)
                {
                    if (message.HasValue("Initialised") && !message.GetBool("Initialised"))
                    {
                        //Console.WriteLine("Whoa ... {0} has reset without us knowing", adm.PortAndNodeID);
                    }
                }
                break;

            case MessageType.CONFIGURE_RESPONSE:
                String key = adm.PortAndNodeID;
                if (adm.State == ADMState.DEVICE_CONNECTED && !_devicesConnected[key])
                {
                    Tracing?.TraceEvent(TraceEventType.Verbose, 100, "ADM: All {0} devices now configured and connected to board {1} on port {2}", adm.DeviceCount, adm.BoardID, adm.PortAndNodeID);
                    OnADMDevicesConnected(adm, message);
                }
                break;

            case MessageType.PING_RESPONSE:
                break;
            }

            if (message.Tag > 0)
            {
                ADMRequest req = GetADMRequest(adm, message.Tag);
                if (req != null)
                {
                    if (req.HasExpired())
                    {
                        Tracing?.TraceEvent(TraceEventType.Warning, 0, "ADM request for tag {0} and target {1} has expired so not returning message of type {2}", message.Tag, req.Target, message.Type);
                        return;
                    }
                    else
                    {
                        message.Target = req.Target;
                    }
                }
            }

            var schema = new ADMService.MessageSchema(message);

            schema.PrepareForBroadcast(adm);

            //notify other clients listening to this client
            Broadcast(ADMEvent.MESSAGE, message);
        }