public override bool ExecuteAction(DeviceAction action) { switch (action.Action) { case "Off": SetColor(Color.Black); break; case "On": SetColor(DefaultColor); break; case "Full": SetColor(WhiteColor); break; case "Set": var color = action.Values != null && action.Values.Length > 2 ? Color.FromArgb(action.Values[0], action.Values[1], action.Values[2]) : Color.Black; SetColor(color); break; default: return false; } if (DeviceEvent != null) { var devEvent = new DeviceEvent(Name, action.Action, Status, _scheduler.TimeIndex, action.Values); DeviceEvent(this, new DeviceEventArgs(devEvent)); } Log.Debug(string.Format("RgbDevice.ExecuteAction {0}", action)); return true; }
public DeviceSchedule(DateTime date, Device device, DeviceAction action, ScheduleTypes type = ScheduleTypes.Once, int interval = 0) { _date = date; _device = device; _action = action; _type = type; _interval = interval; }
public virtual bool ExecuteAction(DeviceAction action) { throw new NotImplementedException(); }
public override bool ExecuteAction(DeviceAction action) { //Safe convert to shutter actions var oldStatus = Status; //Remove old schedules _scheduler.Purge(this.Name); //Turn off motors _hal.Write(_openPin, PinTypes.Output, 0); _hal.Write(_closePin, PinTypes.Output, 0); switch (action.Action) { case ActionOpen: if (oldStatus != StatusOpen) { //Open shutter _hal.Write(_openPin, PinTypes.Output, 1); //stop after n seconds _scheduler.AddSchedule(new DeviceSchedule(DateTime.Now.AddMilliseconds(_delay * 1000), this, new DeviceAction(Name, ActionStopAfterOpen))); _status = StatusOpen; } else { //Double open ==> stop action.Action = ActionStop; _status = StatusStop; } break; case ActionClose: if (oldStatus != StatusClose) { //Close shutter _hal.Write(_closePin, PinTypes.Output, 1); //stop after n seconds _scheduler.AddSchedule(new DeviceSchedule(DateTime.Now.AddMilliseconds(_delay * 1000), this, new DeviceAction(Name, ActionStopAfterClose))); _status = StatusClose; } else { //Double close ==> stop action.Action = ActionStop; _status = StatusStop; } break; case ActionStop: _status = StatusStop; break; case ActionStopAfterClose: _status = StatusClosed; break; case ActionStopAfterOpen: _status = StatusOpened; break; default: return false; } if (DeviceEvent != null) { var devEvent = new DeviceEvent(Name, action.Action, Status, _scheduler.TimeIndex, action.Values); DeviceEvent(this, new DeviceEventArgs(devEvent)); } Log.Debug(string.Format("Shutter.ExecuteAction {0}", action)); return true; }
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"); }; }
/// <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; }