/// <summary>
        /// Get the value of the device.
        /// </summary>
        /// <param name="controller">Concerned controller.</param>
        /// <param name="device">Concerned device.</param>
        /// <returns>True if device value is completed.</returns>
        public bool Get(ControllerDto controller, DeviceDto device)
        {
            // send message
            if (MessageProcessBusiness.Send(controller, CreateCommandMessage(controller, device.ZIdentifier)))
            {
                // wait for ack and response
                WaitAcknowledgment.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitEvent.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitReport.WaitOne(DeviceConstants.WaitEventTimeout);
            }

            return !string.IsNullOrEmpty(device.ConstructorIdentifier) && !string.IsNullOrEmpty(device.ProductIdentifier);
        }
        /// <summary>
        /// Get switch value.
        /// </summary>
        /// <param name="controller">Concerned controller.</param>
        /// <param name="node">Concerned node.</param>
        /// <returns>Value of node.</returns>
        public bool Get(ControllerDto controller, DeviceDto node)
        {
            // send message
            node.Value = null;
            if (MessageProcessBusiness.Send(controller, CreateCommandMessage(node, new List<byte> {(byte) SwitchBinaryAction.Get})))
            {
                // wait for response from controller
                WaitAcknowledgment.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitResponseEvent.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitReportEvent.WaitOne(DeviceConstants.WaitEventTimeout);
            }

            return node.Value != null;
        }
        /// <summary>
        /// Get the current value of a node.
        /// </summary>
        /// <param name="controller">Controller to use.</param>
        /// <param name="node">Node to call.</param>
        /// <returns>Node value.</returns>
        internal static bool Get(ControllerDto controller, DeviceDto node)
        {
            var result = false;

            if (node.DeviceClassGeneric != DeviceClassGeneric.Other)
            {
                var processAttr = ReflectionHelper.GetEnumValueAttribute<DeviceClassGeneric, DataReceivedAttribute>(node.DeviceClassGeneric);
                if (processAttr != null)
                {
                    var iDevice = ReflectionHelper.CreateInstance<IDevice>(processAttr.ClassType);
                    if(iDevice != null) result = iDevice.Get(controller, node);
                }
            }

            return result;
        }
        /// <summary>
        /// Configure a parameter.
        /// </summary>
        /// <param name="controller">Controller used to send message.</param>
        /// <param name="node">Concerned message.</param>
        /// <param name="parameter">Parameter identifier.</param>
        /// <param name="value">Parameter value.</param>
        /// <returns>True if configuration is OK.</returns>
        internal static bool Set(ControllerDto controller, DeviceDto node, byte parameter, List<byte> value)
        {
            var content = new List<byte> { (byte)ConfigurationAction.Set, parameter, (byte)value.Count };
            content.AddRange(value);

            // send message
            if (MessageProcessBusiness.Send(controller, CreateCommandMessage(node, content)))
            {
                // wait for ack and response
                WaitAcknowledgment.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitEvent.WaitOne(DeviceConstants.WaitEventTimeout);
            }

            return true;
        }
 /// <summary>
 /// Set the device value.
 /// </summary>
 /// <param name="controller">Concerned controller.</param>
 /// <param name="device">Concerned device.</param>
 /// <param name="value">Value to set. First byte is parameter identifier, next is parameter value.</param>
 /// <returns>True if value is setted.</returns>
 public bool Set(ControllerDto controller, DeviceDto device, List<byte> value)
 {
     return true;
 }
 /// <summary>
 /// Get the value of the device.
 /// </summary>
 /// <param name="controller">Concerned controller.</param>
 /// <param name="device">Concerned device.</param>
 /// <returns>True if device value is completed.</returns>
 public bool Get(ControllerDto controller, DeviceDto device)
 {
     return false;
 }
        /// <summary>
        /// Create a command message.
        /// </summary>
        /// <param name="node">Concerned node.</param>
        /// <param name="content">Content to send.</param>
        /// <returns>Message.</returns>
        private static MessageToDto CreateCommandMessage(DeviceDto node, List<byte> content)
        {
            var result = new MessageToDto
            {
                Command = MessageCommand.SendData,
                Content = new List<byte> { (byte)RequestCommandClass.Configuration },
                IsConfiguration = true,
                IsValid = true,
                Node = node,
                Type = MessageType.Request,
                ZIdentifier = node.ZIdentifier
            };

            // fill content
            result.Content.AddRange(content);
            result.Content.Insert(0, (byte)result.Content.Count);

            return result;
        }
        /// <summary>
        /// Get node protocol.
        /// </summary>
        /// <param name="controller">Controller.</param>
        /// <param name="node">Z node to complete.</param>
        /// <returns>Process result.</returns>
        private static bool GetNodeProtocol(ControllerDto controller, DeviceDto node)
        {
            // send message
            if (MessageProcessBusiness.Send(controller, CreateCommandMessage(MessageCommand.GetNodeProtocol, controller, node.ZIdentifier)))
            {
                // wait for response
                WaitAcknowledgment.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitEvent.WaitOne(DeviceConstants.WaitEventTimeout);
            }

            // get result
            node.HomeIdentifier = controller.HomeIdentifier;
            return node.DeviceClass != DeviceClass.Unknown && node.DeviceClassGeneric != DeviceClassGeneric.Other;
        }
        /// <summary>
        /// Create a command message.
        /// </summary>
        /// <param name="controller">Contextual node of the message.</param>
        /// <param name="command">Command to process.</param>
        /// <param name="zId">Node identifier to send in message. 0x00 if no node is concerned.</param>
        /// <returns>Message.</returns>
        private static MessageToDto CreateCommandMessage(MessageCommand command, DeviceDto controller, int zId = 0)
        {
            var result = new MessageToDto
            {
                Command = command,
                IsValid = true,
                Node = controller,
                ZIdentifier = (byte)zId,
                Type = MessageType.Request,
            };

            return result;
        }
 /// <summary>
 /// Configure a device.
 /// </summary>
 /// <param name="controller">Controller to use.</param>
 /// <param name="node">Node to configure.</param>
 /// <param name="parameter">Parameter identifier.</param>
 /// <param name="value">Parameter value.</param>
 /// <returns>Configure result.</returns>
 internal static bool Configure(ControllerDto controller, DeviceDto node, byte parameter, List<byte> value)
 {
     return ConfigurationBusiness.Set(controller, node, parameter, value);
 }
        /// <summary>
        /// Set ON a switch.
        /// </summary>
        /// <param name="controller">Concerned controller.</param>
        /// <param name="node">Concerned node.</param>
        /// <param name="value">"0xFF" to set on, "0x00" to set off.</param>
        /// <returns>Updated node.</returns>
        public bool Set(ControllerDto controller, DeviceDto node, List<byte> value)
        {
            var result = false;

            // send message
            if (MessageProcessBusiness.Send(controller, CreateCommandMessage(node, new List<byte> {(byte) SwitchBinaryAction.Set, value.FirstOrDefault()})))
            {
                // wait for response from controller
                WaitAcknowledgment.WaitOne(DeviceConstants.WaitEventTimeout);
                WaitResponseEvent.WaitOne(DeviceConstants.WaitEventTimeout);
                result = Get(controller, node);
            }

            // get node value
            return result && node.Value.SequenceEqual(value);
        }
        /// <summary>
        /// Create a command message.
        /// </summary>
        /// <param name="controller">Contextual node of the message.</param>
        /// <param name="zId">Node identifier to send in message. 0x00 if no node is concerned.</param>
        /// <returns>Message.</returns>
        private static MessageToDto CreateCommandMessage(DeviceDto controller, int zId)
        {
            var result = new MessageToDto
            {
                Command = MessageCommand.SendData,
                IsValid = true,
                Node = controller,
                ZIdentifier = (byte)zId,
                Type = MessageType.Request,
                Content = new List<byte> { 0x02, (byte)RequestCommandClass.Constructor, (byte)ConstructorAction.Get },

                IsConstructor = true
            };

            return result;
        }