/// <summary>
        /// A response a received from node.
        /// </summary>
        /// <param name="resposne">Response message.</param>
        public void ResponseReceived(MessageFromDto resposne)
        {
            if (resposne?.Node != null)
            {
                var controller = (ControllerDto)resposne.Node;

                switch (resposne.Command)
                {
                    case MessageCommand.GetDeviceCapabilities:
                        GetApiCapabilitiesResponse(controller, resposne);
                        break;
                    case MessageCommand.GetHomeId:
                        GetHomeIdResponse(controller, resposne);
                        break;
                    case MessageCommand.GetVersion:
                        GetZVersionResponse(controller, resposne);
                        break;
                    case MessageCommand.GetControllerNodes:
                        GetControllerNodesResponse(controller, resposne);
                        break;
                    case MessageCommand.GetNodeProtocol:
                        GetNodeProtocolResponse(controller, resposne);
                        break;
                }
            }
        }
        /// <summary>
        /// Convert a serial mesage to business message.
        /// </summary>
        /// <param name="message">Serial message.</param>
        /// <returns>Business message.</returns>
        public MessageFromDto Convert(MessageDto message)
        {
            var result = new MessageFromDto {Header = message.Header};

            if (message.Header == MessageHeader.StartOfFrame)
            {
                result.IsValid = ValidMessage(message.Content);
                if (result.IsValid && message.Content.Count > 3)
                {
                    result.Type = (MessageType)message.Content[2];
                    result.Command = (MessageCommand)message.Content[3];

                    if (result.Type == MessageType.Request && message.Content.Count > 8)
                    {
                        result.ZIdentifier = message.Content[5];
                        result.RequestCommand = (RequestCommandClass) message.Content[7];
                        result.Content = message.Content.Skip(8).Take(message.Content[6] - 1).ToList();
                    }
                    else if (message.Content.Count > 4)
                    {
                        result.Content = message.Content.Skip(4).Take(message.Content.Count - 5).ToList();
                    }
                }
            }
            else
            {
                result.IsValid = true;
                result.Type = MessageType.Response;
                result.Content = message.Content;
            }

            return result;
        }
        /// <summary>
        /// No request received.
        /// </summary>
        /// <param name="request">Received message.</param>
        public void RequestRecevied(MessageFromDto request)
        {
            if (request.Content.Count > 6 && request.Content[0] == (byte)ConstructorAction.Report)
            {
                request.Node.ConstructorIdentifier = string.Concat(request.Content[1].ToString("X2"), request.Content[2].ToString("X2"));
                // content 3 and 4 are product type
                request.Node.ProductIdentifier = string.Concat(request.Content[5].ToString("X2"), request.Content[6].ToString("X2"));
            }

            WaitReport.Set();
        }
        /// <summary>
        /// A request is received.
        /// </summary>
        /// <param name="receivedMessage">Received request.</param>
        /// <returns>Process state.</returns>
        public void RequestRecevied(MessageFromDto receivedMessage)
        {
            // update state of switch
            if (receivedMessage.Content.Count >= 2)
            {
                // report action
                var switchAction = (SwitchBinaryAction)receivedMessage.Content[0];
                if (switchAction == SwitchBinaryAction.Report)
                {
                    // Update node value
                    var valueLength = receivedMessage.Content.Count - 1;
                    var rawValue = receivedMessage.Content.Skip(receivedMessage.Content.Count - valueLength).Take(valueLength).ToList();
                    receivedMessage.Node.Value = rawValue;

                    // release event
                    WaitReportEvent.Set();
                }
            }
        }
 /// <summary>
 /// A response a received from node.
 /// </summary>
 /// <param name="resposne">Response message.</param>
 public void ResponseReceived(MessageFromDto resposne)
 {
     WaitEvent.Set();
 }
 /// <summary>
 /// A request is recevied from node.
 /// </summary>
 /// <param name="request">Received message.</param>
 public void RequestRecevied(MessageFromDto request)
 {
 }
 /// <summary>
 /// Acknowlegment received.
 /// </summary>
 /// <param name="receivedMessage">Recevied message.</param>
 public void AcknowlegmentReceived(MessageFromDto receivedMessage)
 {
     WaitAcknowledgment.Set();
 }
 /// <summary>
 /// A request is recevied from node.
 /// </summary>
 /// <param name="request">Received message.</param>
 public void RequestRecevied(MessageFromDto request)
 {
     // Not used
 }
        /// <summary>
        /// Execute command "Get version".
        /// </summary>
        /// <param name="controller">Concerned controller.s</param>
        /// <param name="receivedMessage">Message received.</param>
        private static void GetZVersionResponse(ControllerDto controller, MessageFromDto receivedMessage)
        {
            // complete controller
            if (receivedMessage.Content.Count >= 3)
            {
                var end = receivedMessage.Content.TakeWhile(b => b != '\0').Count();
                controller.ZVersion = Encoding.ASCII.GetString(receivedMessage.Content.Take(end).ToArray());
                controller.DeviceClass = (DeviceClass)receivedMessage.Content[receivedMessage.Content.Count - 1];
            }

            // release event
            WaitEvent.Set();
        }
        /// <summary>
        /// Process the response to get a node protocol.
        /// </summary>
        /// <param name="controller">Concerned controller.s</param>
        /// <param name="receivedMessage">Message received.</param>
        private static void GetNodeProtocolResponse(ControllerDto controller, MessageFromDto receivedMessage)
        {
            if (receivedMessage.Content.Count >= 5)
            {
                var node = controller.Nodes.FirstOrDefault(x => x.ZIdentifier == receivedMessage.ZIdentifier);
                if (node != null)
                {
                    node.DeviceClass = (DeviceClass) receivedMessage.Content[3];
                    node.DeviceClassGeneric = (DeviceClassGeneric) receivedMessage.Content[4];
                }
            }

            // release event
            WaitEvent.Set();
        }
        /// <summary>
        /// Execute command "Get home id" and node identifier.
        /// </summary>
        /// <param name="controller">Concerned controller.s</param>
        /// <param name="receivedMessage">Message received.</param>
        private static void GetHomeIdResponse(ControllerDto controller, MessageFromDto receivedMessage)
        {
            // complete controller
            if (receivedMessage.Content.Count >= 5)
            {
                controller.HomeIdentifier = BitConverter.ToString(receivedMessage.Content.Take(4).ToArray());
                controller.ZIdentifier = receivedMessage.Content.Last();
            }

            // release event
            WaitEvent.Set();
        }
        /// <summary>
        /// Execute command to get note list.
        /// </summary>
        /// <param name="controller">Concerned controller.s</param>
        /// <param name="receivedMessage">Message received.</param>
        private static void GetControllerNodesResponse(ControllerDto controller, MessageFromDto receivedMessage)
        {
            if (receivedMessage.Content.Count >= 29)
            {
                controller.Nodes = new List<DeviceDto>();
                for (var i = 3; i < 32; i++)
                {
                    var byteData = receivedMessage.Content[i];
                    for (var b = 0; b < 8; b++)
                    {
                        if ((byteData & (byte) Math.Pow(2, b)) == (byte) Math.Pow(2, b))
                        {
                            int zId = ((i - 3)*8) + b + 1;

                            if (zId == controller.ZIdentifier)
                            {
                                controller.Nodes.Add(controller);
                            }
                            else
                            {
                                controller.Nodes.Add(new DeviceDto
                                {
                                    HomeIdentifier = controller.HomeIdentifier,
                                    ZIdentifier = zId
                                });
                            }
                        }
                    }
                }
            }
            else
            {
                receivedMessage.Node = null;
            }

            // release event
            WaitEvent.Set();
        }
        /// <summary>
        /// Execute command to get COM capabilitis.
        /// </summary>
        /// <param name="controller">Concerned controller.s</param>
        /// <param name="receivedMessage">Message received.</param>
        private static void GetApiCapabilitiesResponse(ControllerDto controller, MessageFromDto receivedMessage)
        {
            if (receivedMessage.Content.Count >= 6)
            {
                decimal version;
                decimal.TryParse(string.Concat(receivedMessage.Content[0], ",", receivedMessage.Content[1]), out version);
                controller.ApiVersion = version;

                controller.ConstructorIdentifier = string.Concat(receivedMessage.Content[2].ToString("00"), receivedMessage.Content[3].ToString("00"));
                controller.ProductType = string.Concat(receivedMessage.Content[3].ToString("00"), receivedMessage.Content[4].ToString("00"));
                controller.ProductIdentifier = string.Concat(receivedMessage.Content[5].ToString("00"), receivedMessage.Content[6].ToString("00"));
                controller.ApiCapabilities = receivedMessage.Content.Skip(7).ToList();
            }

            // release event
            WaitEvent.Set();
        }
 /// <summary>
 /// Process a request received.
 /// </summary>
 /// <param name="received">Recevied message.</param>
 /// <returns>Process state.</returns>
 internal static void RequestReceived(MessageFromDto received)
 {
     // process request
     var processAttr = ReflectionHelper.GetEnumValueAttribute<RequestCommandClass, DataReceivedAttribute>(received.RequestCommand);
     if (processAttr != null)
     {
         var iDevice = ReflectionHelper.CreateInstance<IDevice>(processAttr.ClassType);
         iDevice?.RequestRecevied(received);
     }
 }
 /// <summary>
 /// Receive a response message from binary switch.
 /// </summary>
 /// <param name="receivedMessage">Received message.</param>
 public void ResponseReceived(MessageFromDto receivedMessage)
 {
     // if message received is good, wait event is released.
     if (receivedMessage.Content.Count == 1 && receivedMessage.Content.First() == 0x01)
     {
         WaitResponseEvent.Set();
     }
 }