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
{
///
/// Representing all registers from one meter.
/// create empty list on construction.
/// updated after read register
///
public class MeterRegisters
{
///
/// Dictionary of meter registers
///
public readonly ConcurrentDictionary MeterRegisterDic;
///
/// create empty list on construction.
///
public MeterRegisters()
{
MeterRegisterDic = new ConcurrentDictionary();
}
///
/// add empty registers
///
///
public void AddRegistersDefinitions(List adds)
{
foreach (var add in adds)
{
try
{
if (add is RegisterDefinition addGenesisRegister)
{
MeterRegisterDic.TryAdd(addGenesisRegister, null);
}
}
catch (Exception )
{
// ignored
}
}
}
///
/// Search register referenced by name as combination of application name and register name
/// Example: GENSISFLOW_LedMode
///
///
///
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!");
}
///
/// Get current value of register in program.
/// ATTENTION: this is not the current meter register!
/// for meter register use read register in advance
///
/// register to get
/// current value
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;
}
///
/// Set register in program
/// ATTENTION: this is not stored to the meter!
/// to store to meter register use write register!
///
/// Register to set
/// Value to set
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");
}
}
}
}