protected string GetZclClusterCommandPackage(ZigBeeXmlCluster cluster)
 {
     if (cluster.Name.StartsWith("ZDO"))
     {
         return(packageRoot + packageZdpCommand);
     }
     else
     {
         return(packageRoot + packageZclProtocolCommand + "." + StringToUpperCamelCase(cluster.Name).Replace("_", ""));
     }
 }
Beispiel #2
0
        /*
         * public ZigBeeZclConstantGenerator(string sourceRootPath, ZigBeeXmlConstant constant, string generatedDate)
         *  : base(sourceRootPath, generatedDate)
         * {
         *  try
         *  {
         *      GenerateZclConstant(constant);
         *  }
         *  catch (IOException e)
         *  {
         *      Console.WriteLine(e.ToString());
         *  }
         * }
         */

        private void GenerateZclClusterConstants(ZigBeeXmlCluster cluster)
        {
            if (cluster.Constants == null)
            {
                return;
            }

            string packageRoot = GetZclClusterCommandPackage(cluster);

            foreach (ZigBeeXmlConstant constant in cluster.Constants)
            {
                GenerateZclConstant(packageRoot, constant);
            }
        }
Beispiel #3
0
        private void GenerateZclClusterCommands(ZigBeeXmlCluster cluster)
        {
            foreach (ZigBeeXmlCommand command in cluster.Commands)
            {
                string packageRoot = GetZclClusterCommandPackage(cluster);
                string packagePath = GetPackagePath(_sourceRootPath, packageRoot);

                string     className = StringToUpperCamelCase(command.Name);
                TextWriter @out      = GetClassOut(packagePath, className);

                // List of fields that are handled internally by super class
                List <string> reservedFields = new List <string>();

                ImportsClear();

                OutputLicense(@out);

                ImportsAdd("System");
                ImportsAdd("System.Collections.Generic");
                ImportsAdd("System.Linq");
                ImportsAdd("System.Text");
                ImportsAdd("ZigBeeNet.ZCL.Protocol");


                string commandExtends = "";
                if (packageRoot.Contains(".zcl.", StringComparison.InvariantCultureIgnoreCase))
                {
                    ImportsAdd("ZigBeeNet.ZCL.Field");
                    ImportsAdd("ZigBeeNet" + packageRoot);
                    ImportsAdd("ZigBeeNet.Security");
                    commandExtends = "ZclCommand";
                    reservedFields.Add("ManufacturerCode");
                }
                else
                {
                    ImportsAdd("ZigBeeNet.ZCL");
                    ImportsAdd("ZigBeeNet.ZDO.Field");
                    if (command.Name.Contains("Response"))
                    {
                        commandExtends = "ZdoResponse";
                        reservedFields.Add("Status");
                    }
                    else
                    {
                        commandExtends = "ZdoRequest";
                    }
                }
                if (command.Response != null)
                {
                    ImportsAdd("ZigBeeNet.Transaction");
                }

                OutputImports(@out);
                @out.WriteLine();

                if (packageRoot.Contains(".zcl.", StringComparison.InvariantCultureIgnoreCase))
                {
                    @out.WriteLine("namespace ZigBeeNet" + packageRoot);
                }
                else
                {
                    @out.WriteLine("namespace ZigBeeNet.ZDO.Command");
                }
                @out.WriteLine("{");

                @out.WriteLine("    /// <summary>");
                @out.WriteLine("    /// " + command.Name + " value object class.");

                @out.WriteLine("    ///");
                if (packageRoot.Contains(".zcl.", StringComparison.InvariantCultureIgnoreCase))
                {
                    @out.WriteLine("    /// Cluster: " + cluster.Name + ". Command ID 0x"
                                   + command.Code.ToString("X2") + " is sent "
                                   + (command.Source.Equals("client") ? "TO" : "FROM") + " the server.");
                    @out.WriteLine("    /// This command is " + ((cluster.Name.Equals("GENERAL", StringComparison.InvariantCultureIgnoreCase))
                            ? "a generic command used across the profile."
                            : "a specific command used for the " + cluster.Name + " cluster."));
                }

                if (command.Description.Count > 0)
                {
                    @out.WriteLine("    ///");
                    OutputWithLinebreak(@out, "    ", command.Description);
                }

                @out.WriteLine("    ///");
                @out.WriteLine("    /// Code is auto-generated. Modifications may be overwritten!");
                @out.WriteLine("    /// </summary>");
                OutputClassGenerated(@out);


                @out.Write("    public class " + className + " : " + commandExtends);
                if (command.Response != null)
                {
                    @out.Write(", IZigBeeTransactionMatcher");
                }
                @out.WriteLine();
                @out.WriteLine("    {");

                if (commandExtends.Equals("ZclCommand"))
                {
                    if (!cluster.Name.Equals("GENERAL", StringComparison.InvariantCultureIgnoreCase))
                    {
                        @out.WriteLine("        /// <summary>");
                        @out.WriteLine("        /// The cluster ID to which this command belongs.");
                        @out.WriteLine("        /// </summary>");
                        @out.WriteLine("        public const ushort CLUSTER_ID = 0x" + cluster.Code.ToString("X4") + ";");
                        @out.WriteLine();
                    }
                    @out.WriteLine("        /// <summary>");
                    @out.WriteLine("        /// The command ID.");
                    @out.WriteLine("        /// </summary>");
                    @out.WriteLine("        public const byte COMMAND_ID = 0x" + command.Code.ToString("X2") + ";");
                    @out.WriteLine();
                }
                else
                {
                    @out.WriteLine("        /// <summary>");
                    @out.WriteLine("        /// The ZDO cluster ID.");
                    @out.WriteLine("        /// </summary>");
                    @out.WriteLine("        public const ushort CLUSTER_ID = 0x" + command.Code.ToString("X4") + ";");
                    @out.WriteLine();
                }

                foreach (ZigBeeXmlField field in command.Fields)
                {
                    if (reservedFields.Contains(StringToUpperCamelCase(field.Name)))
                    {
                        continue;
                    }
                    if (GetAutoSized(command.Fields, StringToLowerCamelCase(field.Name)) != null)
                    {
                        continue;
                    }

                    @out.WriteLine("        /// <summary>");
                    @out.WriteLine("        /// " + field.Name + " command message field.");
                    if (field.Description.Count != 0)
                    {
                        @out.WriteLine("        /// ");
                        OutputWithLinebreak(@out, "        ", field.Description);
                    }
                    @out.WriteLine("        /// </summary>");
                    @out.WriteLine("        public " + GetDataTypeClass(field) + " " + StringToUpperCamelCase(field.Name) + " { get; set; }");
                    @out.WriteLine();
                }

                @out.WriteLine("        /// <summary>");
                @out.WriteLine("        /// Default constructor.");
                @out.WriteLine("        /// </summary>");
                @out.WriteLine("        public " + className + "()");
                @out.WriteLine("        {");

                if (!cluster.Name.Equals("GENERAL", StringComparison.InvariantCultureIgnoreCase))
                {
                    @out.WriteLine("            ClusterId = CLUSTER_ID;");
                }
                if (commandExtends.Equals("ZclCommand"))
                {
                    @out.WriteLine("            CommandId = COMMAND_ID;");
                    @out.WriteLine("            GenericCommand = " + (cluster.Name.Equals("GENERAL", StringComparison.InvariantCultureIgnoreCase) ? "true" : "false") + ";");
                    @out.WriteLine("            CommandDirection = ZclCommandDirection." + (command.Source.Equals("client") ? "CLIENT_TO_SERVER" : "SERVER_TO_CLIENT") + ";");
                }
                @out.WriteLine("        }");

                GenerateFields(@out, commandExtends, className, command.Fields, reservedFields);

                if (command.Response != null)
                {
                    @out.WriteLine();
                    @out.WriteLine("        public bool IsTransactionMatch(ZigBeeCommand request, ZigBeeCommand response)");
                    @out.WriteLine("        {");
                    if (command.Response.Matchers.Count == 0)
                    {
                        @out.WriteLine("            return (response is " + command.Response.Command + ") && ((ZdoRequest) request).DestinationAddress.Equals(((" +
                                       command.Response.Command + ") response).SourceAddress);");
                    }
                    else
                    {
                        @out.WriteLine("            if (!(response is " + command.Response.Command + "))");
                        @out.WriteLine("            {");
                        @out.WriteLine("                return false;");
                        @out.WriteLine("            }");
                        @out.WriteLine();
                        @out.Write("            return ");

                        bool first = true;
                        foreach (ZigBeeXmlMatcher matcher in command.Response.Matchers)
                        {
                            if (first == false)
                            {
                                @out.WriteLine();
                                @out.Write("                    && ");
                            }
                            first = false;
                            @out.Write("(((" + StringToUpperCamelCase(command.Name) + ") request)." + matcher.CommandField);
                            @out.Write(".Equals(((" + command.Response.Command + ") response)." + matcher.ResponseField + "))");
                        }
                        @out.WriteLine(";");
                    }
                    @out.WriteLine("         }");
                }

                GenerateToString(@out, className, command.Fields, reservedFields);

                @out.WriteLine("    }");
                @out.WriteLine("}");

                @out.Flush();
                @out.Close();
            }
        }
        private void GenerateZclClusterDependencies(ZigBeeXmlCluster cluster, string packageRootPrefix)
        {
            if (cluster.Constants != null)
            {
                foreach (ZigBeeXmlConstant constant in cluster.Constants)
                {
                    string packageRoot = packageRootPrefix + packageZclProtocolCommand + "." + StringToLowerCamelCase(cluster.Name).Replace("_", "").ToLower();
                    string className   = constant.ClassName;

                    if (_dependencies.ContainsKey(className))
                    {
                        throw new ArgumentException("Duplicate class definition: " + _dependencies[className] + " with " + packageRoot + "." + className);
                    }
                    else
                    {
                        _dependencies.Add(className, packageRoot + "." + className);
                    }
                }
            }

            if (cluster.Structures != null)
            {
                foreach (ZigBeeXmlStructure structure in cluster.Structures)
                {
                    string packageRoot = packageRootPrefix + packageZclProtocolCommand + "." + StringToLowerCamelCase(cluster.Name).Replace("_", "").ToLower();
                    string className   = structure.ClassName;

                    if (_dependencies.ContainsKey(className))
                    {
                        throw new ArgumentException("Duplicate class definition: " + _dependencies[className] + " with " + packageRoot + "." + className);
                    }
                    else
                    {
                        _dependencies.Add(className, packageRoot + "." + className);
                    }

                    foreach (ZigBeeXmlField field in structure.Fields)
                    {
                        _zclTypes.Add(field.Type);
                    }
                }
            }

            if (cluster.Commands != null)
            {
                foreach (ZigBeeXmlCommand command in cluster.Commands)
                {
                    foreach (ZigBeeXmlField field in command.Fields)
                    {
                        _zclTypes.Add(field.Type);
                    }
                }
            }

            if (cluster.Attributes != null)
            {
                foreach (ZigBeeXmlAttribute attribute in cluster.Attributes)
                {
                    _zclTypes.Add(attribute.Type);
                }
            }
        }
