예제 #1
0
 public DeviceAction(byte[] array, int startIndex = 0)
 {
     var stack = new SimpleStack(array, startIndex);
     _device = stack.PopName();
     _action = stack.PopString();
     _values = stack.PopArray();
 }
예제 #2
0
        public NodeInfo(byte[] data)
        {
            if (data == null)
                throw new ArgumentNullException("data");

            if (data.Length < 28)
                throw new ArgumentException("data length not sufficient to fill NodeInfo");

            var stack = new SimpleStack(data);
            Name = stack.PopName();
            Description = stack.PopString();
            Location = stack.PopString();
            Address = stack.PopAddress();
            Type = stack.PopString();
            Hardware = stack.PopName();
            Version = stack.PopName();
            DigitalInputs = stack.PopByte();
            DigitalOutputs = stack.PopByte();
            AnalogInputs = stack.PopByte();
            CounterInputs = stack.PopByte();
            PwmOutputs = stack.PopByte();
            WiresCount = stack.PopByte();
            DevicesCount = stack.PopByte();
            SensorsCount = stack.PopByte();
            ResetPin = stack.PopByte();
        }
예제 #3
0
 public PinEvent(byte[] array, int startIndex = 0)
 {
     var stack = new SimpleStack(array, startIndex);
     _pin = stack.PopName();
     _value = stack.PopInt32();
     _isActive = stack.PopByte() == 1;
 }
예제 #4
0
        public SensorRead(byte[] array)
        {
            var stack = new SimpleStack(array);

            Name = stack.PopName();
            Time = stack.PopUInt32();
            Value = stack.PopSingle();
        }
예제 #5
0
 public PinStatus(byte[] array, int start = 0) : this()
 {
     if (array == null || array.Length < start) return;
     var stack = new SimpleStack(array, start);
     Index = stack.PopByte();
     Pin = stack.PopName();
     Value = stack.PopUInt32();
 }
예제 #6
0
 public DeviceStatus(byte[] array, int start = 0) : this()
 {
     if (array == null || array.Length < start) return;
     var stack = new SimpleStack(array, start);
     Index = stack.PopByte();
     Device = stack.PopName();
     Status = stack.PopString();
 }
예제 #7
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();
            stack.Push(Index);
            stack.PushName(Pin);
            stack.Push(Value);

            return stack.Data;
        }
예제 #8
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();
            stack.PushName(_device);
            stack.Push(_action);
            stack.Push(_values);

            return stack.Data;
        }
예제 #9
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();
            stack.PushName(_pin);
            stack.Push(_value);
            stack.Push((byte)(_isActive ?  1 : 0));

            return stack.Data;
        }
예제 #10
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();
            stack.Push(Index);
            stack.PushName(Device);
            stack.Push(Status);

            return stack.Data;
        }
예제 #11
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();
            stack.PushName(_device);
            stack.Push(_event);
            stack.Push(_status);
            stack.Push(_time);
            stack.Push(_values);

            return stack.Data;
        }
예제 #12
0
 public DeviceEvent(byte[] array, int startIndex = 0)
 {
     if (array != null)
     {
         var stack = new SimpleStack(array, startIndex);
         _device = stack.PopName();
         _event = stack.PopString();
         _status = stack.PopString();
         _time = stack.PopUInt32();
         _values = stack.PopArray();
     }
     else 
     {
         _device = string.Empty;
         _event = string.Empty;
         _status = string.Empty;
         _time = 0;
         _values = null;
     }
 }
예제 #13
0
        public byte[] ToArray()
        {
            var stack = new SimpleStack();

            stack.PushName(Name);
            stack.Push(Description);
            stack.Push(Location);
            stack.Push(Address);
            stack.Push(Type);
            stack.PushName(Hardware);
            stack.PushName(Version);
            stack.Push(DigitalInputs);
            stack.Push(DigitalOutputs);
            stack.Push(AnalogInputs);
            stack.Push(CounterInputs);
            stack.Push(PwmOutputs);
            stack.Push(WiresCount);
            stack.Push(DevicesCount);
            stack.Push(SensorsCount);
            //stack.Push(SupportedCommands);
            stack.Push(ResetPin);

            return stack.Data;
        }
