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); } var messageId = data[offset]; var 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; var 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); }
private static bool ButtonEvent(byte[] data, int offset, out int count, out InsteonMessage message) { //todo: something to actually process this. count = 0; message = null; return(false); }
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 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; }
public EchoStatus TrySendEchoCommand(byte[] message, bool retryOnNak, int echoLength, out Dictionary <PropertyKey, int> properties) { echoMessage = null; echoCommand = true; EchoStatus status = TrySend(message, retryOnNak, echoLength); echoCommand = false; properties = echoMessage?.Properties; echoMessage = null; return(status); }
private void OnMessage(InsteonMessage message) { if (message.Properties.ContainsKey(PropertyKey.FromAddress)) { int address = message.Properties[PropertyKey.FromAddress]; if (network.Devices.ContainsKey(address)) { logger.DebugFormat("Device {0} received message {1}", InsteonAddress.Format(address), message.ToString()); InsteonDevice device = 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 (network.AutoAdd) { logger.DebugFormat("Unknown device {0} received message {1}, adding device", InsteonAddress.Format(address), message.ToString()); //note: due to how messages are handled and how devices cannot receive new messages while pending sends (I think) we should only add on certain message types. // right now I've only tested devices where we get broadcast messages. Thus, we wait until the last message received. if (message.MessageType == InsteonMessageType.SuccessBroadcast) { InsteonIdentity?id; // TODO: probably shouldn't be in a while loop. Need a better way to address this while (!network.Controller.TryGetLinkIdentity(new InsteonAddress(address), out id)) { if (id != null) { InsteonDevice device = network.Devices.Add(new InsteonAddress(address), id.Value); device.OnMessage(message); } } } } else { logger.WarnFormat("Unknown device {0} received message {1}. Could be Identification process.", InsteonAddress.Format(address), message.ToString()); } } else { logger.DebugFormat("Controller received message {0}", message.ToString()); network.Controller.OnMessage(message); } }
private bool IsDuplicateMessage(InsteonMessage message) { lock (duplicates) { // determine if message key matches an entry in the list if (duplicates.Any(item => message.Key == item.Key)) { return(true); } // create a new duplicte entry Timer timer = new Timer(DuplicateMessageTimerCallback, message.Key, 0, 1000); duplicates.Add(message.Key, timer); return(false); } }
private bool IsDuplicateMessage(InsteonMessage message) { lock (duplicates) { // determine if message key matches an entry in the list if (duplicates.Any(item => message.Key == item.Key)) { return true; } // create a new duplicte entry Timer timer = new Timer(DuplicateMessageTimerCallback, message.Key, 0, 1000); 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; } var messageId = data[offset]; var properties = new Dictionary<PropertyKey, int>(); properties[PropertyKey.LinkStatus] = data[offset + 1]; count = 2; message = new InsteonMessage(messageId, InsteonMessageType.DeviceLinkCleanup, 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); } }
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); } var messageId = data[offset]; var properties = new Dictionary <PropertyKey, int>(); properties[PropertyKey.LinkStatus] = data[offset + 1]; count = 2; message = new InsteonMessage(messageId, InsteonMessageType.DeviceLinkCleanup, properties); return(true); }
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); } }
private static bool GetInsteonModemInfo(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 7) { return(false); } var messageId = data[offset]; var 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, InsteonMessageType.GetInsteonModemInfo, properties); return(true); }
private void UpdateWaitItems(InsteonMessage message) { lock (waitList) { for (int i = 0; i < waitList.Count; ++i) { WaitItem item = waitList[i]; if (message.MessageId == item.MessageId) { if (item.MessageType == null || item.MessageType.Value == message.MessageType) { if (item.Message == null) { item.Message = message; item.MessageEvent.Set(); } } } } } }
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 ((InsteonModemSerialCommand)data[offset]) { case InsteonModemSerialCommand.StandardMessage: return(StandardMessage(data, offset, out count, out message)); case InsteonModemSerialCommand.ExtendedMessage: return(ExtendedMessage(data, offset, out count, out message)); case InsteonModemSerialCommand.DeviceLinkingCompleted: return(DeviceLinkMessage(data, offset, out count, out message)); case InsteonModemSerialCommand.DeviceLinkRecord: return(DeviceLinkRecordMessage(data, offset, out count, out message)); case InsteonModemSerialCommand.DeviceCleanup: return(DeviceLinkCleanupMessage(data, offset, out count, out message)); case InsteonModemSerialCommand.GetImInfo: return(GetInsteonModemInfo(data, offset, out count, out message)); case InsteonModemSerialCommand.ButtonEventReport: return(ButtonEvent(data, offset, out count, out message)); default: logger.DebugFormat("Received message {0} but currently not processing it.", (InsteonModemSerialCommand)data[offset]); break; } return(false); }
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); } var messageId = data[offset]; var 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, InsteonMessageType.DeviceLinkRecord, properties); return(true); }
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); } var messageId = data[offset]; var 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, InsteonMessageType.DeviceLink, properties); return(true); }
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; } var messageId = data[offset]; var 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, InsteonMessageType.DeviceLink, 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; } var messageId = data[offset]; var 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, InsteonMessageType.DeviceLinkRecord, properties); return true; }
internal void OnMessage(InsteonMessage message) { if (message.MessageType == InsteonMessageType.DeviceLink) { var address = new InsteonAddress(message.Properties[PropertyKey.Address]); var identity = new InsteonIdentity((byte)message.Properties[PropertyKey.DevCat], (byte)message.Properties[PropertyKey.SubCat], (byte)message.Properties[PropertyKey.FirmwareVersion]); var 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 static bool GetInsteonModemInfo(byte[] data, int offset, out int count, out InsteonMessage message) { message = null; count = 0; if (data.Length < offset + 7) { return false; } var messageId = data[offset]; var 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, InsteonMessageType.GetInsteonModemInfo, properties); return true; }
private static bool ButtonEvent(byte[] data, int offset, out int count, out InsteonMessage message) { //todo: something to actually process this. count = 0; message = null; return false; }
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 void OnMessage(InsteonMessage message) { if (message.Properties.ContainsKey(PropertyKey.FromAddress)) { int address = message.Properties[PropertyKey.FromAddress]; if (network.Devices.ContainsKey(address)) { logger.DebugFormat("Device {0} received message {1}", InsteonAddress.Format(address), message.ToString()); InsteonDevice device = 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 (network.AutoAdd) { logger.DebugFormat("Unknown device {0} received message {1}, adding device", InsteonAddress.Format(address), message.ToString()); //note: due to how messages are handled and how devices cannot receive new messages while pending sends (I think) we should only add on certain message types. // right now I've only tested devices where we get broadcast messages. Thus, we wait until the last message received. if (message.MessageType == InsteonMessageType.SuccessBroadcast) { InsteonIdentity? id; // TODO: probably shouldn't be in a while loop. Need a better way to address this while (!network.Controller.TryGetLinkIdentity(new InsteonAddress(address), out id)) { if (id != null) { InsteonDevice device = network.Devices.Add(new InsteonAddress(address), id.Value); device.OnMessage(message); } } } } else { logger.WarnFormat("Unknown device {0} received message {1}. Could be Identification process.", InsteonAddress.Format(address), message.ToString()); } } else { logger.DebugFormat("Controller received message {0}", message.ToString()); network.Controller.OnMessage(message); } }
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 ((InsteonModemSerialCommand)data[offset]) { case InsteonModemSerialCommand.StandardMessage: return StandardMessage(data, offset, out count, out message); case InsteonModemSerialCommand.ExtendedMessage: return ExtendedMessage(data, offset, out count, out message); case InsteonModemSerialCommand.DeviceLinkingCompleted: return DeviceLinkMessage(data, offset, out count, out message); case InsteonModemSerialCommand.DeviceLinkRecord: return DeviceLinkRecordMessage(data, offset, out count, out message); case InsteonModemSerialCommand.DeviceCleanup: return DeviceLinkCleanupMessage(data, offset, out count, out message); case InsteonModemSerialCommand.GetImInfo: return GetInsteonModemInfo(data, offset, out count, out message); case InsteonModemSerialCommand.ButtonEventReport: return ButtonEvent(data, offset, out count, out message); default: logger.DebugFormat("Received message {0} but currently not processing it.", (InsteonModemSerialCommand)data[offset]); break; } return false; }
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(); }
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; } var messageId = data[offset]; var 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; var messageType = GetMessageType(data, offset, properties); message = new InsteonMessage(messageId, messageType, properties); return true; }
// 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 } } } } }
public EchoStatus TrySendEchoCommand(byte[] message, bool retryOnNak, int echoLength, out Dictionary<PropertyKey, int> properties) { echoMessage = null; echoCommand = true; EchoStatus status = TrySend(message, retryOnNak, echoLength); echoCommand = false; properties = echoMessage?.Properties; echoMessage = null; return status; }