Beispiel #5
0
        private void GenerateZclClusterClasses(ZigBeeXmlCluster cluster)
        {
            string     packageRoot = GetZclClusterCommandPackage(cluster);
            string     packagePath = GetPackagePath(_sourceRootPath, packageZclCluster);
            String     className   = "Zcl" + StringToUpperCamelCase(cluster.Name) + "Cluster";
            TextWriter @out        = GetClassOut(packagePath, className);

            OutputLicense(@out);
            @out.WriteLine();

            ImportsClear();

            int commandsServer = 0;
            int commandsClient = 0;

            foreach (ZigBeeXmlCommand command in cluster.Commands)
            {
                //ImportsAdd(packageRoot + packageZclCluster + "." + StringToLowerCamelCase(cluster.Name).ToLower() + "."
                //        + StringToUpperCamelCase(command.Name));

                if (command.Source.Equals("server"))
                {
                    commandsServer++;
                }
                if (command.Source.Equals("client"))
                {
                    commandsClient++;
                }
            }

            List <ZigBeeXmlAttribute> attributesClient = new List <ZigBeeXmlAttribute>();
            List <ZigBeeXmlAttribute> attributesServer = new List <ZigBeeXmlAttribute>();

            foreach (ZigBeeXmlAttribute attribute in cluster.Attributes)
            {
                if (attribute.Side.Equals("server"))
                {
                    attributesServer.Add(attribute);
                }
                if (attribute.Side.Equals("client"))
                {
                    attributesClient.Add(attribute);
                }
            }

            ImportsAdd("System");
            ImportsAdd("System.Collections.Concurrent");
            ImportsAdd("System.Collections.Generic");
            ImportsAdd("System.Linq");
            ImportsAdd("System.Text");
            ImportsAdd("System.Threading");
            ImportsAdd("System.Threading.Tasks");
            ImportsAdd("ZigBeeNet.Security");
            ImportsAdd("ZigBeeNet.ZCL.Protocol");
            ImportsAdd("ZigBeeNet.ZCL.Field");
            if (commandsClient > 0)
            {
                ImportsAdd("ZigBeeNet" + packageRoot);
            }

            OutputImports(@out);
            @out.WriteLine();

            @out.WriteLine("namespace ZigBeeNet.ZCL.Clusters");
            @out.WriteLine("{");
            @out.WriteLine("    /// <summary>");
            @out.WriteLine("    /// " + cluster.Name + " cluster implementation (Cluster ID " + "0x" + cluster.Code.ToString("X4") + ").");
            if (cluster.Description.Count != 0)
            {
                @out.WriteLine("    ///");
                OutputWithLinebreak(@out, "    ", cluster.Description);
            }

            @out.WriteLine("    ///");
            @out.WriteLine("    /// Code is auto-generated. Modifications may be overwritten!");

            @out.WriteLine("    /// </summary>");

            @out.WriteLine("    public class " + className + " : ZclCluster");
            @out.WriteLine("    {");
            @out.WriteLine("        /// <summary>");
            @out.WriteLine("        /// The ZigBee Cluster Library Cluster ID");
            @out.WriteLine("        /// </summary>");
            @out.WriteLine("        public const ushort CLUSTER_ID = 0x" + cluster.Code.ToString("X4") + ";");
            @out.WriteLine();
            @out.WriteLine("        /// <summary>");
            @out.WriteLine("        /// The ZigBee Cluster Library Cluster Name");
            @out.WriteLine("        /// </summary>");
            @out.WriteLine("        public const string CLUSTER_NAME = \"" + cluster.Name + "\";");
            @out.WriteLine();

            if (cluster.Attributes.Count != 0)
            {
                @out.WriteLine("        // Attribute constants");
                foreach (ZigBeeXmlAttribute attribute in cluster.Attributes)
                {
                    if (attribute.ArrayStart != null && attribute.ArrayCount != null && attribute.ArrayCount > 0)
                    {
                        int arrayCount = attribute.ArrayStart.Value;
                        int arrayStep  = attribute.ArrayStep == null ? 1 : attribute.ArrayStep.Value;
                        for (int count = 0; count < attribute.ArrayCount; count++)
                        {
                            if (attribute.Description.Count != 0)
                            {
                                @out.WriteLine();
                                @out.WriteLine("        /// <summary>");
                                OutputWithLinebreak(@out, "        ", attribute.Description);
                                @out.WriteLine("     /// </summary>");
                            }

                            String name = Regex.Replace(attribute.Name, "\\{\\{count\\}\\}", arrayCount.ToString());
                            @out.WriteLine("        public const ushort " + GetEnum(name) + " = 0x" + (attribute.Code + (arrayCount - attribute.ArrayStart) * arrayStep).Value.ToString("X4") + ";");
                            arrayCount++;
                        }
                    }
                    else
                    {
                        if (attribute.Description.Count != 0)
                        {
                            @out.WriteLine();
                            @out.WriteLine("        /// <summary>");
                            OutputWithLinebreak(@out, "        ", attribute.Description);
                            @out.WriteLine("        /// </summary>");
                        }
                        @out.WriteLine("        public const ushort " + GetEnum(attribute.Name) + " = 0x" + attribute.Code.ToString("X4") + ";");
                    }
                }
                @out.WriteLine();
            }

            @out.WriteLine("        protected override Dictionary<ushort, ZclAttribute> InitializeClientAttributes()");
            @out.WriteLine("        {");
            CreateInitializeAttributes(@out, cluster.Name, attributesClient);
            @out.WriteLine();

            @out.WriteLine("        protected override Dictionary<ushort, ZclAttribute> InitializeServerAttributes()");
            @out.WriteLine("        {");
            CreateInitializeAttributes(@out, cluster.Name, attributesServer);
            @out.WriteLine();


            if (commandsServer != 0)
            {
                @out.WriteLine("        protected override Dictionary<ushort, Func<ZclCommand>> InitializeServerCommands()");
                @out.WriteLine("        {");
                @out.WriteLine("            Dictionary<ushort, Func<ZclCommand>> commandMap = new Dictionary<ushort, Func<ZclCommand>>(" + commandsServer + ");");
                @out.WriteLine();
                foreach (ZigBeeXmlCommand command in cluster.Commands)
                {
                    if (command.Source.Equals("server", StringComparison.InvariantCultureIgnoreCase))
                    {
                        @out.WriteLine("            commandMap.Add(0x" + command.Code.ToString("X4") + ", () => new " + StringToUpperCamelCase(command.Name) + "());");
                    }
                }
                @out.WriteLine();

                @out.WriteLine("            return commandMap;");
                @out.WriteLine("        }");
                @out.WriteLine();
            }

            if (commandsClient != 0)
            {
                @out.WriteLine("        protected override Dictionary<ushort, Func<ZclCommand>> InitializeClientCommands()");
                @out.WriteLine("        {");
                @out.WriteLine("            Dictionary<ushort, Func<ZclCommand>> commandMap = new Dictionary<ushort, Func<ZclCommand>>(" + commandsClient + ");");
                @out.WriteLine();
                foreach (ZigBeeXmlCommand command in cluster.Commands)
                {
                    if (command.Source.Equals("client", StringComparison.InvariantCultureIgnoreCase))
                    {
                        @out.WriteLine("            commandMap.Add(0x" + command.Code.ToString("X4") + ", () => new " + StringToUpperCamelCase(command.Name) + "());");
                    }
                }
                @out.WriteLine();

                @out.WriteLine("            return commandMap;");
                @out.WriteLine("        }");
                @out.WriteLine();
            }

            @out.WriteLine("        /// <summary>");
            @out.WriteLine("        /// Default constructor to create a " + cluster.Name + " cluster.");
            @out.WriteLine("        ///");
            @out.WriteLine("        /// <param name=\"zigbeeEndpoint\"> the ZigBeeEndpoint this cluster is contained within </param>");
            @out.WriteLine("        /// </summary>");
            @out.WriteLine("        public " + className + "(ZigBeeEndpoint zigbeeEndpoint)");
            @out.WriteLine("            :base(zigbeeEndpoint, CLUSTER_ID, CLUSTER_NAME)");
            @out.WriteLine("        {");
            @out.WriteLine("        }");

            foreach (ZigBeeXmlCommand command in cluster.Commands)
            {
                @out.WriteLine();
                @out.WriteLine("        /// <summary>");
                @out.WriteLine("        /// The " + command.Name);
                if (command.Description.Count != 0)
                {
                    @out.WriteLine("        ///");
                    OutputWithLinebreak(@out, "        ", command.Description);
                }
                @out.WriteLine("        ///");

                LinkedList <ZigBeeXmlField> fields = new LinkedList <ZigBeeXmlField>(command.Fields);
                foreach (ZigBeeXmlField field in fields)
                {
                    @out.WriteLine("        /// <param name=\"" + StringToLowerCamelCase(field.Name) + "\" <see cref=\"" + GetDataTypeClass(field) + "\"> " + field.Name + "</ param >");
                }

                @out.WriteLine("        /// <returns> the command result Task </returns>");
                @out.WriteLine("        /// </summary>");
                @out.Write("        public Task<CommandResult> " + StringToUpperCamelCase(command.Name) + "(");

                bool first = true;
                foreach (ZigBeeXmlField field in fields)
                {
                    if (first == false)
                    {
                        @out.Write(", ");
                    }
                    @out.Write(GetDataTypeClass(field) + " " + StringToLowerCamelCase(field.Name));
                    first = false;
                }

                @out.WriteLine(")");
                @out.WriteLine("        {");
                if (fields.Count == 0)
                {
                    @out.WriteLine("            return Send(new " + StringToUpperCamelCase(command.Name) + "());");
                }
                else
                {
                    @out.WriteLine("            " + StringToUpperCamelCase(command.Name) + " command = new " + StringToUpperCamelCase(command.Name) + "();");
                    @out.WriteLine();
                    @out.WriteLine("            // Set the fields");

                    foreach (ZigBeeXmlField field in fields)
                    {
                        @out.WriteLine("            command." + StringToUpperCamelCase(field.Name) + " = " + StringToLowerCamelCase(field.Name) + ";");
                    }
                    @out.WriteLine();
                    @out.WriteLine("            return Send(command);");
                }
                @out.WriteLine("        }");
            }

            @out.WriteLine("    }");
            @out.WriteLine("}");

            @out.Flush();
            @out.Close();
        }
        private void GenerateZclClusterStructures(ZigBeeXmlCluster cluster)
        {
            if (cluster.Structures == null)
            {
                return;
            }

            foreach (ZigBeeXmlStructure structure in cluster.Structures)
            {
                string packageRoot = GetZclClusterCommandPackage(cluster);
                string packagePath = GetPackagePath(_sourceRootPath, packageRoot);

                string     className = structure.ClassName;
                TextWriter @out      = GetClassOut(packagePath, className);

                ImportsClear();

                OutputLicense(@out);

                ImportsAdd("System");
                ImportsAdd("System.Collections.Generic");
                ImportsAdd("System.Linq");
                ImportsAdd("System.Text");
                ImportsAdd("ZigBeeNet.Serialization");
                ImportsAdd("ZigBeeNet.ZCL.Protocol");
                ImportsAdd("ZigBeeNet.ZCL.Field");
                ImportsAdd("ZigBeeNet.ZCL.Clusters." + cluster.Name.Replace("/", "").Replace(" ", "").Replace("(", "").Replace(")", ""));

                OutputImports(@out);

                @out.WriteLine("namespace ZigBeeNet.ZCL.Clusters." + cluster.Name.Replace("/", "").Replace(" ", "").Replace("(", "").Replace(")", ""));
                @out.WriteLine("{");

                @out.WriteLine("    /// <summary>");
                @out.WriteLine("    /// " + structure.Name + " structure implementation.");

                if (structure.Description.Count > 0)
                {
                    @out.WriteLine("    ///");
                    OutputWithLinebreak(@out, "    ", structure.Description);
                }

                @out.WriteLine("    ///");
                @out.WriteLine("    /// Code is auto-generated. Modifications may be overwritten!");
                @out.WriteLine("    /// </summary>");
                OutputClassGenerated(@out);

                @out.WriteLine("    public class " + className + " : IZigBeeSerializable");
                @out.WriteLine("    {");

                foreach (ZigBeeXmlField field in structure.Fields)
                {
                    @out.WriteLine("        /// <summary>");
                    @out.WriteLine("        /// " + field.Name + " structure field.");
                    if (field.Description.Count != 0)
                    {
                        @out.WriteLine("        /// ");
                        OutputWithLinebreak(@out, "        ", field.Description);
                    }
                    @out.WriteLine("        /// </summary>");
                    @out.WriteLine("        public " + GetDataTypeClass(field) + " " + StringToUpperCamelCase(field.Name) + " { get; set; }");
                    @out.WriteLine();
                }
                @out.WriteLine();

                GenerateFields(@out, "IZigBeeSerializable", className, structure.Fields, new List <string>());
                GenerateToString(@out, className, structure.Fields, new List <string>());

                @out.WriteLine("    }");
                @out.WriteLine("}");

                @out.Flush();
                @out.Close();
            }
        }