예제 #14
0
 /// <summary>
 /// HBus compatible constructor
 /// </summary>
 /// <param name="data"></param>
 /// <param name="index"></param>
 public DeviceInfo(byte[] data, int index = 0) : this()
 {
     var stack = new SimpleStack(data, index);
     Index = stack.PopByte();
     Name = stack.PopName();
     //Address = stack.PopAddress();
     Description = stack.PopString();
     Location = stack.PopString();
     Class = stack.PopString();
     Hardware = stack.PopString();
     Version = stack.PopString();
     Actions = stack.PopStringArray();
 }
예제 #15
0
        /// <summary>
        /// Serialize node status to byte array
        /// </summary>
        /// <returns>data stream (byte array)</returns>
        public byte[] ToArray()
        {
            var stack = new SimpleStack();

            //Node global status
            stack.Push(Mask);
            stack.Push(Time);
            stack.Push((byte)NodeStatus);
            stack.Push((byte)BusStatus);
            stack.Push((byte)LastError);
            stack.Push(TotalErrors);

            stack.Push((byte)(Inputs!= null ? Inputs.Length : 0));
            stack.Push((byte)(Outputs != null ? Outputs.Length : 0));
            stack.Push((byte)(Analogs != null ? Analogs.Length : 0));
            stack.Push((byte)(Counters != null ? Counters.Length : 0));
            stack.Push((byte)(Pwms != null ? Pwms.Length : 0));
            stack.Push((byte)(Devices != null ? Devices.Length : 0));
            stack.Push((byte)(Sensors != null ? Sensors.Length : 0));

            stack.PushName(LastActivatedInput);
            stack.PushName(LastActivatedOutput);

            //Inputs
            if ((Mask & 0x01) != 0 && Inputs != null && Inputs.Length > 0)
                foreach (var input in Inputs)
                    stack.Push(input);

            //Outputs
            if ((Mask & 0x02) != 0 && Outputs != null && Outputs.Length > 0)
                foreach (var output in Outputs)
                    stack.Push(output);
            //Analogs
            if ((Mask & 0x04) != 0 && Analogs != null && Analogs.Length > 0)
                foreach (var analog in Analogs)
                    stack.Push(analog);
            //Counters
            if ((Mask & 0x08) != 0 && Counters != null && Counters.Length > 0)
                foreach (var counter in Counters)
                    stack.Push(counter);
            //Pwms
            if ((Mask & 0x10) != 0 && Pwms != null && Pwms.Length > 0)
                foreach (var pwm in Pwms)
                    stack.Push(pwm);
            //Devices
            if ((Mask & 0x20) != 0 && Devices != null && Devices.Length > 0)
                foreach (var device in Devices)
                    stack.Push(device);
            //Sensors
            if ((Mask & 0x40) != 0 && Sensors != null && Sensors.Length > 0)
                foreach (var sensor in Sensors)
                    stack.Push(sensor);

            return stack.Data;
        }
