예제 #1
0
    /// <summary>
    /// Process HBus ack messages
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="ack"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private bool OnAckReceived(object sender, Message ack, int port)
    {
      try
      {
        Event evt = null;

        //if (Status.NodeStatus != NodeStatusValues.Active) return false;
        if (ack.MessageType == MessageTypes.NackResponse)
        {
          var err = ack.Data.Length > 1 ? ack.Data[0] << 1 | ack.Data[1] : 0;
          Log.Debug(string.Format("HBus: nack from {0}:{1} with error {2}", ack.Source, port, err));
          return false;
        }

        Log.Debug(string.Format("HBus: ack from {0}:{1}", ack.Source, port));

        switch (ack.Command)
        {
          //case NodeCommands.CMD_GET_PIN_INFO:
          //    var pp = new Pin();
          //    var pi = PinSerializer.DeSerialize(ack.Data, ref pp);
          //    break;
          case NodeCommands.CMD_READ_PIN:
            var pe = new PinEvent(ack.Data);
            evt = new Event
            {
              Name = "pin-read",
              Source = pe.Pin,
              Channel = "hbus",
              Value = pe.Value,
              Status = pe.IsActive ? "active" : "inactive",
              Timestamp = DateTime.Now
            };
            break;
          case NodeCommands.CMD_GET_DEVICE_STATUS:
            var ds = new DeviceStatus(ack.Data);
            evt = new Event
            {
              Name = "device-status",
              Source = ds.Device,
              Channel = "hbus",
              Status = ds.Status,
              Timestamp = DateTime.Now
            };
            break;
          //case NodeCommands.CMD_GET_DEVICE_INFO:
          //    var dd = new Device();
          //    var di = DeviceSerializer.DeSerialize(ack.Data, ref dd);
          //    break;
          //case NodeCommands.CMD_GET_SENSOR_INFO:
          //    break;
          case NodeCommands.CMD_READ_SENSOR:
            var sr = new SensorRead(ack.Data);
            evt = new Event
            {
              Name = "sensor-read",
              Source = sr.Name,
              Channel = "hbus",
              Value = sr.Value,
              Unit = "", //sr.Unit, //TODO: add to HBus protocol
              Timestamp = DateTime.Now
            };
            break;
        }

        if (evt != null)
          //Send event to subscribers
          Send(evt, this);

        return true;
      }
      catch (Exception ex)
      {
        Log.Error(string.Format("HBus: error occurred with ack {0} from {1}", ack.Command, ack.Source), ex);

        //Propagate errors to observers
        Error(ex, this);
      }
      return false;
    }
예제 #2
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;
        }
예제 #3
0
    /// <summary>
    /// Process HBus command messages
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="message"></param>
    /// <param name="port"></param>
    /// <returns></returns>
    private bool OnCommandReceived(object sender, Message message, int port)
    {
      Log.Debug(string.Format("HBus command from {0}:{1}", message.Source, port));

      try
      {
        Event evt = null;

        //Clear bus & node errors
        _bus.ClearErrors();

        switch (message.Command)
        {
          case NodeCommands.CMD_PUSH_PIN_EVENT:
            var pe = new PinEvent(message.Data);
            evt = new Event
            {
              Name = "pin-change",
              Source = pe.Pin,
              //Channel = "hbus",
              Value = pe.Value,
              Status = pe.IsActive ? "active" : "inactive",
              Timestamp = DateTime.Now
            };
            break;
          case NodeCommands.CMD_PUSH_DEVICE_EVENT:
            var de = new DeviceEvent(message.Data);
            evt = new Event
            {
              Name = "device-event",
              Source = de.Device,
              //Channel = "hbus",
              Status = de.Status,
              Data = de.Values,
              Timestamp = DateTime.Now
            };
            break;
          case NodeCommands.CMD_PUSH_SENSOR_READ:
            var sr = new SensorRead(message.Data);
            evt = new Event
            {
              Name = "sensor-read",
              Source = sr.Name,
              //Channel = "hbus",
              Value = sr.Value,
              Unit = "", //sr.Unit, //TODO: add to HBus protocol
              Timestamp = DateTime.Now
            };
            break;
        }

        if (evt != null)
          //Send event to subscribers
          Send(evt, this);

        //HBus command processed
        return true;
      }
      catch (Exception ex)
      {
        Log.Error(string.Format("HBus: error with command {0} from {1}", message.Command, message.Source), ex);

        //Propagate errors to observers
        Error(ex, this);
      }
      return false;
    }
예제 #4
0
 public WireEventArgs(PinEvent evtSource)
 {
     Source = evtSource;
 }