126 lines
4.3 KiB
C#
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");
|
|
}
|
|
}
|
|
}
|
|
}
|