예제 #16
0
    private IList<Wire> GetWires(IEnumerable<XElement> elements, Node node, BusController bus)
    {
      var wires = new List<Wire>();

      foreach (var xwire in elements)
      {
        var input = xwire.Attribute("input").Value;
        var pin = node.Pins.FirstOrDefault(p => p.Name == input);
        if (pin == null) throw new WireException("Input pin not found");

        var index = Convert.ToByte(xwire.Attribute("index").Value);

        var address = xwire.Attribute("address") != null && !string.IsNullOrEmpty(xwire.Attribute("address").Value)
            ? Address.Parse(Convert.ToUInt32(xwire.Attribute("address").Value))
            : Address.Empty;

        var useInputData = xwire.Attribute("useInputData") != null && !string.IsNullOrEmpty(xwire.Attribute("useInputData").Value) && Convert.ToBoolean(xwire.Attribute("useInputData").Value);

        var cmdText = xwire.Attribute("command").Value.ToUpperInvariant();
        byte cmd = 0;

        #region parse command name
        switch (cmdText)
        {
          case "PING":
            cmd = NodeCommands.CMD_PING;
            break;
          case "RESET":
            cmd = NodeCommands.CMD_RESET;
            break;
          case "READ_CONFIG":
            cmd = NodeCommands.CMD_READ_CONFIG;
            break;
          case "START":
            cmd = NodeCommands.CMD_START;
            break;
          case "STOP":
            cmd = NodeCommands.CMD_STOP;
            break;
          //Pins
          case "CHANGE_DIGITAL":
            cmd = NodeCommands.CMD_CHANGE_DIGITAL;
            break;
          case "TOGGLE_DIGITAL":
            cmd = NodeCommands.CMD_TOGGLE_DIGITAL;
            break;
          case "TIMED_DIGITAL":
            cmd = NodeCommands.CMD_TIMED_DIGITAL;
            break;
          case "DELAY_DIGITAL":
            cmd = NodeCommands.CMD_DELAY_DIGITAL;
            break;
          case "PULSE_DIGITAL":
            cmd = NodeCommands.CMD_PULSE_DIGITAL;
            break;
          case "CYCLE_DIGITAL":
            cmd = NodeCommands.CMD_CYCLE_DIGITAL;
            break;
          case "CHANGE_ALL_DIGITAL":
            cmd = NodeCommands.CMD_CHANGE_ALL_DIGITAL;
            break;
          case "CHANGE_PWM":
            cmd = NodeCommands.CMD_CHANGE_PWM;
            break;
          case "CHANGE_PIN":
            cmd = NodeCommands.CMD_CHANGE_PIN;
            break;
          case "DELAY_TOGGLE_DIGITAL":
            cmd = NodeCommands.CMD_DELAY_TOGGLE_DIGITAL;
            break;
          case "DELTA_PWM":
            cmd = NodeCommands.CMD_DELTA_PWM;
            break;
          case "FADE_PWM":
            cmd = NodeCommands.CMD_FADE_PWM;
            break;
          case "ACTIVATE":
            cmd = NodeCommands.CMD_ACTIVATE;
            break;
          case "DEACTIVATE":
            cmd = NodeCommands.CMD_DEACTIVATE;
            break;
          case "EXECUTE_DEVICE_ACTION":
            cmd = NodeCommands.CMD_EXECUTE_DEVICE_ACTION;
            break;
          case "PUSH_SENSOR_READ":
            cmd = NodeCommands.CMD_READ_SENSOR;
            break;
        }
        #endregion

        var dataText = xwire.Attribute("data") != null ? xwire.Attribute("data").Value : string.Empty;
        var data = Csv.CsvToList<byte>(dataText).ToArray();
        //var trgText = xwire.Attribute("trigger") != null ? xwire.Attribute("trigger").Value : string.Empty;
        //var trgs = Csv.CsvToList<string>(trgText).ToArray();
        //var trigger = WireTriggers.None;
        //foreach (var trg in trgs)
        //{
        //    trigger |= trg != null && Enum.IsDefined(typeof (WireTriggers), trg)
        //        ? (WireTriggers) Enum.Parse(typeof (WireTriggers), trg)
        //        : WireTriggers.None;
        //}

        var wire = new Wire(pin)
        {
          Index = index,
          Command = cmd,
          Address = address,
          UseInputData = useInputData,
          Parameters = data
        };

        //Add wire trigger event
        //TODO configurable on Activate/deactivate/change
        wire.OnWireTriggered += (sender, args) =>
        {
          var w = (Wire)sender;

          var stack = new SimpleStack(w.Parameters);
          if (w.UseInputData)
          {
            stack.Push(args.Source.Value);
          }
          if (w.Address == Address.Empty || w.Address == bus.Address)
            node.Execute(w.Address, w.Command, stack.Data);
          else
            bus.SendImmediate(w.Command, w.Address, stack.Data);
        };

        wires.Add(wire);
      }

      Log.Debug(string.Format("Configured {0} wires", wires.Count));

      return wires;
    }
