238 lines
7.9 KiB
C#
238 lines
7.9 KiB
C#
namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore
|
|
{
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Converters;
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
|
|
using Applications;
|
|
using Registers;
|
|
using Registers.DataTypes;
|
|
using Registers.Json;
|
|
using WaterMeterRegisters;
|
|
|
|
/// <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 { get; }
|
|
= new List<IRegister>();
|
|
|
|
/// <summary>
|
|
/// Applications defined in configuration.json file
|
|
/// </summary>
|
|
public List<ApplicationDefinition> ConfigApplicationDefinitions { get; }
|
|
= new List<ApplicationDefinition>();
|
|
|
|
/// <summary>
|
|
/// Ctor
|
|
/// </summary>
|
|
public GenesisConfigurationReader() {}
|
|
|
|
/// <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");
|
|
}
|
|
|
|
BuildRegisterList(File.ReadAllText(configFilePath));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert file content to register list
|
|
/// </summary>
|
|
/// <param name="configurationJson"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="Exception"></exception>
|
|
public void BuildRegisterList(String configurationJson)
|
|
{
|
|
IDictionary<String, AppSection> sections;
|
|
|
|
try
|
|
{
|
|
sections = JsonConvert
|
|
.DeserializeObject<IDictionary<String, AppSection>>(configurationJson, SerializerSettings)
|
|
?? new Dictionary<String, AppSection>();
|
|
}
|
|
catch (Exception )
|
|
{
|
|
sections = new Dictionary<String, AppSection>();
|
|
}
|
|
|
|
foreach (var sectionKVP in sections)
|
|
{
|
|
var appId = sectionKVP.Value.Id;
|
|
var appName = sectionKVP.Key;
|
|
|
|
ConfigApplicationDefinitions.Add(new ApplicationDefinition
|
|
{
|
|
AppId = appId,
|
|
AppName = appName
|
|
});
|
|
|
|
var section = sectionKVP.Value;
|
|
|
|
var registers = section.Registers;
|
|
|
|
if (registers is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (var registerKVP in registers)
|
|
{
|
|
var register = registerKVP.Value;
|
|
|
|
if (register is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var details = register.Details;
|
|
|
|
if (details is null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var regId = register.Id;
|
|
|
|
foreach (var detail in details)
|
|
{
|
|
var values = detail.Values;
|
|
|
|
ConfigRegistersDefinitions.Add(new RegisterDefinition
|
|
{
|
|
AppAddress = appId,
|
|
AppName = appName,
|
|
DataType = GetType(detail.Type),
|
|
Default = values?.Default is Int64 d ? d : default(Int64?),
|
|
IsAvailable = default(Boolean),
|
|
Maximum = values?.Maximum is Int64 max ? max : default(Int64?),
|
|
Minimum = values?.Minimum is Int64 min ? min : default(Int64?),
|
|
RegAddressInApp = regId,
|
|
// RegisterAddress = new byte[] { appId, regId },
|
|
RegisterDetail = detail,
|
|
RegisterName = registerKVP.Key,
|
|
RestoreCapability = new StaticType(detail.StaticType)
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Settings
|
|
/// </summary>
|
|
private static readonly JsonSerializerSettings SerializerSettings = new JsonSerializerSettings
|
|
{
|
|
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
|
|
DateParseHandling = DateParseHandling.None,
|
|
Converters =
|
|
{
|
|
AccessConverter.Singleton,
|
|
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
|
|
},
|
|
};
|
|
|
|
private static Type GetType(String value)
|
|
{
|
|
switch (value.ToLower())
|
|
{
|
|
case "bool_t": return typeof(Boolean);
|
|
case "rpc": return typeof(Rpc);
|
|
case "string": return typeof(String);
|
|
case "uint32_t": return typeof(UInt32);
|
|
case "time_t": return typeof(TimeT);
|
|
case "status_t": return typeof(StatusT);
|
|
case "uint16_t": return typeof(UInt16);
|
|
case "uint8_t": return typeof(Byte);
|
|
case "enum8": return typeof(Enum8);
|
|
case "uint64_t": return typeof(UInt64);
|
|
case "uint96_t": return typeof(UInt96);
|
|
case "uint128_t": return typeof(UInt128);
|
|
case "int8_t": return typeof(SByte);
|
|
case "int32_t": return typeof(Int32);
|
|
case "int64_t": return typeof(Int64);
|
|
case "int16_t": return typeof(Int16);
|
|
case "uint72_t": return typeof(UInt72);
|
|
case "uint48_t": return typeof(UInt48);
|
|
case "uint88_t": return typeof(UInt88);
|
|
default: throw new Exception($"Type {value} not recognized!");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class AccessConverter : JsonConverter
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="t"></param>
|
|
/// <returns></returns>
|
|
public override Boolean CanConvert(Type t) => t == typeof(Access) || t == typeof(Access?);
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="reader"></param>
|
|
/// <param name="t"></param>
|
|
/// <param name="existingValue"></param>
|
|
/// <param name="serializer"></param>
|
|
/// <returns></returns>
|
|
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);
|
|
|
|
return Enum.TryParse(value, true, out Access access) ? access : default(Access);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="writer"></param>
|
|
/// <param name="untypedValue"></param>
|
|
/// <param name="serializer"></param>
|
|
public override void WriteJson(JsonWriter writer, Object untypedValue, JsonSerializer serializer)
|
|
{
|
|
if (untypedValue is Access access)
|
|
{
|
|
writer.WriteValue(access.ToString());
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Cannot marshal type Lvl");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public static readonly AccessConverter Singleton = new AccessConverter();
|
|
}
|
|
}
|