protected string GetZclClusterCommandPackage(ZigBeeXmlCluster cluster) { if (cluster.Name.StartsWith("ZDO")) { return(packageRoot + packageZdpCommand); } else { return(packageRoot + packageZclProtocolCommand + "." + StringToUpperCamelCase(cluster.Name).Replace("_", "")); } }
/* * 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); } }
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); } } }
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(); } }