예제 #17
0
        public NodeStatusInfo(byte[] data)
        {
            var stack = new SimpleStack(data);
            //Bit Mask:
            //----------
            //00: Inputs
            //01: Outputs
            //02: Analogs
            //04: Counters
            //08: Pwms
            //16: Devices
            //32: Sensors
            Mask = stack.PopByte();

            //Node global status
            Time = stack.PopUInt32();

            NodeStatus = (NodeStatusValues)stack.PopByte();
            BusStatus = (BusStatus)stack.PopByte();

            LastError = (NodeErrorCodes)stack.PopByte();
            TotalErrors = stack.PopUInt32();
            
            var size = stack.PopByte(); Inputs = size > 0 ? new byte[size] : null;
            size = stack.PopByte(); Outputs = size > 0 ? new byte[size] : null;
            size = stack.PopByte(); Analogs = size > 0 ? new ushort[size] : null;
            size = stack.PopByte(); Counters = size > 0 ? new uint[size] : null;
            size = stack.PopByte(); Pwms = size > 0 ? new ushort[size] : null;
            size = stack.PopByte(); Devices = size > 0 ? new string[size] : null;
            size = stack.PopByte(); Sensors = size > 0 ? new float[size] : null;

            LastActivatedInput = stack.PopName();
            LastActivatedOutput = stack.PopName();

            //Inputs
            if ((Mask & 0x01) != 0 && Inputs!=null)
                for (var i = 0; i < Inputs.Length; i++)
                    Inputs[i] = stack.PopByte();
            //Outputs
            if ((Mask & 0x02) != 0 && Outputs != null)
                for (var i = 0; i < Outputs.Length; i++)
                    Outputs[i] = stack.PopByte();
            //Analogs
            if ((Mask & 0x04) != 0 && Analogs != null)
                for (var i = 0; i < Analogs.Length; i++)
                    Analogs[i] = stack.PopUInt16();
            //Counters
            if ((Mask & 0x08) != 0 && Counters != null)
                for (var i = 0; i < Counters.Length; i++)
                    Counters[i] = stack.PopUInt32();
            //Pwms
            if ((Mask & 0x10) != 0 && Pwms != null)
                for (var i = 0; i < Pwms.Length; i++)
                    Pwms[i] = stack.PopUInt16();
            //Devices
            if ((Mask & 0x20) != 0 && Devices!= null)
                for (var i = 0; i < Devices.Length; i++)
                    //Get status string
                    Devices[i] = stack.PopString();
            //Sensors
            if ((Mask & 0x40) != 0 && Sensors != null)
                for (var i = 0; i < Sensors.Length; i++)
                    //Get last sensor read
                    Sensors[i] = stack.PopSingle();
        }
예제 #18
0
파일: Node.cs 프로젝트: vinmenn/HBus.DotNet
        private bool OnCommandReceived(object sender, Message message, int port)
        {
            //if (Status.NodeStatus != NodeStatusValues.Active) return false;

            //Clear bus & node errors
            _bus.ClearErrors();
            Status.LastError = 0;

            //Most common parameters
            var stack = new SimpleStack(message.Data);
            stack.ClearRead();

            Log.Debug(string.Format("received command from node {0}", message.Source));

            return Execute(message.Source, message.Command, message.Data);

        }
