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"); } } } }