Files
laatzen/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisConfigReader.cs
T

466 lines
24 KiB
C#

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Xylem.Common.Hardware.WaterMeter.Genesis.Applications;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.DataTypes;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers.RegisterProperties;
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
{
/// <summary>
/// JSON filer reader for generation of register lists
/// </summary>
public class GenesisConfigurationReader
{
/// <summary>
/// Registers defined in configuration.json file
/// </summary>
public List<IRegister> ConfigRegistersDefinitions;
/// <summary>
/// Applications defined in configuration.json file
/// </summary>
public List<ApplicationDefinition> ConfigApplicationDefinitions;
/// <summary>
/// Ctor
/// </summary>
/// <param name="configFilePath">the file path for configuration.json as interface description to the meter</param>
public GenesisConfigurationReader(String configFilePath)
{
if (string.IsNullOrEmpty(configFilePath))
{
throw new ApplicationException("JsonFileRegisterReader needs at least one file path");
}
if (!File.Exists(configFilePath))
{
throw new ApplicationException($" {configFilePath} doesn't exists");
}
Convert(File.ReadAllText(configFilePath));
}
/// <summary>
/// Convert file content to register list
/// </summary>
/// <param name="fileContent"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private void Convert(String fileContent)
{
var applicationGroups = (JObject)JsonConvert.DeserializeObject(fileContent);
ConfigRegistersDefinitions = new List<IRegister>();
ConfigApplicationDefinitions = new List<ApplicationDefinition>();
try
{
//extract information of every application
if (applicationGroups != null)
foreach (var currentApplication in applicationGroups)
{
var o = (JObject)currentApplication.Value;
var application = new ApplicationDefinition();
Byte applicationAddress = 0;
foreach (var groupProp in o)
{
try
{
if (groupProp.Key == "id")
{
applicationAddress = groupProp.Value.Value<Byte>();
application.AppName = currentApplication.Key;
application.AppId = applicationAddress;
ConfigApplicationDefinitions.Add(application);
}
else if (groupProp.Key == "registers")
{
foreach (var registers in groupProp.Value)
{
var register = (JProperty)registers;
try
{
foreach (var registerJ in register.Value)
{
var reg = (JProperty)registerJ;
Byte? registerAddress = null;
if (reg.Name == "id")
{
registerAddress = (Byte)reg.Value;
}
if (reg.Name == "details")
{
var details = ((JArray)reg.Value);
foreach (var jdetail in details.Children())
{
var actualRegister = new RegisterDefinition();
var idTag = reg.Parent.First(f => ((JProperty)f).Name == "id");
var id = (Byte)(JProperty)idTag; //.Value<int>();
if (registerAddress.HasValue)
{
throw new Exception("invalid json cast");
}
actualRegister.RegAddressInApp = id;
actualRegister.AppName = currentApplication.Key;
actualRegister.AppAddress = applicationAddress;
actualRegister.RegisterDetail = new RegisterDetail();
actualRegister.RegisterName = register.Name;
var detailO = (JObject)jdetail;
JProperty detail;
detail = detailO.Property("privilege");
if (detail.Name == "privilege")
{
actualRegister.RegisterDetail.Privilege =
JsonConvert.DeserializeObject<Privilege>(
detail.Value.ToString(), Settings);
}
detail = detailO.Property("type");
if (detail.Name == "type")
{
actualRegister.DataType =
typeof(String); // detail.Value.ToString();
switch (detail.Value.ToString().ToLower())
{
case "bool_t":
actualRegister.DataType = typeof(Boolean);
break;
case "rpc":
actualRegister.DataType = typeof(Rpc);
break;
case "string":
actualRegister.DataType = typeof(String);
break;
case "uint32_t":
actualRegister.DataType = typeof(UInt32);
break;
case "time_t":
actualRegister.DataType = typeof(TimeT);
break;
case "status_t":
actualRegister.DataType = typeof(StatusT);
break;
case "uint16_t":
actualRegister.DataType = typeof(UInt16);
break;
case "uint8_t":
actualRegister.DataType = typeof(byte);
break;
case "enum8":
actualRegister.DataType = typeof(Enum8);
break;
case "uint64_t":
actualRegister.DataType = typeof(UInt64);
break;
case "uint96_t":
actualRegister.DataType = typeof(UInt96);
break;
case "int8_t":
actualRegister.DataType = typeof(sbyte);
break;
case "int32_t":
actualRegister.DataType = typeof(Int32);
break;
case "int64_t":
actualRegister.DataType = typeof(Int64);
break;
case "int16_t":
actualRegister.DataType = typeof(Int16);
break;
}
}
detail = detailO.Property("description");
if (detail.Name == "description")
{
actualRegister.RegisterDetail.Description =
detail.Value.ToString();
}
detail = detailO.Property("version");
if (detail.Name == "version")
{
actualRegister.RegisterDetail.Version =
JsonConvert.DeserializeObject<FwVersion>(
detail.Value.ToString());
}
detail = detailO.Property("values");
if (detail != null && detail.Name == "values")
{
foreach (var dValues in detail.Children().First())
{
switch (((JProperty)dValues).Name)
{
case "default":
actualRegister.Default =
(Int64)((JProperty)dValues).Value;
break;
case "maximum":
actualRegister.Maximum =
(Int64)((JProperty)dValues).Value;
break;
case "minimum":
actualRegister.Minimum =
(Int64)((JProperty)dValues).Value;
break;
}
}
}
detail = detailO.Property(StaticType.StaticTypeFieldIdentifier);
if (detail != null && detail.Name ==
StaticType.StaticTypeFieldIdentifier)
{
actualRegister.RestoreCapability =
new StaticType(detail.Value.ToString());
}
ConfigRegistersDefinitions.Add(actualRegister);
}
}
}
}
catch (Exception )
{
//todo log ex
}
}
}
}
catch (Exception )
{
//todo log ex
}
}
}
}
catch (Exception )
{
// ignored
}
////tofile
var listOfRegisters = new List<RegisterDefinition>();
foreach (var item in ConfigRegistersDefinitions)
{
if (item is RegisterDefinition reg)
{
if (listOfRegisters.Any(a => a.GetIdent() == reg.GetIdent()))
{
var oldItem = listOfRegisters.First(a => a.GetIdent() == reg.GetIdent());
if (oldItem.RegisterDetail.Version.Last < reg.RegisterDetail.Version.Last)
{
listOfRegisters.Remove(oldItem);
listOfRegisters.Add(reg);
}
}
else
{
listOfRegisters.Add(reg);
}
}
}
//#region create a file for my american friends
//var sbCSV = new StringBuilder();
//sbCSV.AppendLine("Filter;Ident;First;Last");
//foreach (var item in ConfigRegistersDefinitions)
//{
// if (item is RegisterDefinition Reg)
// {
// sbCSV.AppendLine($"ALL;{Reg.GetIdent()};{Reg.RegisterDetail.Version.First}; {Reg.RegisterDetail.Version.Last};");
// }
//}
//foreach (var item in lsitOfRegisters)
//{
// sbCSV.AppendLine($"InUse;{item.GetIdent()};{item.RegisterDetail.Version.First}; {item.RegisterDetail.Version.Last};");
//}
//foreach (var item in lsitOfRegisters)
//{
// sbCSV.AppendLine($"InUse;{item.GetIdent()};{item.RegisterDetail.Version.First}; {item.RegisterDetail.Version.Last};");
//}
//var k = sbCSV.ToString();
//sbCSV.AppendLine("###");
//sbCSV.AppendLine("###");
//sbCSV.AppendLine("###");
//sbCSV.AppendLine("App;Version");
//foreach (var item in lsitOfRegisters)
//{
// sbCSV.AppendLine($"InUse;{item.GetIdent()};{item.RegisterDetail.Version.First}; {item.RegisterDetail.Version.Last};");
//}
//foreach (var grpReg in lsitOfRegisters.GroupBy(g => g.AppName))
//{
// sb.AppendLine($"public static class {grpReg.Key} {{");
// foreach (var item in grpReg)
// {
// sbCSV.Append($"{grpReg.Key};{item.RegisterName};{item.DataType.Name};{item.RegisterDetail.Description}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl1.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl2.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl3.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl4.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl5.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl6.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl7.ToString()}");
// sbCSV.Append($";{ item.RegisterDetail.Privilege.Lvl8.ToString()}");
// sb.AppendLine($"public static readonly RegisterDefinition {item.RegisterName} = new RegisterDefinition() {{");
// sb.AppendLine($"DataType = typeof({item.DataType.Name}),");
// sb.AppendLine($"Address = new byte[2] {{ (byte){item.RegisterAddress[0]}, (byte){item.RegisterAddress[1]} }},");
// sb.AppendLine($"Default = new long?(");
// if (item.Default.HasValue)
// {
// sb.Append(item.Default.Value);
// sbCSV.Append($";{item.Default.Value}");
// }
// else
// {
// sbCSV.Append(";-");
// }
// sb.Append($"),");
// sb.AppendLine($"Maximum = new long?(");
// if (item.Maximum.HasValue)
// {
// sb.Append(item.Maximum.Value);
// sbCSV.Append($";{item.Maximum.Value}");
// }
// else
// {
// sbCSV.Append(";-");
// }
// sb.Append($"),");
// sb.AppendLine($"Minimum = new long?(");
// if (item.Minimum.HasValue)
// {
// sb.Append(item.Minimum.Value);
// sbCSV.Append($";{item.Minimum.Value}");
// }
// else
// {
// sbCSV.Append(";-");
// }
// sb.Append($"),");
// sb.AppendLine($"Detail = new Detail(){{");
// sb.AppendLine($" Description = \"{item.RegisterDetail.Description}\",");
// sb.AppendLine($" Version = new Version(1,{item.RegisterDetail.Version.Last}),");
// sb.AppendLine($" Privilege = new Privilege(){{");
// //
// sb.AppendLine($" Lvl1 = Access.{item.RegisterDetail.Privilege.Lvl1.ToString()},");
// sb.AppendLine($" Lvl2 = Access.{item.RegisterDetail.Privilege.Lvl2.ToString()},");
// sb.AppendLine($" Lvl3 = Access.{item.RegisterDetail.Privilege.Lvl3.ToString()},");
// sb.AppendLine($" Lvl4 = Access.{item.RegisterDetail.Privilege.Lvl4.ToString()},");
// sb.AppendLine($" Lvl5 = Access.{item.RegisterDetail.Privilege.Lvl5.ToString()},");
// sb.AppendLine($" Lvl6 = Access.{item.RegisterDetail.Privilege.Lvl6.ToString()},");
// sb.AppendLine($" Lvl7 = Access.{item.RegisterDetail.Privilege.Lvl7.ToString()},");
// sb.AppendLine($" Lvl8 = Access.{item.RegisterDetail.Privilege.Lvl8.ToString()},");
// sb.AppendLine($" }}");
// sb.AppendLine($"}}");
// sb.AppendLine($"}};");
// sbCSV.AppendLine(";");
// }
// sb.AppendLine($"}}");
//}
//#endregion
//var z = sbCSV.ToString();
//var code = sb.ToString();
}
internal class LvlConverter : JsonConverter
{
public override Boolean CanConvert(Type t) => t == typeof(Access) || t == typeof(Access?);
public override Object ReadJson(JsonReader reader, Type t, Object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var value = serializer.Deserialize<String>(reader);
switch (value)
{
case "NA":
return Access.Na;
case "RO":
return Access.Ro;
case "RW":
return Access.Rw;
case "WO":
return Access.Wo;
}
throw new Exception("Cannot unmarshal type Lvl");
}
public override void WriteJson(JsonWriter writer, Object untypedValue, JsonSerializer serializer)
{
if (untypedValue == null)
{
serializer.Serialize(writer, null);
return;
}
var value = (Access)untypedValue;
switch (value)
{
case Access.Na:
serializer.Serialize(writer, "NA");
return;
case Access.Ro:
serializer.Serialize(writer, "RO");
return;
case Access.Rw:
serializer.Serialize(writer, "RW");
return;
case Access.Wo:
serializer.Serialize(writer, "WO");
return;
}
throw new Exception("Cannot marshal type Lvl");
}
public static readonly LvlConverter Singleton = new LvlConverter();
}
/// <summary>
/// Settings
/// </summary>
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
LvlConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
}