예제 #19
0
파일: Node.cs 프로젝트: vinmenn/HBus.DotNet
        /// <summary>
        /// Execute node command
        /// </summary>
        /// <param name="source">Source of command</param>
        /// <param name="command">HBus command</param>
        /// <param name="datain">Command data</param>
        /// <returns>true if command is executed</returns>
        public bool Execute(Address source, byte command, byte[] datain)
        {
            try
            {
                byte index;
                int value;
                byte delay;
                byte width;
                string name;
                Pin pin;
                Sensor sensor;
                Device device;
                var stack = new SimpleStack(datain);
                var dataOut = new List<byte>();
                var done = false;

                switch (command)
                {
                    #region Bus commands
                    case NodeCommands.CMD_PING:
                        dataOut.AddRange(FixedString.ToArray(Name, HBusSettings.NameLength));
                        _bus.Payload = dataOut.ToArray();
                        done = true;
                        break;
                    #endregion

                    #region Node commands
                    case NodeCommands.CMD_RESET:
                        index = stack.PopByte();	//1 = full reset
                        Reset(index == 1);
                        done = true;
                        break;
                    case NodeCommands.CMD_START:
                        Start();
                        done = true;
                        break;
                    case NodeCommands.CMD_STOP:
                        Stop();
                        done = true;
                        break;
                    case NodeCommands.CMD_FACTORY_DEFAULT:
                        LoadConfiguration(true);
                        done = true;
                        break;
                    case NodeCommands.CMD_READ_CONFIG:
                        LoadConfiguration(false);
                        done = true;
                        break;
                    case NodeCommands.CMD_WRITE_CONFIG:
                        SaveConfiguration();
                        done = true;
                        break;
                    case NodeCommands.CMD_ADD_NODE_LISTENER:
                        //index = stack.PopByte();	//mask
                        //Add pin to subscriptions
                        if (!_nodeSubscribers.ContainsKey(source))
                        {
                            _nodeSubscribers.Add(source, 0);
                            
                            SubscribeAll();

                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELETE_NODE_LISTENER:
                        if (_nodeSubscribers.ContainsKey(source))
                        {
                            _nodeSubscribers.Remove(source);

                            UnsubscribeAll();

                            done = true;
                        }
                        break;
                    #endregion

                    #region information commands
                    case NodeCommands.CMD_READ_ALL:
                        value = stack.PopByte(); //mask
                        UpdateNodeStatus((byte)value);
                        _bus.Payload = Status.ToArray();
                        done = true;
                        break;
                    case NodeCommands.CMD_GET_INFO:
                        UpdateNodeInfo();
                        var array = NodeSerializer.Serialize(this);
                        _bus.Payload = array;
                        done = true;
                        break;
                    case NodeCommands.CMD_GET_NAME_INFO: //Subnode info
                        name = stack.PopName();
                        var node = GetSubnode(name);
                        if (node != null)
                        {
                            _bus.Payload = node.ToArray();
                            done = true;
                        }
                        break;
                    #endregion
                    
                    #region General pin commands
                    case NodeCommands.CMD_ACTIVATE:
                        name = stack.PopName();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            pin.Activate();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DEACTIVATE:
                        name = stack.PopName();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            pin.Deactivate();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_SET_PIN:
                        pin = new Pin(_hal, _scheduler);
                        PinSerializer.DeSerialize(datain, ref pin);
                        //pin = new Pin(datain, _hal, _scheduler);
                        var oldPin = Pins.FirstOrDefault(p => p.Index == pin.Index);
                        if (oldPin != null) Pins.Remove(oldPin);
                        Pins.Add(pin);
                        done = true;
                        break;
                    case NodeCommands.CMD_CONNECT:
                        //var wire = new Wire(datain, this, _bus);
                        var wire = new Wire();
                        WireSerializer.DeSerialize(datain, ref wire);
                        wire.Input = Pins.FirstOrDefault(p => p.Name == wire.Input.Name);

                        var oldWire = Wires.FirstOrDefault(w => w.Index == wire.Index);
                        if (oldWire != null) Wires.Remove(oldWire);
                        Wires.Add(wire);
                        done = true;
                        break;
                    case NodeCommands.CMD_ADD_PIN_LISTENER:
                        //Device name
                        name = stack.PopName();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            //Add pin to subscriptions
                            if (!_pinSubscribers.ContainsKey(source + "." + name))
                                _pinSubscribers.Add(source + "." + name, pin);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELETE_PIN_LISTENER:
                        //Device name
                        name = stack.PopName();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            //Add pin to subscriptions
                            if (_pinSubscribers.ContainsKey(source + "." + name))
                                _pinSubscribers.Remove(source + "." + name);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_PUSH_PIN_EVENT:
                        if (OnPinEvent != null)
                        {
                            OnPinEvent(source, new PinEvent(datain));
                        }
                        done = true;
                        break;
                    #endregion

                    #region Pins digital write commands
                    case NodeCommands.CMD_CHANGE_ALL_DIGITAL:
                        value = stack.PopByte();
                        foreach (var p in Pins)
                        {
                            p.Change(value);
                        }
                        done = true;
                        break;
                    case NodeCommands.CMD_CHANGE_DIGITAL:
                        index = stack.PopByte();
                        value = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.Change(value);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_TOGGLE_DIGITAL:
                        index = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.Toggle();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_TIMED_DIGITAL:
                        index = stack.PopByte();
                        width = stack.PopByte();
                        value = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.TimedOutput(width, value);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELAY_DIGITAL:
                        index = stack.PopByte();
                        delay = stack.PopByte();
                        value = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.DelayOutput(delay, value);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELAY_TOGGLE_DIGITAL:
                        index = stack.PopByte();
                        delay = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.DelayToggle(delay);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_PULSE_DIGITAL:
                        index = stack.PopByte();
                        delay = stack.PopByte();
                        width = stack.PopByte();
                        value = stack.PopByte();
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.PulsedOutput(delay, width, value);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_CYCLE_DIGITAL:
                        index = stack.PopByte();
                        delay = stack.PopByte();
                        width = stack.PopByte();
                        value = stack.PopByte(); //cycles
                        pin = GetPin(index, PinTypes.Output);
                        if (pin != null)
                        {
                            pin.CycledOutput(delay, width, value);
                            done = true;
                        }
                        break;
                    #endregion

                    #region Pins analog/pwm write commands
                    case NodeCommands.CMD_CHANGE_PWM:
                        index = stack.PopByte();
                        delay = stack.PopByte(); //high pulse
                        width = stack.PopByte(); //total pulse
                        pin = GetPin(index, PinTypes.Pwm);
                        if (pin != null)
                        {
                            pin.ChangePwm(delay, width);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELTA_PWM:
                        index = stack.PopByte();
                        value = stack.PopInt16();
                        pin = GetPin(index, PinTypes.Pwm);
                        if (pin != null)
                        {
                            pin.ChangeDelta(value);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_FADE_PWM:
                        index = stack.PopByte();
                        //type = (PinTypes)stack.PopByte();
                        var startValue = stack.PopUInt16();
                        var endValue = stack.PopUInt16();
                        value = stack.PopByte();  //steps
                        delay = stack.PopByte();
                        pin = GetPin(index, PinTypes.Pwm);
                        if (pin != null)
                        {
                            pin.Fade(startValue, endValue, (byte)value, delay);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_CHANGE_PIN:
                        name = stack.PopName();
                        value = stack.PopInt32();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            pin.Change(value);
                            done = true;
                        }
                        break;
                    #endregion

                    #region Pins read commands
                    case NodeCommands.CMD_GET_PIN_INFO:
                        index = stack.PopByte();
                        value = stack.PopByte();
                        pin = GetPin(index, (PinTypes)value);
                        if (pin != null)
                        {
                            _bus.Payload = PinSerializer.Serialize(pin);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_GET_CONNECT_INFO:
                        index = stack.PopByte();
                        wire = Wires.FirstOrDefault(w => w.Index == index);
                        if (wire != null)
                        {
                            array = WireSerializer.Serialize(wire);
                            _bus.Payload = array;
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_READ_PIN:
                        name = stack.PopName();
                        pin = GetPin(name);
                        if (pin != null)
                        {
                            //Get pin value
                            var evt = new PinEvent(name, pin.Read(), pin.IsActive());
                            _bus.Payload = evt.ToArray();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_READ_LAST_INPUT:
                        dataOut.AddRange(FixedString.ToPaddedArray(Status.LastActivatedInput, HBusSettings.NameLength, ' '));
                        _bus.Payload = dataOut.ToArray();
                        done = true;
                        break;
                    case NodeCommands.CMD_READ_LAST_ACTIVE:
                        dataOut.AddRange(FixedString.ToPaddedArray(Status.LastActivatedOutput, HBusSettings.NameLength, ' '));
                        _bus.Payload = dataOut.ToArray();
                        done = true;
                        break;
                    #endregion

                    #region Device commands
                    case NodeCommands.CMD_GET_DEVICE_INFO:
                        index = stack.PopByte();
                        device = GetDevice(index);
                        if (device != null)
                        {
                            array = DeviceSerializer.Serialize(device);
                            _bus.Payload = array;
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_GET_DEVICE_STATUS:
                        name = stack.PopName();
                        device = GetDevice(name);
                        if (device != null)
                        {
                            var status = new DeviceStatus(device.Index, device.Name, device.Status);
                            _bus.Payload = status.ToArray();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_EXECUTE_DEVICE_ACTION:
                        //Device name
                        var action = new DeviceAction(datain);
                        device = GetDevice(action.Device);
                        //Execute action
                        if (device != null)
                        {
                            device.ExecuteAction(action);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_ADD_DEVICE_LISTENER:
                        //Device name
                        name = stack.PopName();
                        device = GetDevice(name);
                        //Execute action
                        if (device != null)
                        {
                            if (!_deviceSubscribers.ContainsKey(source + "." + name))
                                _deviceSubscribers.Add(source + "." + name, device);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELETE_DEVICE_LISTENER:
                        //Device name
                        name = stack.PopName();
                        device = GetDevice(name);
                        //Execute action
                        if (device != null)
                        {
                            if (_deviceSubscribers.ContainsKey(source + "." + name))
                                _deviceSubscribers.Remove(source + "." + name);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_PUSH_DEVICE_EVENT:
                        if (OnDeviceEvent != null)
                        {
                            var evt = new DeviceEvent(datain);
                            OnDeviceEvent(source, evt);
                            done = true;
                        }
                        break;
                    #endregion

                    #region Sensor commands
                    case NodeCommands.CMD_GET_SENSOR_INFO:
                        index = stack.PopByte();
                        sensor = GetSensor(index);
                        if (sensor != null)
                        {
                            array = SensorSerializer.Serialize(sensor);
                            _bus.Payload = array;
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_READ_SENSOR:
                        //Sensor name
                        name = stack.PopName();
                        sensor = GetSensor(name);
                        if (sensor != null)
                        {
                            _bus.Payload = sensor.Read().ToArray();
                            done = true;
                        }
                        break;

                    case NodeCommands.CMD_RESET_SENSOR:
                        //Sensor name
                        name = stack.PopName();
                        sensor = GetSensor(name);
                        if (sensor != null)
                        {
                            sensor.Reset();
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_ADD_SENSOR_LISTENER:
                        //Sensor name
                        name = stack.PopName();
                        var interval = stack.PopByte(); //interval
                        var expire = stack.PopUInt16(); //Expires

                        sensor = GetSensor(name);
                        if (sensor != null)
                        {
                            if (_sensorSubscribers.All(s => s.Sensor != sensor))
                                _sensorSubscribers.Add(new SensorSubscriber(source, sensor, interval, expire));
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_DELETE_SENSOR_LISTENER:
                        //Sensor name
                        name = stack.PopName();
                        sensor = GetSensor(name);
                        if (sensor != null)
                        {
                            var sub = _sensorSubscribers.FirstOrDefault(s => s.Address == source);
                            if (sub.Sensor != null)
                                _sensorSubscribers.Remove(sub);
                            done = true;
                        }
                        break;
                    case NodeCommands.CMD_PUSH_SENSOR_READ:
                        if (OnSensorRead != null)
                        {
                            OnSensorRead(source, new SensorRead(datain));
                        }
                        done = true;
                        break;
                    #endregion

                    #region Obolete / unsupported commands
                    //case NodeCommands.CMD_MULTI_ACTIVATE:
                    //    //delay = stack.PopByte();
                    //    //var names = stack.PopNames();
                    //    //MultiActivateOutput(names, delay);
                    //    SetError(NodeErrorCodes.CommandNotSupported);
                    //    break;
                    //case NodeCommands.CMD_READ_KEY:
                    //    //value = GetKeyPressed();
                    //    //_bus.Payload = new[] { (byte)value };
                    //    SetError(NodeErrorCodes.CommandNotSupported);
                    //    break;
                    #endregion
                    default:
                        SetError(NodeErrorCodes.CommandNotSupported);
                        break;
                }
                return done;
            }
            catch (Exception ex)
            {
                SetError(NodeErrorCodes.GenericError);
                Log.Error(string.Format("error occurred while processing command {0} for main node {1}", command, Name), ex);
            }
            return false;
        }
예제 #20
0
    public HBusProcessor(BusController hbus)
    {
      _bus = hbus;
      _bus.CommandReceived += OnCommandReceived;
      _bus.AckReceived += OnAckReceived;
      _scheduler = Scheduler.GetScheduler();
      _hbusEvents = new Dictionary<string, IList<Event>>();
      //Event from ep source
      OnSourceEvent = (@event, point) =>
      {
        if (@event.Channel != Channel && !string.IsNullOrEmpty(@event.Channel)) return;

        var address = !string.IsNullOrEmpty(@event.Address) ? Address.Parse(@event.Address) : Address.BroadcastAddress;

        var stack = new SimpleStack();

        ////Create new page event list
        //if (!_hbusEvents.ContainsKey(@event.Subscriber))
        //    _hbusEvents.Add(@event.Subscriber, new List<Event>());

        switch (@event.Name)
        {
          case "node-subscribe":
            _bus.SendCommand(NodeCommands.CMD_ADD_NODE_LISTENER, address);
            break;
          case "node-unsubscribe":
            _bus.SendCommand(NodeCommands.CMD_DELETE_NODE_LISTENER, address);
            break;
          case "pin-activate":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_ACTIVATE, address, stack.Data);
            break;
          case "pin-deactivate":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_DEACTIVATE, address, stack.Data);
            break;
          case "pin-subscribe":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_ADD_PIN_LISTENER, address, stack.Data);
            break;
          case "pin-unsubscribe":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_DELETE_PIN_LISTENER, address, stack.Data);
            break;
          case "device-subscribe":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_ADD_DEVICE_LISTENER, address, stack.Data);
            break;
          case "device-unsubscribe":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_DELETE_DEVICE_LISTENER, address, stack.Data);
            break;
          case "sensor-subscribe":
            //This is extracted only for explantion
            //@event.Data could be used as it is
            var interval = @event.Data[0];
            var expires = (ushort) (@event.Data[2] << 8 + @event.Data[1]);
            stack.PushName(@event.Source);
            stack.Push(interval);
            stack.Push(expires);
            _bus.SendCommand(NodeCommands.CMD_ADD_SENSOR_LISTENER, address, stack.Data);
            break;
          case "sensor-unsubscribe":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_DELETE_SENSOR_LISTENER, address, stack.Data);
            break;
          case "sensor-read":
            stack.PushName(@event.Source);
            _bus.SendCommand(NodeCommands.CMD_READ_SENSOR, address, stack.Data);
            break;
          //TODO: other HBus commands
          default:
            if (@event.Name.IndexOf("device-") == 0)
            {
              //Send device action
              var devaction = new DeviceAction(@event.Source, @event.Name.Substring(7), @event.Data);
              _bus.SendCommand(NodeCommands.CMD_EXECUTE_DEVICE_ACTION, address, devaction.ToArray());
            }
            break;
        }
      };

      //Error from ep source
      OnSourceError = (exception, sender) =>
      {
        Log.Error("Error from source endpoint", exception);
      };

      //Close connection with ep source
      OnSourceClose = (sender) =>
      {
        //Close HBus endpoint
        Stop();

        Log.Debug("closed on source close");
      };
    }
예제 #21
0
 /// <summary>
 /// Convert shared information
 /// to transmit to other devices
 /// </summary>
 /// <returns></returns>
 public byte[] ToArray()
 {
     var stack = new SimpleStack();
     stack.Push(Index);
     stack.PushName(Name);
     //stack.Push(Address);
     stack.Push(Description);
     stack.Push(Location);
     stack.Push(Class);
     stack.Push(Hardware);
     stack.Push(Version);
     stack.PushStringArray(Actions);
     return stack.Data;
 }