laatzen/Common/Hardware/WaterMeter/Genesis/Registers/MeterRegisters.cs
2022-04-06 10:42:16 +02:00

126 lines
4.3 KiB
C#

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters;
namespace Xylem.Common.Hardware.WaterMeter.Genesis.Registers
{
/// <summary>
/// Representing all registers from one meter.
/// create empty list on construction.
/// updated after read register
/// </summary>
public class MeterRegisters
{
/// <summary>
/// Dictionary of meter registers
/// </summary>
public readonly ConcurrentDictionary<RegisterDefinition, Byte[]> MeterRegisterDic;
/// <summary>
/// create empty list on construction.
/// </summary>
public MeterRegisters()
{
MeterRegisterDic = new ConcurrentDictionary<RegisterDefinition, Byte[]>();
}
/// <summary>
/// add empty registers
/// </summary>
/// <param name="adds"></param>
public void AddRegistersDefinitions(List<IRegister> adds)
{
foreach (var add in adds)
{
try
{
if (add is RegisterDefinition addGenesisRegister)
{
MeterRegisterDic.TryAdd(addGenesisRegister, null);
}
}
catch (Exception )
{
// ignored
}
}
}
/// <summary>
/// Search register referenced by name as combination of application name and register name
/// Example: GENSISFLOW_LedMode
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public RegisterDefinition GetRegisterDefinitionByName(String name)
{
if (MeterRegisterDic == null || !MeterRegisterDic.Any())
{
throw new ApplicationException($"Register {name} is not available. Registers are not loaded!");
}
var regDef = MeterRegisterDic.Where(f => f.Key.GetIdent().ToLower() == name.ToLower()).ToList();
if (regDef.Count() == 1)
{
return regDef.First().Key;
}
var r = regDef.Count() >= 1 ? regDef.Last().Key : new RegisterDefinition();
if (!string.IsNullOrEmpty(r.AppName))
{
return r;
}
// if no register is available throw ex
throw new ApplicationException($"Register {name} is not available. Check the configuration.json for latest version!");
}
/// <summary>
/// Get current value of register in program.
/// ATTENTION: this is not the current meter register!
/// for meter register use read register in advance
/// </summary>
/// <param name="register">register to get</param>
/// <returns>current value</returns>
public Byte[] Get(String register)
{
var reg = GetRegisterDefinitionByName(register);
if (!MeterRegisterDic.ContainsKey(reg)) return null;
if (MeterRegisterDic.Count(f => f.Key.GetIdent() == register) > 1)
{
if (MeterRegisterDic.Any(f => f.Key.GetIdent() == register && f.Value != null))
{
var regDs = MeterRegisterDic.Last(f => f.Key.GetIdent() == register && f.Value != null);
return regDs.Value;
}
}
var regD = MeterRegisterDic.First(f => f.Key.GetIdent() == register);
return regD.Value;
}
/// <summary>
/// Set register in program
/// ATTENTION: this is not stored to the meter!
/// to store to meter register use write register!
/// </summary>
/// <param name="register">Register to set</param>
/// <param name="value">Value to set</param>
public void Set(RegisterDefinition register, Byte[] value)
{
if (MeterRegisterDic.ContainsKey(register))
{
MeterRegisterDic[register] = value;
}
else if (register.DataType != null && register.RegisterDetail != null)
{
throw new ApplicationException("unknown register");
}
}
}
}