/// <summary>
 /// Query the type from all the known devices.
 /// </summary>
 private void SetupAllDevices()
 {
     foreach (LinkingRecord record in this.linkedDevices.Values)
     {
         if (provider != null)
         {
             Tuple<byte, byte> categories = provider.GetDeviceCategory(record.Address);
             if (categories != null)
             {
                 AddDevice(record.Address, categories.Item1, categories.Item2);
                 continue;
             }
         }
         InsteonPacket packet = new InsteonPacket(record.Address, InsteonPacket.Command.IdRequest);
         InsteonPacket response;
         if (SendDirectInsteonPacket(packet, out response) == PowerLineModemMessage.MessageResponse.Ack)
         {
             log.InfoFormat("Id Request Acked {0}", response.FromAddress);
         }
         else
         {
             log.InfoFormat("Id Request Failed {0}", record.Address);
         }
     }
 }
 /// <summary>
 /// Sends the specified direct message and waits for a response.
 /// </summary>
 /// <param name="packet">Packet to send</param>
 /// <param name="response">The response from the device</param>
 /// <returns>the result of the call</returns>
 public PowerLineModemMessage.MessageResponse SendDirectInsteonPacket(InsteonPacket packet, out InsteonPacket response)
 {
     // Only one packet at a time.
     lock (this)
     {
         if (packet.Flags.MessageType != InsteonPacket.InsteonFlags.MessageTypeEnum.Direct)
         {
             response = null;
             return PowerLineModemMessage.MessageResponse.Invalid;
         }
         // Send only one direct packet at a time.
         PowerLineModemMessage.MessageResponse messageResponse;
         StandardMessage message = new StandardMessage(PowerLineModemMessage.Message.SendInsteonMessage, packet);
         this.sendingPacket = packet;
         messageResponse = port.SendCommand(message);
         if (messageResponse == PowerLineModemMessage.MessageResponse.Ack)
         {
             // We should get an ack back for this message.
             if (this.linkingEvent.WaitOne(5000))
             {
                 // See if we got back an ack or nack.
                 if (this.receivedPacket.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.NackDirect)
                 {
                     messageResponse = PowerLineModemMessage.MessageResponse.Nack;
                 }
                 response = this.receivedPacket;
             }
             else
             {
                 response = null;
                 return PowerLineModemMessage.MessageResponse.Unknown;
             }
         }
         else
         {
             response = null;
         }
         return messageResponse;
     }
 }
 /// <summary>
 /// Called when a message comes in from the modem.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="args"></param>
 void port_ReceivedMessage(object sender, RecievedMessageEventArgs args)
 {
     switch (args.Message.MessageType)
     {
         case PowerLineModemMessage.Message.AllLinkRecordResponse:
             // If we get this, then query the device for more details.
             AllLinkRecordResponse response = (AllLinkRecordResponse)args.Message;
             this.linkedDevices[response.Record.Address] = response.Record;
             this.linkingEvent.Set();
             break;
         case PowerLineModemMessage.Message.StandardMessageReceived:
             StandardMessage standardMessage = (StandardMessage)args.Message;
             if (standardMessage.Packet.FromAddress.Equals(this.sendingPacket.FromAddress))
             {
                 if (standardMessage.Packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.AckDirect ||
                     standardMessage.Packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.NackDirect)
                 {
                     this.receivedPacket = standardMessage.Packet;
                     this.linkingEvent.Set();
                     break;
                 }
             }
             // Find the device and send the packet there.
             if (this.devices.ContainsKey(standardMessage.Packet.FromAddress))
             {
                 DeviceBase device = this.devices[standardMessage.Packet.FromAddress];
                 if (device.handleInsteonPacket(standardMessage.Packet)) {
                     if (DeviceChanged != null){
                         DeviceChanged(this, new DeviceChangedEventArgs(device));
                     }
                     }
             }
             else
             {
                 // If this is a broadcast set button pressed, add into the device list.
                 if (standardMessage.Packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.Broadcast &&
                     standardMessage.Packet.Command1 == (byte)InsteonPacket.BroadcastCommand.SetButtonPressed)
                 {
                     byte category = standardMessage.Packet.ToAddress.Address[0];
                     byte subCategory = standardMessage.Packet.ToAddress.Address[1];
                     AddDevice(standardMessage.Packet.FromAddress, category, subCategory);
                 }
             }
             break;
         case PowerLineModemMessage.Message.ExtendedMessageReceived:
             ExtendedMessage extendedMessage = (ExtendedMessage)args.Message;
             if (extendedMessage.Packet.FromAddress.Equals(this.sendingPacket.FromAddress))
             {
                 if (extendedMessage.Packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.AckDirect ||
                     extendedMessage.Packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.NackDirect)
                 {
                     this.receivedPacket = extendedMessage.Packet;
                     this.linkingEvent.Set();
                     break;
                 }
             }
             // Find the device and send the packet there.
             if (this.devices.ContainsKey(extendedMessage.Packet.FromAddress))
             {
                 DeviceBase device = this.devices[extendedMessage.Packet.FromAddress];
                 if (device.handleInsteonPacket(extendedMessage.Packet))
                 {
                     if (DeviceChanged != null)
                     {
                         DeviceChanged(this, new DeviceChangedEventArgs(device));
                     }
                 }
             }
             break;
     }
 }
 /// <summary>
 /// Sends a standard command off to do stuff.
 /// </summary>
 /// <param name="cmd">The command to send</param>
 /// <param name="command2">The second part of the command to update</param>
 /// <returns></returns>
 protected Messages.PowerLineModemMessage.MessageResponse SendStandardCommandWithResponse(InsteonPacket.Command cmd, byte command2, out byte outCommand2)
 {
     InsteonPacket packet = new InsteonPacket(this.deviceId, cmd);
     packet.Command2 |= command2;
     InsteonPacket response;
     Messages.PowerLineModemMessage.MessageResponse ret = coms.SendDirectInsteonPacket(packet, out response);
     if (ret == Messages.PowerLineModemMessage.MessageResponse.Ack)
     {
         outCommand2 = response.Command2;
     }
     else
     {
         outCommand2 = 0;
     }
     return ret;
 }
 internal override bool handleInsteonPacket(InsteonPacket packet)
 {
     bool changed = false;
     if (packet.Flags.MessageType == InsteonPacket.InsteonFlags.MessageTypeEnum.GroupBroadcast)
     {
         // Do other stuff in here.
     }
     else
     {
         InsteonPacket.Command cmd = packet.ComposedCommand;
         switch (cmd)
         {
             case InsteonPacket.Command.LightOn:
             case InsteonPacket.Command.LightOnFast:
                 this.onLevel = packet.Command2;
                 changed = true;
                 break;
             case InsteonPacket.Command.LightOff:
             case InsteonPacket.Command.LightOffFast:
                 this.onLevel = 0;
                 changed = true;
                 break;
         }
     }
     return base.handleInsteonPacket(packet) || changed;
 }
 /// <summary>
 /// Sends an extended command off to do stuff.
 /// </summary>
 /// <param name="cmd">The command to send</param>
 /// <param name="command2">The second part of the command to update</param>
 /// <returns></returns>
 protected Messages.PowerLineModemMessage.MessageResponse SendExtendedCommandWithResponse(InsteonPacket.ExtendedCommand cmd, byte command2, byte[] data, out InsteonPacket response)
 {
     InsteonPacket packet = new InsteonPacket(this.deviceId, cmd, command2, data);
     return coms.SendDirectInsteonPacket(packet, out response);
 }
 /// <summary>
 /// Sends a standard command off to do stuff.
 /// </summary>
 /// <param name="cmd">The command to send</param>
 /// <param name="command2">The second part of the command to update</param>
 /// <returns></returns>
 protected Messages.PowerLineModemMessage.MessageResponse SendStandardCommand(InsteonPacket.Command cmd, byte command2)
 {
     InsteonPacket packet = new InsteonPacket(this.deviceId, cmd);
     packet.Command2 |= command2;
     InsteonPacket response;
     return coms.SendDirectInsteonPacket(packet, out response);
 }
 /// <summary>
 /// Sends an extended command to the specified device.
 /// </summary>
 /// <param name="cmd"></param>
 /// <param name="data"></param>
 /// <returns></returns>
 protected Messages.PowerLineModemMessage.MessageResponse SendExtendedCommand(InsteonPacket.ExtendedCommand cmd, byte[] data)
 {
     return this.SendExtendedCommand(cmd, 0, data);
 }
 /// <summary>
 /// Handle an insteon packet from somewhere else.
 /// </summary>
 /// <param name="packet">the incoming packet</param>
 /// <returns>true if something changed</returns>
 internal virtual bool handleInsteonPacket(InsteonPacket packet)
 {
     return false;
 }
 /// <summary>
 /// Gets the text string from the device.
 /// </summary>
 /// <param name="outTextString"></param>
 /// <returns></returns>
 public Messages.PowerLineModemMessage.MessageResponse GetTextString(out string outTextString)
 {
     outTextString = textString;
     if (textString == null)
     {
         InsteonPacket packet = new InsteonPacket(this.deviceId, InsteonPacket.Command.ProductDataRequest, 0x2);
         packet.Flags.ExtendedMessage = true;
         packet.UserData = new byte[14];
         InsteonPacket response;
         Messages.PowerLineModemMessage.MessageResponse ret = coms.SendDirectInsteonPacket(packet, out response);
         if (ret == Messages.PowerLineModemMessage.MessageResponse.Ack)
         {
             // Response should be an extended message.
             if (response.Flags.ExtendedMessage)
             {
                 int i;
                 for (i = 0; i < response.UserData.Length; i++)
                 {
                     if (response.UserData[i] == 0)
                     {
                         break;
                     }
                 }
                 textString = System.Text.Encoding.ASCII.GetString(response.UserData, 0, i);
                 outTextString = textString;
                 return ret;
             }
         }
         return ret;
     }
     return Messages.PowerLineModemMessage.MessageResponse.Ack;
 }
 public StandardMessage(Message message, byte[] data)
     : base(message)
 {
     Packet = new InsteonPacket(data);
 }
 public StandardMessage(Message message, InsteonPacket packet)
     : base(message)
 {
     Packet = packet;
 }