internal override void OnMessage(InsteonMessage message) { var cmd2 = (byte)message.Properties[PropertyKey.Cmd2]; if (message.MessageType == InsteonMessageType.OnCleanup) { if (cmd2 == 0x01) { logger.InfoFormat("Dry State detected in device {0}", Address.ToString()); OnDeviceStatusChanged(InsteonDeviceStatus.DryDetected); } else if (cmd2 == 0x02) { logger.InfoFormat("Wet State detect in device {0}", Address.ToString()); OnDeviceStatusChanged(InsteonDeviceStatus.WetDetected); } else if (cmd2 == 0x04) { logger.InfoFormat("Heartbeat from device {0}", Address.ToString()); LastHeartbeat = DateTime.Now; OnDeviceStatusChanged(InsteonDeviceStatus.Heartbeat); } } else { base.OnMessage(message); } }
private void OnSetButtonPressed(InsteonMessage message) { if (Identity.IsEmpty) { var devCat = (byte)message.Properties[PropertyKey.DevCat]; var subCat = (byte)message.Properties[PropertyKey.SubCat]; var firmwareVersion = (byte)message.Properties[PropertyKey.FirmwareVersion]; Identity = new InsteonIdentity(devCat, subCat, firmwareVersion); } OnDeviceIdentified(); }
internal virtual void OnMessage(InsteonMessage message) { switch (message.MessageType) { case InsteonMessageType.Ack: PendingCommandAck(message); break; case InsteonMessageType.OnCleanup: OnDeviceStatusChanged(InsteonDeviceStatus.On); break; case InsteonMessageType.OffCleanup: OnDeviceStatusChanged(InsteonDeviceStatus.Off); break; case InsteonMessageType.FastOnCleanup: OnDeviceStatusChanged(InsteonDeviceStatus.On); OnDeviceStatusChanged(InsteonDeviceStatus.FastOn); break; case InsteonMessageType.FastOffCleanup: OnDeviceStatusChanged(InsteonDeviceStatus.Off); OnDeviceStatusChanged(InsteonDeviceStatus.FastOff); break; case InsteonMessageType.IncrementBeginBroadcast: dimmerDirection = message.Properties[PropertyKey.IncrementDirection] != 0 ? DimmerDirection.Up : DimmerDirection.Down; break; case InsteonMessageType.IncrementEndBroadcast: if (dimmerDirection == DimmerDirection.Up) { OnDeviceStatusChanged(InsteonDeviceStatus.Brighten); } else if (dimmerDirection == DimmerDirection.Down) { OnDeviceStatusChanged(InsteonDeviceStatus.Dim); } break; case InsteonMessageType.SetButtonPressed: OnSetButtonPressed(message); break; default: logger.Warn("Unhandled message type"); break; } }
private bool IsDuplicateMessage(InsteonMessage message) { lock (this.duplicates) { // determine if message key matches an entry in the list foreach (var item in this.duplicates) if (message.Key == item.Key) return true; // create a new duplicte entry var timer = new Timer(new TimerCallback(this.DuplicateMessageTimerCallback), message.Key, 0, 1000); this.duplicates.Add(message.Key, timer); return false; } }
private static bool DeviceLinkCleanupMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length <= offset + 8) return false; byte messageId = data[offset]; InsteonMessageType messageType = InsteonMessageType.DeviceLinkCleanup; Dictionary<PropertyKey, int> properties = new Dictionary<PropertyKey, int>(); properties[PropertyKey.LinkStatus] = data[offset + 1]; count = 2; message = new InsteonMessage(messageId, messageType, properties); return true; }
internal override void OnMessage(InsteonMessage message) { if (message.MessageType == InsteonMessageType.OnCleanup) { SensorStatus = IOState.Closed; OnDeviceStatusChanged(InsteonDeviceStatus.SensorTriggerOn); } else if (message.MessageType == InsteonMessageType.OffCleanup) { SensorStatus = IOState.Open; OnDeviceStatusChanged(InsteonDeviceStatus.SensorTriggerOff); } else { base.OnMessage(message); } }
internal override void OnMessage(InsteonMessage message) { var cmd2 = (byte)message.Properties[PropertyKey.Cmd2]; if (cmd2 == 0x03 && message.MessageType == InsteonMessageType.OnCleanup) { logger.WarnFormat("Low battery in device {0}", Address.ToString()); LowBattery = true; OnDeviceStatusChanged(InsteonDeviceStatus.LowBattery); } else if (cmd2 == 0x02 && message.MessageType == InsteonMessageType.OffCleanup) { logger.WarnFormat("Light detect in device {0}", Address.ToString()); OnDeviceStatusChanged(InsteonDeviceStatus.LightDetected); } else { base.OnMessage(message); } }
// if a command is pending determines whether the current message completes the pending command private void PendingCommandAck(InsteonMessage message) { lock (pendingEvent) { if (pendingCommand != null) { var cmd1 = message.Properties[PropertyKey.Cmd1]; if (System.Enum.IsDefined(typeof(InsteonDirectCommands), cmd1)) { var command = (InsteonDirectCommands)cmd1; if (pendingCommand.Value == command) { pendingCommand = null; pendingValue = 0; ackTimer.Change(Timeout.Infinite, Timeout.Infinite); // stop ACK timeout timer pendingEvent.Set(); // unblock any thread that may be waiting on the pending command } } } } }
private static bool DeviceLinkMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 9) return false; byte messageId = data[offset]; InsteonMessageType messageType = InsteonMessageType.DeviceLink; Dictionary<PropertyKey, int> properties = new Dictionary<PropertyKey, int>(); properties[PropertyKey.LinkType] = data[offset + 1]; properties[PropertyKey.LinkGroup] = data[offset + 2]; GetAddressProperty(PropertyKey.Address, data, offset + 3, out count, properties); properties[PropertyKey.DevCat] = data[offset + 6]; properties[PropertyKey.SubCat] = data[offset + 7]; properties[PropertyKey.FirmwareVersion] = data[offset + 8]; count = 9; message = new InsteonMessage(messageId, messageType, properties); return true; }
private static bool DeviceLinkRecordMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 9) return false; byte messageId = data[offset]; InsteonMessageType messageType = InsteonMessageType.DeviceLinkRecord; Dictionary<PropertyKey, int> properties = new Dictionary<PropertyKey, int>(); properties[PropertyKey.LinkRecordFlags] = data[offset + 1]; properties[PropertyKey.LinkGroup] = data[offset + 2]; properties[PropertyKey.LinkAddress] = new InsteonAddress(data[offset + 3], data[offset + 4], data[offset + 5]).Value; properties[PropertyKey.LinkData1] = data[offset + 6]; properties[PropertyKey.LinkData2] = data[offset + 7]; properties[PropertyKey.LinkData3] = data[offset + 8]; count = 9; message = new InsteonMessage(messageId, messageType, properties); return true; }
internal void OnMessage(InsteonMessage message) { if (message.MessageType == InsteonMessageType.DeviceLink) { InsteonAddress address = new InsteonAddress(message.Properties[PropertyKey.Address]); InsteonIdentity identity = new InsteonIdentity((byte)message.Properties[PropertyKey.DevCat], (byte)message.Properties[PropertyKey.SubCat], (byte)message.Properties[PropertyKey.FirmwareVersion]); InsteonDevice device = network.Devices.Add(address, identity); timer.Stop(); IsInLinkingMode = false; if (linkingMode.HasValue) { if (linkingMode != InsteonLinkMode.Delete) OnDeviceLinked(device); else OnDeviceUnlinked(device); } else { OnDeviceLinked(device); } } }
private void OnSetButtonPressed(InsteonMessage message) { if (this.Identity.IsEmpty) { var devCat = (byte)message.Properties[PropertyKey.DevCat]; var subCat = (byte)message.Properties[PropertyKey.DevCat]; var firmwareVersion = (byte)message.Properties[PropertyKey.DevCat]; this.Identity = new InsteonIdentity(devCat, subCat, firmwareVersion); } this.OnDeviceIdentified(); }
private void UpdateWaitItems(InsteonMessage message) { lock (this.waitList) { for (var i = 0; i < this.waitList.Count; ++i) { var item = this.waitList[i]; if (message.MessageId == item.MessageId) if (item.Message == null) { item.Message = message; item.MessageEvent.Set(); } } } }
// if a command is pending determines whether the current message completes the pending command private InsteonDeviceCommands? PendingCommandAck(InsteonMessage message) { lock (this.pendingEvent) { if (this.pendingCommand != null) { var cmd1 = message.Properties[PropertyKey.Cmd1]; if (Enum.IsDefined(typeof(InsteonDeviceCommands), cmd1)) { var command = (InsteonDeviceCommands)cmd1; if (this.pendingCommand.Value == command) { this.pendingCommand = null; this.pendingValue = 0; this.ackTimer.Change(Timeout.Infinite, Timeout.Infinite); // stop ACK timeout timer this.pendingEvent.Set(); // unblock any thread that may be waiting on the pending command return command; } } } } return null; }
private void OnMessage(InsteonMessage message) { if (message.Properties.ContainsKey(PropertyKey.FromAddress)) { var address = message.Properties[PropertyKey.FromAddress]; if (this.network.Devices.ContainsKey(address)) { Log.WriteLine("Device {0} received message {1}", InsteonAddress.Format(address), message.ToString()); var device = this.network.Devices.Find(address); device.OnMessage(message); } else if (message.MessageType == InsteonMessageType.SetButtonPressed) { // don't warn about SetButtonPressed message from unknown devices, because it may be from a device about to be added } else if (this.network.AutoAdd) { Log.WriteLine("Unknown device {0} received message {1}, adding device", InsteonAddress.Format(address), message.ToString()); var device = this.network.Devices.Add(new InsteonAddress(address), new InsteonIdentity()); device.OnMessage(message); } else { Log.WriteLine("WARNING: Unknown device {0} received message {1}", InsteonAddress.Format(address), message.ToString()); } } else { Log.WriteLine("Controller received message {0}", message.ToString()); this.network.Controller.OnMessage(message); } }
public EchoStatus TrySendEchoCommand(byte[] message, bool retryOnNak, int echoLength, out Dictionary<PropertyKey, int> properties) { this.echoMessage = null; this.echoCommand = true; var status = this.TrySend(message, retryOnNak, echoLength); this.echoCommand = false; properties = this.echoMessage != null ? this.echoMessage.Properties : null; this.echoMessage = null; return status; }
private static bool GetIMInfo(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 7) return false; byte messageId = data[offset]; InsteonMessageType messageType = InsteonMessageType.GetIMInfo; Dictionary<PropertyKey, int> properties = new Dictionary<PropertyKey, int>(); properties[PropertyKey.Address] = new InsteonAddress(data[offset + 1], data[offset + 2], data[offset + 3]).Value; properties[PropertyKey.DevCat] = data[offset + 4]; properties[PropertyKey.SubCat] = data[offset + 5]; properties[PropertyKey.FirmwareVersion] = data[offset + 6]; count = 7; message = new InsteonMessage(messageId, messageType, properties); return true; }
public static bool ProcessMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length <= offset) return false; switch (data[offset]) { case 0x50: return InsteonMessageProcessor.StandardMessage(data, offset, out count, out message); case 0x51: return InsteonMessageProcessor.ExtendedMessage(data, offset, out count, out message); case 0x53: return InsteonMessageProcessor.DeviceLinkMessage(data, offset, out count, out message); case 0x57: return InsteonMessageProcessor.DeviceLinkRecordMessage(data, offset, out count, out message); case 0x58: return InsteonMessageProcessor.DeviceLinkCleanupMessage(data, offset, out count, out message); case 0x60: return InsteonMessageProcessor.GetIMInfo(data, offset, out count, out message); } return false; }
private static bool StandardMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 10) return false; byte messageId = data[offset]; Dictionary<PropertyKey, int> properties = new Dictionary<PropertyKey, int>(); GetAddressProperty(PropertyKey.FromAddress, data, offset + 1, out count, properties); GetMessageFlagProperty(data, offset, out count, properties); if (properties[PropertyKey.MessageFlagsBroadcast] == 0) GetAddressProperty(PropertyKey.ToAddress, data, offset + 4, out count, properties); properties[PropertyKey.Cmd1] = data[offset + 8]; properties[PropertyKey.Cmd2] = data[offset + 9]; count = 10; InsteonMessageType messageType = GetMessageType(data, offset, properties); message = new InsteonMessage(messageId, messageType, properties); return true; }
private static bool ExtendedMessage(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 23) return false; StandardMessage(data, offset, out count, out message); message.Properties[PropertyKey.Data1] = data[offset + 10]; message.Properties[PropertyKey.Data2] = data[offset + 11]; message.Properties[PropertyKey.Data3] = data[offset + 12]; message.Properties[PropertyKey.Data4] = data[offset + 13]; message.Properties[PropertyKey.Data5] = data[offset + 14]; message.Properties[PropertyKey.Data6] = data[offset + 15]; message.Properties[PropertyKey.Data7] = data[offset + 16]; message.Properties[PropertyKey.Data8] = data[offset + 17]; message.Properties[PropertyKey.Data9] = data[offset + 18]; message.Properties[PropertyKey.Data10] = data[offset + 19]; message.Properties[PropertyKey.Data11] = data[offset + 20]; message.Properties[PropertyKey.Data12] = data[offset + 21]; message.Properties[PropertyKey.Data13] = data[offset + 22]; message.Properties[PropertyKey.Data14] = data[offset + 23]; count = 23; return true; }
internal void OnMessage(InsteonMessage message) { switch (message.MessageType) { case InsteonMessageType.Ack: var cmd = this.PendingCommandAck(message); if (cmd.HasValue) { // This feels wrong, but I'm not seeing the 'DeviceStatusChanged' as a result of setting the status. // Could probably use some sort of 'map' here to map command to status. switch (cmd.Value) { case InsteonDeviceCommands.On: this.OnDeviceStatusChanged(InsteonDeviceStatus.On); break; case InsteonDeviceCommands.Off: this.OnDeviceStatusChanged(InsteonDeviceStatus.Off); break; } } break; case InsteonMessageType.OnCleanup: this.OnDeviceStatusChanged(InsteonDeviceStatus.On); break; case InsteonMessageType.OffCleanup: this.OnDeviceStatusChanged(InsteonDeviceStatus.Off); break; case InsteonMessageType.FastOnCleanup: this.OnDeviceStatusChanged(InsteonDeviceStatus.On); this.OnDeviceStatusChanged(InsteonDeviceStatus.FastOn); break; case InsteonMessageType.FastOffCleanup: this.OnDeviceStatusChanged(InsteonDeviceStatus.Off); this.OnDeviceStatusChanged(InsteonDeviceStatus.FastOff); break; case InsteonMessageType.IncrementBeginBroadcast: this.dimmerDirection = message.Properties[PropertyKey.IncrementDirection] != 0 ? DimmerDirection.Up : DimmerDirection.Down; break; case InsteonMessageType.IncrementEndBroadcast: if (this.dimmerDirection == DimmerDirection.Up) { this.OnDeviceStatusChanged(InsteonDeviceStatus.Brighten); } else if (this.dimmerDirection == DimmerDirection.Down) { this.OnDeviceStatusChanged(InsteonDeviceStatus.Dim); } break; case InsteonMessageType.SetButtonPressed: this.OnSetButtonPressed(message); break; } }