eregister - all radio keys by type

This commit is contained in:
Stoyan Zlatev 2024-10-17 10:06:36 +02:00
parent 5340d0c03b
commit a679ecddce
26 changed files with 770 additions and 452 deletions

View File

@ -49,9 +49,12 @@
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="eProgramingParametersList.cs" />
<Compile Include="eProgrammingParameters.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
@ -97,6 +100,8 @@
<Name>Common.Utils.Extensions</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="epp.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -2,20 +2,222 @@
{
using Common.Hardware.WaterMeter.eRegister;
using Common.Hardware.WaterMeter.eRegister.Features;
using Common.Logic.Extensions.SQL;
using System;
using System.Xml.Serialization;
public class Program
{
public static void Main()
{
var eregister = EregisterModel();
var serialNumbers = String.Join(", ", new Object[] { 17833444, 18743226, 18752765, 19744225, 18743225, 19793034, 19793035, 20731121, 20731265, 18743224 });
var xml = new SQLConnection("Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;")
.CreateCommand($@"
SELECT CAST((SELECT vm.Wert AS CSD
, SUBSTRING(ISNULL(fs.Wert, ''), 1, 1) AS RadioKeyType
, aps.SerienNr
, aps.StatusFertigung
, CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%'
OR vm.Wert LIKE 'CSD 770951%'
OR vm.Wert LIKE 'CSD 772721%'
THEN RIGHT(er.Adresse, 9)
ELSE aps.SerienNr END AS NVARCHAR(10)) AS MeterId
, er.TempAdresse
, er.Adresse
, x.FertigungsauftragNr
, x.Frequency
, x.Metersize
, x.Volume_per_Pulse AS VolumePerPulse
, x.Volume_per_LED_Pulse AS VolumePerLedPulse
, CAST(0 AS TINYINT) AS OffsetFactor
, CAST(5 AS TINYINT) AS OffsetTime
, CAST(0 AS TINYINT) AS FactoryCalibration
, CAST(3 AS TINYINT) AS TransmissionInterval
, CAST(7 AS TINYINT) AS MBusStatus
, CAST(0 AS TINYINT) AS LatWindows
, x.Byte11 AS UnitOfMesure
, x.Bit56 AS DecimalPoint
, x.Disallow_Reverse_Volume AS CandI
, x.Alarm_Low_Battery
, x.Alarm_Leakage
, x.Alarm_Magnetic_Tamper
, x.Alarm_Metrology_Unavailable
, x.Alarm_Backflow
, x.Alarm_Broken_Pipe
, x.Alarm_Medium_Absent
, x.Alarm_Specific_Error
, x.LeakagePeriod
, x.LeakageThreshold
, x.BrokenPipePeriod
, x.BrokenPipeThreshold
, x.History_Error_Limits_Days
, x.Data_Logging_Period
, x.Data_Logging_Forward_Counter
, x.Data_Logging_Time_Of_Minimum_Flow
, x.Data_Logging_Minimum_Flow
, x.Data_Logging_Time_Of_Broken_Pipe
, x.Data_Logging_Broken_Pipe_Flow
, x.Data_Logging_Current_Flow
, x.Data_Logging_Time_Of_Peak_Flow
, x.Data_Logging_Peak_Flow
, x.Data_Logging_Time_Of_Maximum_Flow
, x.Data_Logging_Maximum_Flow
, x.Data_Logging_Backward_Volume
, x.Data_Logging_Counter
, x.Data_Logging_Alarm_State
, x.FDR_Day_Of_Data_Reading
, x.FDR_Forward_Counter
, x.FDR_Time_Of_Minimum_Flow
, x.FDR_Minimum_Flow
, x.FDR_Time_Of_Broken_Pipe
, x.FDR_Broken_Pipe_Flow
, x.FDR_Current_Flow
, x.FDR_Time_Of_Peak_Flow
, x.FDR_Peak_Flow
, x.FDR_Time_Of_Maximum_Flow
, x.FDR_Maximum_Flow
, x.FDR_Backward_Volume
, x.FDR_Counter
, x.FDR_Alarm_State
, x.Transmission_Intervall
, x.PowerLevelHex
, CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%'
OR vm.Wert LIKE 'CSD 770951%'
OR vm.Wert LIKE 'CSD 773102%' THEN 0 ELSE 1 END AS BIT) AS DisableOTA
, CAST(CASE WHEN vm.Wert LIKE 'CSD 764144%'
OR vm.Wert LIKE 'CSD 760407%'
THEN 0 ELSE x.LAT_Interval END AS TINYINT) AS LATInterval
, CAST(CASE WHEN vm.Wert LIKE 'CSD 769400%' THEN 0
WHEN x.Metersize BETWEEN 53 AND 55 THEN 8
ELSE 10 END AS TINYINT) AS ActivationByThreshold
, CAST(CASE WHEN vm.Wert LIKE 'CSD 760407%'
OR vm.Wert LIKE 'CSD 764144%' THEN 16
WHEN vm.Wert LIKE 'CSD 38102_BU%' THEN 30
WHEN vm.Wert LIKE 'CSD 772100_WE%' THEN 15 * 60
ELSE 60 * 60 END AS SMALLINT) AS OpenMeteringTransmissionIntervalSeconds
, x.UTC_Offset AS UtcOffset
, x.Wake_Up_Interval AS WakeUpInterval
, CASE WHEN idn.Nennweite < 150 THEN 500 ELSE 50 END AS DisplayVolume
, CAST(CASE WHEN er.GeschlossenDatum IS NULL THEN 0 ELSE 1 END AS BIT) AS Sealed
FROM eRegister AS er
JOIN (SELECT DISTINCT
AuftragNr
, PositionNr
, SerienNr
, MAX(StatusFertigung) OVER (PARTITION BY SerienNr) AS StatusFertigung
FROM AuftragPositionSerienNr
WHERE SerienNr IN ({serialNumbers})) AS aps
ON er.Seriennummer = aps.SerienNr
JOIN AlleAuftragPositionen AS aap
ON aps.AuftragNr = aap.AuftragNr
AND aps.PositionNr = aap.PositionNr
JOIN (SELECT ap.FertigungsauftragNr
, rf.Frequency
, ms.Metersize
, ms.Volume_per_Pulse
, ms.Volume_per_LED_Pulse
, u.Byte11
, dp.Bit56
, ap.Disallow_Reverse_Volume
, ap.Alarm_Low_Battery
, ap.Alarm_Leakage
, ap.Alarm_Magnetic_Tamper
, ap.Alarm_Metrology_Unavailable
, ap.Alarm_Backflow
, ap.Alarm_Broken_Pipe
, ap.Alarm_Medium_Absent
, ap.Alarm_Specific_Error
, lp.[Bit0-2] AS LeakagePeriod
, lt.[Bit3-7] AS LeakageThreshold
, bpp.[Bit0-2] AS BrokenPipePeriod
, bpt.[Bit3-7] AS BrokenPipeThreshold
, ap.History_Error_Limits_Days
, dl.Data_Logging_Period
, ap.Data_Logging_Forward_Counter
, ap.Data_Logging_Time_Of_Minimum_Flow
, ap.Data_Logging_Minimum_Flow
, ap.Data_Logging_Time_Of_Broken_Pipe
, ap.Data_Logging_Broken_Pipe_Flow
, ap.Data_Logging_Current_Flow
, ap.Data_Logging_Time_Of_Peak_Flow
, ap.Data_Logging_Peak_Flow
, ap.Data_Logging_Time_Of_Maximum_Flow
, ap.Data_Logging_Maximum_Flow
, ap.Data_Logging_Backward_Volume
, ap.Data_Logging_Counter
, ap.Data_Logging_Alarm_State
, ap.FDR_Day_Of_Data_Reading
, ap.FDR_Forward_Counter
, ap.FDR_Time_Of_Minimum_Flow
, ap.FDR_Minimum_Flow
, ap.FDR_Time_Of_Broken_Pipe
, ap.FDR_Broken_Pipe_Flow
, ap.FDR_Current_Flow
, ap.FDR_Time_Of_Peak_Flow
, ap.FDR_Peak_Flow
, ap.FDR_Time_Of_Maximum_Flow
, ap.FDR_Maximum_Flow
, ap.FDR_Backward_Volume
, ap.FDR_Counter
, ap.FDR_Alarm_State
, ap.Transmission_Intervall
, ap.LAT_Interval
, utc.UTC_Offset
, wup.Wake_Up_Interval
, rfpl.PowerLevelHex
FROM eRegister_Auftragposition AS ap
LEFT JOIN eRegister_Metersize AS ms
ON ap.Meter_Size_Id = ms.Id
LEFT JOIN eRegister_Radiofrequency AS rf
ON ap.Radiofrequency_Id = rf.Id
LEFT JOIN eRegister_Unit AS u
ON ap.Unit_Id = u.Id
LEFT JOIN eRegister_DecimalPoint AS dp
ON ap.Decimal_Point_Id = dp.Id
LEFT JOIN eRegister_LeakagePeriod AS lp
ON ap.Leakage_Period_Id = lp.Id
LEFT JOIN eRegister_LeakageThreshold AS lt
ON ap.Leakage_Threshold_Id = lt.Id
LEFT JOIN eRegister_BrokenPipePeriod AS bpp
ON ap.Broken_Pipe_Period_Id = bpp.Id
LEFT JOIN eRegister_BrokenPipeThreshold AS bpt
ON ap.Broken_Pipe_Threshold_Id = bpt.Id
LEFT JOIN eRegister_DataLoggingPeriod AS dl
ON ap.Data_Logging_Period_Id = dl.Id
LEFT JOIN eRegister_UtcOffset AS utc
ON ap.UTC_Offset_Id = utc.Id
LEFT JOIN eRegister_WakeUpInterval AS wup
ON ap.Wake_Up_Interval_Id = wup.Id
LEFT JOIN eRegister_RFPowerlevel AS rfpl
ON rf.Frequency = rfpl.Frequenz
AND ms.Nennweite = rfpl.Nennweite) AS x
ON aap.FertigungsauftragNr = x.FertigungsauftragNr
JOIN Identnr AS idn
ON aap.IdentNr = idn.IdentNr
LEFT JOIN VAKO_Merkmale AS vm
ON SUBSTRING(idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
AND vm.Wert LIKE 'CSD%'
LEFT JOIN VAKO_Merkmale AS fs
ON SUBSTRING(idn.VakoCode, 1, LEN(fs.Basis)) = fs.Basis
AND SUBSTRING(idn.VakoCode, fs.Stelle, fs.Laenge) = fs.Charcode
AND fs.Bezeichnung LIKE 'Funkschlüssel'
FOR XML PATH('eProgrammingParameters')
, ROOT('eProgramingParametersList')) AS XML)")
.FirstOrDefault(x => x.GetXml(0));
var pams = eregister.BuildPams();
foreach (var pam in pams)
var serializer = new XmlSerializer(typeof(eProgramingParametersList));
var model = serializer.Deserialize(xml);
if (model is Eregister eregister)
{
Console.WriteLine($"{pam.Name}: {BitConverter.ToString(pam.CommandBytes.ToArray()).Replace("-", String.Empty)}");
foreach (var pam in eregister.BuildPams())
{
Console.WriteLine($"{pam.PamNames}: {BitConverter.ToString(pam.CommandBytes.ToArray())}");
Console.WriteLine();
}
}
}
@ -23,7 +225,7 @@
{
ChangeWakeUp = new ChangeWakeUp
{
Mode = WakeUpMode.StayAwake
WakeUpMode = WakeUpMode.StayAwake
},
ChangeMeterReading = new ChangeMeterReading
{

View File

@ -41,11 +41,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="JustSirtBroadcaster.cs" />
<Compile Include="JustSirtMessage.cs" />
<Compile Include="JustSirtProxy.cs" />
<Compile Include="JustSirtTask.cs" />
<Compile Include="JustTaskStatus.cs" />
<Compile Include="SIRT.cs" />
<Compile Include="SirtMessage.cs" />
<Compile Include="SirtProxy.cs" />
<Compile Include="SirtTask.cs" />
<Compile Include="TaskStatus.cs" />
<Compile Include="Parameters\BluetoothOperating.cs" />
<Compile Include="Parameters\OperatingModes.cs" />
<Compile Include="Parameters\P11.cs" />

View File

@ -4,15 +4,15 @@
using System.Collections.Concurrent;
using System.Threading;
public class JustSirtBroadcaster
public class SIRT
{
private static readonly ConcurrentDictionary<UInt32, JustSirtTask> runningTasks
= new ConcurrentDictionary<UInt32, JustSirtTask>();
private readonly JustSirtProxy proxy;
private static readonly ConcurrentDictionary<UInt32, SirtTask> runningTasks
= new ConcurrentDictionary<UInt32, SirtTask>();
private readonly SirtProxy proxy;
public JustSirtBroadcaster(String portName)
public SIRT(String portName)
{
this.proxy = new JustSirtProxy(portName);
this.proxy = new SirtProxy(portName);
this.proxy.MessageReceived += this.Proxy_MessageReceived;
}
@ -39,11 +39,11 @@
var awaiter = new ManualResetEventSlim();
var task = JustSirtTask.ActivateSIRT;
var task = SirtTask.ActivateSIRT;
task.Cancelled += _ => awaiter.Set();
task.Completed += _task =>
{
activated = _task.TaskStatus == JustTaskStatus.Completed;
activated = _task.TaskStatus == TaskStatus.Completed;
if (activated)
{
@ -60,11 +60,11 @@
if (activated)
{
task = JustSirtTask.IdentifySIRT;
task = SirtTask.IdentifySIRT;
task.Cancelled += _ => awaiter.Set();
task.Completed += _task =>
{
activated = _task.TaskStatus == JustTaskStatus.Completed;
activated = _task.TaskStatus == TaskStatus.Completed;
if (activated)
{
@ -96,25 +96,25 @@
return this.proxy.TryClose();
}
public JustTaskStatus TryRun(JustSirtTask task)
public TaskStatus TryRun(SirtTask task)
{
if (!this.proxy.IsOpen)
{
return JustTaskStatus.ProxyNotOpen;
return TaskStatus.ProxyNotOpen;
}
var address = task.Address;
if (runningTasks.TryGetValue(address, out var runningTask) && runningTask != null)
{
return JustTaskStatus.InRunningTasks;
return TaskStatus.InRunningTasks;
}
var countInPamPool = 0;
foreach (var _task in runningTasks.Values)
{
if (_task != null && _task.Cmd == JustSirtMessage.W_PAM)
if (_task != null && _task.Cmd == SirtMessage.W_PAM)
{
countInPamPool++;
}
@ -122,16 +122,16 @@
if (countInPamPool >= 5)
{
return JustTaskStatus.PamPoolIsFull;
return TaskStatus.PamPoolIsFull;
}
task = runningTasks.AddOrUpdate(address, task, (a, t) => task);
if (task.TaskStatus == JustTaskStatus.Completed)
if (task.TaskStatus == TaskStatus.Completed)
{
this.Task_DismissFromRunningTasks(task);
return JustTaskStatus.Completed;
return TaskStatus.Completed;
}
task.Cancelled += this.Task_DismissFromRunningTasks;
@ -141,10 +141,10 @@
this.proxy.WriteBytes(task);
this.Log($"{task.Address}|{BitConverter.ToString(task)}");
return JustTaskStatus.Sent;
return TaskStatus.Sent;
}
private void Proxy_MessageReceived(JustSirtMessage message)
private void Proxy_MessageReceived(SirtMessage message)
{
var address = message.Address;
@ -155,7 +155,7 @@
}
}
private void Task_DismissFromRunningTasks(JustSirtTask task)
private void Task_DismissFromRunningTasks(SirtTask task)
{
task.Cancelled -= this.Task_DismissFromRunningTasks;
task.Completed -= this.Task_DismissFromRunningTasks;

View File

@ -2,7 +2,7 @@
{
using System;
public class JustSirtMessage
public class SirtMessage
{
public const Byte MIN_LEN = 12;
public const Byte PC2SIRT = 0x55;
@ -23,14 +23,14 @@
private Byte[] bytes;
public JustSirtMessage(DateTime? timestamp = null)
public SirtMessage(DateTime? timestamp = null)
{
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = new Byte[MIN_LEN];
this.bytes[0] = PC2SIRT;
}
public JustSirtMessage(Byte[] bytes, DateTime? timestamp = null)
public SirtMessage(Byte[] bytes, DateTime? timestamp = null)
{
this.timestamp = timestamp ?? DateTime.Now;
this.bytes = bytes;
@ -132,7 +132,7 @@
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
public static implicit operator Byte[](JustSirtMessage message)
public static implicit operator Byte[](SirtMessage message)
=> message.ToByteArray() ?? new Byte[0];
private UInt16 CRCCCITT(Int32 start, Int32 length)

View File

@ -2,16 +2,15 @@
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Timers;
public class JustSirtProxy
public class SirtProxy
{
private readonly JustSerialPort serialPort;
private readonly List<Byte> buffer;
private readonly Timer timer;
public JustSirtProxy(String portName)
public SirtProxy(String portName)
{
var settings = new SerialPortSettings
{
@ -26,7 +25,7 @@
this.timer = new Timer();
}
public event Action<JustSirtMessage> MessageReceived;
public event Action<SirtMessage> MessageReceived;
public Boolean IsOpen => this.serialPort.IsOpen;
@ -96,7 +95,7 @@
}
this.bufferLength = this.buffer.Count;
this.start = this.buffer.IndexOf(JustSirtMessage.SIRT2PC);
this.start = this.buffer.IndexOf(SirtMessage.SIRT2PC);
if (this.start < 0)
{
@ -119,7 +118,7 @@
{
return;
}
else if (this.buffer[this.stopIX] != JustSirtMessage.STOP)
else if (this.buffer[this.stopIX] != SirtMessage.STOP)
{
return;
}
@ -129,7 +128,7 @@
this.buffer.CopyTo(this.start, this.bytes, 0, this.bytesLength);
this.buffer.RemoveRange(0, this.start + this.bytesLength);
this.MessageReceived?.Invoke(new JustSirtMessage(this.bytes));
this.MessageReceived?.Invoke(new SirtMessage(this.bytes));
}
}
}

View File

@ -6,14 +6,14 @@
using System.Collections.Concurrent;
using System.Timers;
public class JustSirtTask
public class SirtTask
{
private readonly Timer timer = new Timer();
private readonly JustSirtMessage request = new JustSirtMessage();
private readonly ConcurrentStack<JustSirtMessage> responses = new ConcurrentStack<JustSirtMessage>();
private readonly SirtMessage request = new SirtMessage();
private readonly ConcurrentStack<SirtMessage> responses = new ConcurrentStack<SirtMessage>();
public event Action<JustSirtTask> Completed;
public event Action<JustSirtTask> Cancelled;
public event Action<SirtTask> Completed;
public event Action<SirtTask> Cancelled;
public Byte Cmd
{
@ -45,35 +45,35 @@
set => this.request.Data = value;
}
public JustTaskStatus TaskStatus { get; protected set; }
public TaskStatus TaskStatus { get; protected set; }
public Byte[] LastPayload
=> this.responses.TryPeek(out var response)
? response.Data
: default(Byte[]);
public virtual void ReceiveMessage(JustSirtMessage response, Int32 mhz)
public virtual void ReceiveMessage(SirtMessage response, Int32 mhz)
{
this.responses.Push(response);
if (this.TaskStatus != JustTaskStatus.Completed)
if (this.TaskStatus != TaskStatus.Completed)
{
this.TaskStatus = JustTaskStatus.Running;
this.TaskStatus = TaskStatus.Running;
if (this.request.Cmd == JustSirtMessage.W_PAM)
if (this.request.Cmd == SirtMessage.W_PAM)
{
if (response.Cmd == JustSirtMessage.FROMAIR && response.Data[0] == JustSirtMessage.SEMI)
if (response.Cmd == SirtMessage.FROMAIR && response.Data[0] == SirtMessage.SEMI)
{
this.TaskStatus = JustTaskStatus.Completed;
this.TaskStatus = TaskStatus.Completed;
}
}
else if (response.Cmd == JustSirtMessage.ACKNANSW)
else if (response.Cmd == SirtMessage.ACKNANSW)
{
this.TaskStatus = JustTaskStatus.Completed;
this.TaskStatus = TaskStatus.Completed;
}
}
if (this.TaskStatus == JustTaskStatus.Completed)
if (this.TaskStatus == TaskStatus.Completed)
{
this.Completed?.Invoke(this);
this.timer.Stop();
@ -83,12 +83,12 @@
public virtual void PrepareForRun()
{
this.responses.Clear();
this.TaskStatus = JustTaskStatus.Pending;
this.TaskStatus = TaskStatus.Pending;
this.timer.AutoReset = false;
this.timer.Interval = 10_000;
this.timer.Elapsed += (sender, _1) =>
{
this.TaskStatus = JustTaskStatus.Cancelled;
this.TaskStatus = TaskStatus.Cancelled;
this.Cancelled?.Invoke(this);
};
@ -101,12 +101,12 @@
public override String ToString()
=> BitConverter.ToString(this.ToByteArray());
public static implicit operator Byte[] (JustSirtTask task)
public static implicit operator Byte[] (SirtTask task)
=> task?.ToByteArray() ?? new Byte[] { };
public static readonly JustSirtTask ActivateSIRT = new JustSirtTask
public static readonly SirtTask ActivateSIRT = new SirtTask
{
Cmd = JustSirtMessage.W_REG,
Cmd = SirtMessage.W_REG,
Address = 0x20000000,
P2 = 0x05,
Data = new Byte[]
@ -119,22 +119,22 @@
}
};
public static readonly JustSirtTask IdentifySIRT = new JustSirtTask
public static readonly SirtTask IdentifySIRT = new SirtTask
{
Cmd = JustSirtMessage.R_REG,
Cmd = SirtMessage.R_REG,
Address = 0x11001820,
P2 = 0x08
};
public static readonly JustSirtTask ReadPamPool = new JustSirtTask
public static readonly SirtTask ReadPamPool = new SirtTask
{
Cmd = JustSirtMessage.R_PAM,
Cmd = SirtMessage.R_PAM,
Address = 0xFFFFFFFF
};
public static JustSirtTask DeleteFromPamPool(UInt32 address) => new JustSirtTask
public static SirtTask DeleteFromPamPool(UInt32 address) => new SirtTask
{
Cmd = JustSirtMessage.W_PAM,
Cmd = SirtMessage.W_PAM,
P1 = new P811 { DelPamAdr = true },
Address = address
};

View File

@ -1,6 +1,6 @@
namespace Common.Hardware.Interfaces.Ports.SIRT
{
public enum JustTaskStatus
public enum TaskStatus
{
Pending = 0,
Running = 1,

View File

@ -21,7 +21,6 @@
public JustSerialPort(SerialPortSettings serialPortSettings)
{
this.serialPortSettings = serialPortSettings;
this.portName = this.serialPortSettings.PortName;
}

View File

@ -5,12 +5,14 @@
public class ChangeCustomerText : Pam
{
private Int32 serialno;
public ChangeCustomerText() : base(10, ChangeCustomerText)
{
}
public ChangeCustomerText(String text) : this()
=> this.Text = text;
public ChangeCustomerText(Object text) : this()
=> this.Text = $"{text}".Trim();
public String Text
{

View File

@ -35,7 +35,7 @@
public String HexKey
{
get => BitConverter.ToString(this.Key).Replace("-", String.Empty);
set => this.Key = value.ToBytes();
set => this.Key = value.ToByteArray();
}
}
}

View File

@ -9,14 +9,20 @@
}
public ChangeWakeUp(WakeUpMode mode) : base(2, ChangeWakeUpMode)
=> this.Mode = mode;
=> this.WakeUpMode = mode;
public WakeUpMode Mode
public WakeUpMode WakeUpMode
{
get => (WakeUpMode)this.bytes[1];
set => this.bytes[1] = (Byte)value;
}
public Byte Mode
{
get => this.bytes[1];
set => this.bytes[1] = value;
}
public static ChangeWakeUp AutoOff => WakeUpMode.SleepAutoOff;
public static ChangeWakeUp AutoOn => WakeUpMode.SleepAutoOn;

View File

@ -1,9 +1,15 @@
namespace Common.Hardware.WaterMeter.eRegister.Features
{
using System;
public class DeactivateAlarms : AlarmsMask
{
public DeactivateAlarms() : base(2, DeactivateAlarms)
{
}
public DeactivateAlarms(Byte alarmsMask) : base(alarmsMask, DeactivateAlarms)
{
}
}
}

View File

@ -63,6 +63,7 @@
<Compile Include="Data\DEBUG.cs" />
<Compile Include="Eregister.cs" />
<Compile Include="EregisterDebug.cs" />
<Compile Include="EregisterExtensions.cs" />
<Compile Include="EregisterPam.cs" />
<Compile Include="PamTypeAttribute.cs" />
<Compile Include="ParameterSet.cs" />

View File

@ -2,11 +2,6 @@
{
using Common.Hardware.WaterMeter.eRegister.Features;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class Eregister
{
[PamType(AuthLevel.II)]
@ -90,6 +85,10 @@
[PamType(AuthLevel.III)]
public SetBytterySeconds SetBytterySeconds { get; set; }
// TODO: Implement in builder
[PamType(AuthLevel.III)]
public ChangeRadioId ChangeRadioId { get; set; }
[PamType(AuthLevel.III)]
public SetPcbId SetPcbId { get; set; }
@ -99,6 +98,22 @@
[PamType(AuthLevel.O, true)]
public RequestLoggingData RequestLoggingData { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.I, true)]
public ChangePin ChangePinI { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.II, true)]
public ChangePin ChangePinII { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.III, true)]
public ChangePin ChangePinIII { get; set; }
// TODO: Implement in builder
// [PamType(AuthLevel.O)]
public ProvidePin ProvidePin { get; set; }
[PamType(AuthLevel.III, true)]
public SendTestPattern SendTestPattern { get; set; }
@ -114,7 +129,11 @@
[PamType(AuthLevel.II)]
public ChangeCustomerText ChangeCustomerText { get; set; }
[PamType(AuthLevel.O, true)]
// TODO: Implement in builder
// [PamType(AuthLevel.O)]
public ChangeSensusRFEncryptionKey ChangeSensusRFEncryptionKey { get; set; }
[PamType(AuthLevel.II)]
public EncapsulatedFlexNet EncapsulatedFlexNet { get; set; }
[PamType(AuthLevel.O)]
@ -128,147 +147,5 @@
[PamType(AuthLevel.III)]
public SetVariablePcbId SetVariablePcbId { get; set; }
public IEnumerable<EregisterPam> BuildPams()
{
var pams = this.GetPams()
.OrderBy(x => x.CommandBytes[0]);
var cmds = new List<EregisterPam>();
var pamsLevel0 = new List<EregisterPam>();
var pamsLevel1 = new List<EregisterPam>();
var pamsLevel2 = new List<EregisterPam>();
var pamsLevel3 = new List<EregisterPam>();
var pin1 = new ProvidePin { AuthLevel = AuthLevel.I }.ToByteArray();
var pin2 = new ProvidePin { AuthLevel = AuthLevel.II }.ToByteArray();
var pin3 = new ProvidePin { AuthLevel = AuthLevel.III }.ToByteArray();
foreach (var pam in pams)
{
if (pam.IsSingleCmd)
{
if (pam.AuthLevel == AuthLevel.I)
{
pam.CommandBytes.AddRange(pin1);
}
else if (pam.AuthLevel == AuthLevel.II)
{
pam.CommandBytes.AddRange(pin2);
}
else if (pam.AuthLevel == AuthLevel.III)
{
pam.CommandBytes.AddRange(pin3);
}
cmds.Add(pam);
}
else
{
if (pam.AuthLevel == AuthLevel.O)
{
pamsLevel0.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.I)
{
pamsLevel1.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.II)
{
pamsLevel2.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.III)
{
pamsLevel3.Add(pam);
}
}
}
var pamLevel0 = new EregisterPam();
foreach (var pam in pamsLevel0)
{
pamLevel0.Name += $"{pam.Name}{Environment.NewLine}";
pamLevel0.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel0.Name = pamLevel0.Name.Trim();
var pamLevel1 = new EregisterPam();
foreach (var pam in pamsLevel1)
{
pamLevel1.Name += $"{pam.Name}{Environment.NewLine}";
pamLevel1.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel1.Name = pamLevel1.Name.Trim();
pamLevel1.CommandBytes.AddRange(pin1);
var pamLevel2 = new EregisterPam();
foreach (var pam in pamsLevel2)
{
pamLevel2.Name += $"{pam.Name}{Environment.NewLine}";
pamLevel2.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel2.Name = pamLevel2.Name.Trim();
pamLevel2.CommandBytes.AddRange(pin2);
var pamLevel3 = new EregisterPam();
foreach (var pam in pamsLevel3)
{
pamLevel3.Name += $"{pam.Name}{Environment.NewLine}";
pamLevel3.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel3.Name = pamLevel3.Name.Trim();
pamLevel3.CommandBytes.AddRange(pin3);
cmds.Insert(0, pamLevel3);
cmds.Insert(0, pamLevel2);
cmds.Insert(0, pamLevel1);
cmds.Insert(0, pamLevel0);
return cmds;
}
private IEnumerable<EregisterPam> GetPams()
{
foreach (var eregisterProperty in typeof(Eregister).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var pamType = eregisterProperty.GetCustomAttribute<PamTypeAttribute>();
if (pamType is null)
{
continue;
}
var propertyValue = eregisterProperty.GetValue(this);
if (propertyValue is null)
{
continue;
}
else if (propertyValue is EregisterDebug debug)
{
foreach (var pam in debug.GetPams().OrderBy(x => x.CommandBytes[2]))
{
yield return pam;
}
}
else if (propertyValue is Pam pam)
{
yield return new EregisterPam
{
Name = eregisterProperty.Name,
AuthLevel = pamType.AuthLevel,
IsSingleCmd = pamType.IsSingleCmd,
CommandBytes = pam.ToByteArray().ToList()
};
}
}
}
}
}

View File

@ -1,10 +1,6 @@
namespace Common.Hardware.WaterMeter.eRegister
{
using Common.Hardware.WaterMeter.eRegister.Features;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class EregisterDebug
{
@ -52,35 +48,5 @@
[PamType(AuthLevel.III, true)]
public SetMeterType SetMeterType { get; set; }
internal IEnumerable<EregisterPam> GetPams()
{
foreach (var eregisterProperty in typeof(EregisterDebug).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var pamType = eregisterProperty.GetCustomAttribute<PamTypeAttribute>();
if (pamType is null)
{
continue;
}
var propertyValue = eregisterProperty.GetValue(this);
if (propertyValue is null)
{
continue;
}
else if (propertyValue is Pam pam)
{
yield return new EregisterPam
{
Name = eregisterProperty.Name,
AuthLevel = pamType.AuthLevel,
IsSingleCmd = pamType.IsSingleCmd,
CommandBytes = pam.ToByteArray().ToList()
};
}
}
}
}
}

View File

@ -0,0 +1,211 @@
namespace Common.Hardware.WaterMeter.eRegister
{
using Common.Hardware.WaterMeter.eRegister.Features;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public static class EregisterExtensions
{
public static IEnumerable<EregisterPam> BuildPams(this Eregister eregister)
{
var pams = eregister
.GetPams()
.OrderBy(x => x.CommandBytes[0]);
var cmds = new List<EregisterPam>();
var pamsLevel0 = new List<EregisterPam>();
var pamsLevel1 = new List<EregisterPam>();
var pamsLevel2 = new List<EregisterPam>();
var pamsLevel3 = new List<EregisterPam>();
var pin1 = new ProvidePin { AuthLevel = AuthLevel.I }.ToByteArray();
var pin2 = new ProvidePin { AuthLevel = AuthLevel.II }.ToByteArray();
var pin3 = new ProvidePin { AuthLevel = AuthLevel.III }.ToByteArray();
foreach (var pam in pams)
{
if (pam.IsSingleCmd)
{
if (pam.AuthLevel == AuthLevel.I)
{
pam.CommandBytes.AddRange(pin1);
}
else if (pam.AuthLevel == AuthLevel.II)
{
pam.CommandBytes.AddRange(pin2);
}
else if (pam.AuthLevel == AuthLevel.III)
{
pam.CommandBytes.AddRange(pin3);
}
cmds.Add(pam);
}
else
{
if (pam.AuthLevel == AuthLevel.O)
{
pamsLevel0.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.I)
{
pamsLevel1.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.II)
{
pamsLevel2.Add(pam);
}
else if (pam.AuthLevel == AuthLevel.III)
{
pamsLevel3.Add(pam);
}
}
}
if (pamsLevel3.Count > 0)
{
var pamLevel3 = new EregisterPam();
foreach (var pam in pamsLevel3)
{
pamLevel3.PamNames += $"{pam.PamNames}{Environment.NewLine}";
pamLevel3.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel3.PamNames = pamLevel3.PamNames?.Trim();
pamLevel3.CommandBytes.AddRange(pin3);
cmds.Insert(0, pamLevel3);
}
if (pamsLevel2.Count > 0)
{
var pamLevel2 = new EregisterPam();
foreach (var pam in pamsLevel2)
{
pamLevel2.PamNames += $"{pam.PamNames}{Environment.NewLine}";
pamLevel2.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel2.PamNames = pamLevel2.PamNames?.Trim();
pamLevel2.CommandBytes.AddRange(pin2);
cmds.Insert(0, pamLevel2);
}
if (pamsLevel1.Count > 0)
{
var pamLevel1 = new EregisterPam();
foreach (var pam in pamsLevel1)
{
pamLevel1.PamNames += $"{pam.PamNames}{Environment.NewLine}";
pamLevel1.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel1.PamNames = pamLevel1.PamNames?.Trim();
pamLevel1.CommandBytes.AddRange(pin1);
cmds.Insert(0, pamLevel1);
}
if (pamsLevel0.Count > 0)
{
var pamLevel0 = new EregisterPam();
foreach (var pam in pamsLevel0)
{
pamLevel0.PamNames += $"{pam.PamNames}{Environment.NewLine}";
pamLevel0.CommandBytes.AddRange(pam.CommandBytes);
}
pamLevel0.PamNames = pamLevel0.PamNames?.Trim();
cmds.Insert(0, pamLevel0);
}
return cmds;
}
public static IEnumerable<ProgrammingTask> BuildTasks(this IEnumerable<EregisterPam> pams, Action<ProgrammingTask> taskOptions)
{
foreach (var pam in pams)
{
var task = new ProgrammingTask();
taskOptions(task);
task.PamNames = pam.PamNames;
task.Data = pam.CommandBytes.ToArray();
}
yield break;
}
public static IEnumerable<EregisterPam> GetPams(this Eregister eregister)
{
foreach (var eregisterProperty in typeof(Eregister).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var pamType = eregisterProperty.GetCustomAttribute<PamTypeAttribute>();
if (pamType is null)
{
continue;
}
var propertyValue = eregisterProperty.GetValue(eregister);
if (propertyValue is null)
{
continue;
}
else if (propertyValue is EregisterDebug debug)
{
foreach (var pam in debug.GetPams().OrderByDescending(x => x.CommandBytes[2]))
{
yield return pam;
}
}
else if (propertyValue is Pam pam)
{
yield return new EregisterPam
{
PamNames = eregisterProperty.Name,
AuthLevel = pamType.AuthLevel,
IsSingleCmd = pamType.IsSingleCmd,
CommandBytes = pam.ToByteArray().ToList()
};
}
}
}
public static IEnumerable<EregisterPam> GetPams(this EregisterDebug debug)
{
foreach (var eregisterProperty in typeof(EregisterDebug).GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
var pamType = eregisterProperty.GetCustomAttribute<PamTypeAttribute>();
if (pamType is null)
{
continue;
}
var propertyValue = eregisterProperty.GetValue(debug);
if (propertyValue is null)
{
continue;
}
else if (propertyValue is Pam pam)
{
yield return new EregisterPam
{
PamNames = eregisterProperty.Name,
AuthLevel = pamType.AuthLevel,
IsSingleCmd = pamType.IsSingleCmd,
CommandBytes = pam.ToByteArray().ToList()
};
}
}
}
}
}

View File

@ -7,7 +7,7 @@
public class EregisterPam
{
public String Name { get; set; }
public String PamNames { get; set; }
public AuthLevel AuthLevel { get; set; }

View File

@ -103,7 +103,7 @@
internal ProgrammingTask BuildWupTxLatMBusTask()
=> new ProgrammingTask
{
Cmd = JustSirtMessage.W_PAM,
Cmd = SirtMessage.W_PAM,
P1 = new P811
{
DelPamSemi = true,
@ -124,7 +124,7 @@
internal ProgrammingTask BuildTestParametersTask()
=> new ProgrammingTask
{
Cmd = JustSirtMessage.W_PAM,
Cmd = SirtMessage.W_PAM,
P1 = new P811
{
DelPamSemi = true
@ -142,7 +142,7 @@
}
.Append(new ProvidePin
{
AuthLevel = Features.AuthLevel.III
AuthLevel = AuthLevel.III
}),
EncryptionKey = this.IsSealed ? this.EncryptionKey : null
};
@ -150,7 +150,7 @@
internal ProgrammingTask BuildSetupDisplayTask()
=> new ProgrammingTask
{
Cmd = JustSirtMessage.W_PAM,
Cmd = SirtMessage.W_PAM,
P1 = new P811
{
DelPamSemi = true
@ -167,7 +167,7 @@
internal ProgrammingTask BuildOptoOnTask()
=> new ProgrammingTask
{
Cmd = JustSirtMessage.W_PAM,
Cmd = SirtMessage.W_PAM,
P1 = new P811
{
DelPamSemi = true
@ -183,7 +183,7 @@
EncryptionKey = this.IsSealed ? this.EncryptionKey : null
};
internal void ParseParameters()
public void ParseParameters()
{
var length = this.Parameters?.Length ?? 0;
@ -252,78 +252,70 @@
if (!String.IsNullOrWhiteSpace(radioKey))
{
this.EncryptionKey = radioKey.ToBytes();
this.EncryptionKey = radioKey.ToByteArray();
}
}
}
}
var httpClient = new HttpClient();
}
internal IEnumerable<ProgrammingTask> BuildFinalProgrammingTasks()
public IEnumerable<ProgrammingTask> BuildFinalProgrammingTasks()
{
yield return new ProgrammingTask
var tasks = new Eregister
{
Cmd = JustSirtMessage.W_PAM,
Address = this.RadioAddress,
P1 = new P811
ChangeWakeUp = new ChangeWakeUp(WakeUpMode.StayAwake),
ChangeMeterReading = new ChangeMeterReading(this.DisplayVolume),
ChangeCustomerText = new ChangeCustomerText(this.Serialno),
DeactivateAlarms = new DeactivateAlarms(this.AlarmsMask),
ResetAlarms = new ResetAlarms(Byte.MaxValue),
ParameterizeLeakageDetection = new ParameterizeLeakageDetection(this.LeakageDetection),
ParameterizeBrokenPipeDetection = new ParameterizeBrokenPipeDetection(this.BrokenPipeDetection),
SetHistoricalErrorLimit = new SetHistoricalErrorLimit(this.HistoricalErrorLimit),
ChangeDataLoggerSettings = new ChangeDataLoggerSettings
{
TimeInterval = this.DataLoggerTimeInterval,
TimeOfMinimumFlow = this.DataLoggerMinFlowTime,
MinimumFlow = this.DataLoggerMinFlow
},
ChangeFixedDateReadingSettings = new ChangeFixedDateReadingSettings
{
DayOfMonth = this.FixedDateReadingDay,
SettingI = this.FixedDateReadingSettingI,
SettingII = this.FixedDateReadingSettingII
},
WirelessMBusMode = new WirelessMBusMode(this.MBusStatus),
SetPowerLevelSensusRF = new SetPowerLevel(this.PowerModeSensusRF),
SetPowerLevelFlexNet = new SetPowerLevel(this.PowerModeFlexNet),
ChangeNumberOfLatWindows = new ChangeNumberOfLatWindows(this.NumberOfLatWindows),
ChangeTransmissionInterval = new ChangeTransmissionInterval(this.TransmissionIntervalLast),
OpenMeteringTransmitionIntervalWMBus = new OpenMeteringTransmitionIntervalWMBus(this.OpenMeteringTransmissionInterval),
Debug = new EregisterDebug
{
DisableOTAFirmwareUpdate = new DisableOTAFirmwareUpdate(this.OTASettings),
SetActivationByThreshold = new SetActivationByThreshold(this.OTASettings),
}
}
.BuildPams()
.BuildTasks(options =>
{
options.Address = this.RadioAddress;
options.Cmd = SirtMessage.W_PAM;
options.P1 = new P811
{
DelPamSemi = true
},
Data = ChangeWakeUp.StayAwake
// Pin level 2 ^
// Pin level 3 - only production mode
.Append(new ChangeMeterId(this.MeterId))
// Pin level 3 - only production mode
.Append(new ChangeMeterReading(this.DisplayVolume))
// Pin level 2
.Append(new ChangeCustomerText($"{this.Serialno}"))
// Pin level 0
.Append(new AlarmsMask(this.AlarmsMask, Pam.DeactivateAlarms))
// Pin level 1
.Append(new ResetAlarms())
// Pin level 0
.Append(new ParameterizeLeakageDetection(this.LeakageDetection))
// Pin level 0
.Append(new ParameterizeBrokenPipeDetection(this.BrokenPipeDetection))
// Pin level 1
.Append(new SetHistoricalErrorLimit(this.HistoricalErrorLimit))
// Pin level 0
.Append(new ChangeDataLoggerSettings
{
TimeInterval = this.DataLoggerTimeInterval,
TimeOfMinimumFlow = this.DataLoggerMinFlowTime,
MinimumFlow = this.DataLoggerMinFlow
})
// Pin level 0
.Append(new ChangeFixedDateReadingSettings
{
DayOfMonth = this.FixedDateReadingDay,
SettingI = this.FixedDateReadingSettingI,
SettingII = this.FixedDateReadingSettingII
})
// Pin level 2
.Append(new WirelessMBusMode(this.MBusStatus))
// Pin level 0
.Append(new SetPowerLevel(this.PowerModeSensusRF))
// Pin level 3 - only production mode
.Append(new SetPowerLevel(this.PowerModeFlexNet))
// Pin level 3 - single cmd
.Append(new DisableOTAFirmwareUpdate(this.OTASettings))
// Pin level 3 - single cmd
.Append(new SetActivationByThreshold(this.OTASettings))
// Pin level 2
.Append(new OpenMeteringTransmitionIntervalWMBus(this.OpenMeteringTransmissionInterval))
// Pin level 2
.Append(new ChangeTransmissionInterval(this.TransmissionIntervalLast))
// Pin level 2
.Append(new ChangeNumberOfLatWindows(this.NumberOfLatWindows))
// Pin level 2
.Append(new ChangeSensusRFEncryptionKey(this.EncryptionKey))
// Pin level 3
.Append(new ChangeRadioId(this.FinalAddress))
};
};
});
foreach (var task in tasks)
{
yield return task;
}
}
}
}
//// TODO:
//// Pin level 2
//.Append(new ChangeSensusRFEncryptionKey(this.EncryptionKey))
//// Pin level 3
//.Append(new ChangeRadioId(this.FinalAddress))

View File

@ -21,7 +21,7 @@
private readonly Dictionary<Int32, Queue<ProgrammingTask>> completedTasks
= new Dictionary<Int32, Queue<ProgrammingTask>>();
private readonly ILogger logger = CreateNLogger("SIRT");
private JustSirtBroadcaster broadcaster;
private SIRT broadcaster;
private Int32 rssiRow;
public event Action<Int32, Int32, String, TaskState> OnProgress;
@ -272,7 +272,7 @@
foreach (var task in tasks)
{
if (task.TaskStatus != JustTaskStatus.Completed)
if (task.TaskStatus != TaskStatus.Completed)
{
this.broadcaster.TryRun(task);
@ -337,7 +337,7 @@
while (true)
{
if (this.broadcaster.TryRun(task) == JustTaskStatus.Sent)
if (this.broadcaster.TryRun(task) == TaskStatus.Sent)
{
task.Cancelled += _ => awaiter.Set();
task.Completed += _ => awaiter.Set();
@ -346,7 +346,7 @@
awaiter.Reset();
}
if (task.TaskStatus == JustTaskStatus.Completed)
if (task.TaskStatus == TaskStatus.Completed)
{
break;
}
@ -379,20 +379,6 @@
}
}
public void Run(ProgrammingTask task)
{
var status = this.broadcaster.TryRun(task);
var awaiter = new ManualResetEventSlim();
while (status != JustTaskStatus.Sent)
{
awaiter.Wait(1000);
awaiter.Reset();
status = this.broadcaster.TryRun(task);
}
}
public Boolean StartOnCOMPort(String portName)
{
var activated = false;
@ -401,7 +387,7 @@
{
this.Stop();
this.broadcaster = new JustSirtBroadcaster(portName);
this.broadcaster = new SIRT(portName);
this.broadcaster.Logging += this.logger.Debug;
if (this.broadcaster.TryActivate())

View File

@ -8,7 +8,7 @@
using System.Collections.Generic;
using System.Linq;
public class ProgrammingTask : JustSirtTask
public class ProgrammingTask : SirtTask
{
private const String PENDING = nameof(PENDING);
@ -31,6 +31,8 @@
public TaskState State { get; private set; } = TaskState.None;
public String PamNames { get; internal set; }
public override void PrepareForRun()
{
this.OnProgress?.Invoke(this);
@ -38,21 +40,21 @@
base.PrepareForRun();
}
public override void ReceiveMessage(JustSirtMessage response, Int32 mhz)
public override void ReceiveMessage(SirtMessage response, Int32 mhz)
{
if (this.EncryptionKey != null && this.EncryptionKey.Length == 16)
{
this.DecryptResponse(response);
}
if (this.State != TaskState.Success && response.Cmd == JustSirtMessage.FROMAIR)
if (this.State != TaskState.Success && response.Cmd == SirtMessage.FROMAIR)
{
var label = this.Label;
var state = this.State;
var data = response.Data;
var type = data[0];
if (type == JustSirtMessage.SEMI)
if (type == SirtMessage.SEMI)
{
var semi = new SEMI(data, (UInt16)mhz);
label = semi.PAMStatus.ToString();
@ -60,33 +62,33 @@
if (semi.PAMStatus == PAMStatus.OK)
{
state = TaskState.Success;
this.TaskStatus = JustTaskStatus.Completed;
this.TaskStatus = TaskStatus.Completed;
}
else
{
state = TaskState.Error;
this.TaskStatus = JustTaskStatus.Cancelled;
this.TaskStatus = TaskStatus.Cancelled;
}
this.semis.Add(semi);
}
else if (type == JustSirtMessage.BUP)
else if (type == SirtMessage.BUP)
{
label = nameof(JustSirtMessage.BUP);
label = nameof(SirtMessage.BUP);
state = TaskState.Warning;
this.bups.Add(new BUP(data));
}
else if (type == JustSirtMessage.LAT)
else if (type == SirtMessage.LAT)
{
label = nameof(JustSirtMessage.LAT);
label = nameof(SirtMessage.LAT);
state = TaskState.Warning;
this.lats.Add(new LAT(data));
}
else if (type == JustSirtMessage.DEBUG)
else if (type == SirtMessage.DEBUG)
{
label = nameof(JustSirtMessage.DEBUG);
label = nameof(SirtMessage.DEBUG);
state = TaskState.Warning;
this.debugs.Add(new DEBUG(data));
@ -130,7 +132,7 @@
}
else if (this.LastPayload != null)
{
var last = new JustSirtMessage(this.LastPayload);
var last = new SirtMessage(this.LastPayload);
P11 p11 = last.P1;
if (p11.LenOverflow)
@ -205,7 +207,7 @@
return new Tuple<String, TaskState>(label, TaskState.Success);
}
private void DecryptResponse(JustSirtMessage response)
private void DecryptResponse(SirtMessage response)
{
var data = response.Data;
var length = data.Length;

View File

@ -1,9 +1,12 @@
namespace Common.Logic.Extensions.SQL.Interfaces
{
using System;
using System.Xml;
public interface ISQLReader
{
XmlReader GetXml(Int32 index);
T GetValue<T>(Int32 index);
}
}

View File

@ -5,6 +5,8 @@
using System;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Xml;
public class SQLReader : ISQLReader, IDisposable
{
@ -19,6 +21,21 @@
this.sqlDataReader.Dispose();
}
public XmlReader GetXml(Int32 index)
{
var value = default(XmlReader);
if (0 <= index && index < this.sqlDataReader.FieldCount)
{
if (!this.sqlDataReader.IsDBNull(index))
{
value = this.sqlDataReader.GetSqlXml(index)?.CreateReader();
}
}
return value;
}
public T GetValue<T>(Int32 index)
{
var value = default(T);

View File

@ -233,7 +233,7 @@
return (Byte)sum;
}
public static Byte[] ToBytes(this String hexString)
public static Byte[] ToByteArray(this String hexString)
{
var bytes = new List<Byte>();

View File

@ -13,30 +13,70 @@
{
const String SENSUS_STANDARD = "E6C88800DEB868C0D6A84880CE982840";
private readonly SqlConnection sqlConnection;
public RadioKeyController()
=> this.sqlConnection = WebApiApplication.GetService<SqlConnection>();
[HttpGet]
[Route]
public IHttpActionResult Get([FromUri] Int32 serialno, [FromUri] Byte radioKeyType = 0)
[Route("byserialno/{serialno}")]
public IHttpActionResult Get([FromUri] Int32 serialno)
{
var pono = default(Int32);
var address = default(Int64);
var keyType = default(String);
this.sqlConnection
.CreateCommand($@"
SELECT DISTINCT
aap.FertigungsauftragNr
, aps.SerienNr
, er.Adresse
, idn.KeyType
FROM (SELECT DISTINCT
__idn.IdentNr
, SUBSTRING(vm.Wert, 1, 1) AS KeyType
FROM (SELECT DISTINCT
_idn.IdentNr
, _idn.VakoCode
FROM Identnr AS _idn
JOIN VAKO_Merkmale AS vm
ON SUBSTRING(_idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(_idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
AND ((vm.Stelle = 26 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M'))
OR (vm.Stelle = 9 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M')))
AND (vm.Wert LIKE '%eRegister%')) AS __idn
JOIN VAKO_Merkmale AS vm
ON SUBSTRING(__idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(__idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
WHERE vm.Schluessel = 'Funkschluessel') AS idn
JOIN AlleAuftragPositionen AS aap
ON idn.IdentNr = aap.IdentNr
JOIN AuftragPositionSerienNr AS aps
ON aap.AuftragNr = aps.AuftragNr
AND aap.PositionNr = aps.PositionNr
JOIN eRegister AS er
ON aps.SerienNr = er.Seriennummer
WHERE aps.SerienNr = @{nameof(serialno)}")
.SetParameter(nameof(serialno), serialno)
.FirstOrDefault(x =>
{
pono = x.GetValue<Int32>(0);
address = x.GetValue<Int64>(2);
keyType = x.GetValue<String>(3);
});
var radioKey = default(String);
if (radioKeyType == 1)
if (keyType == "S")
{
radioKey = SENSUS_STANDARD;
}
else if (radioKeyType == 2)
else if (keyType == "Z")
{
radioKey = this.GetOrdernoAndAddress(serialno, out var orderno, out var address);
if (String.IsNullOrWhiteSpace(radioKey))
{
radioKey = this.GetRadioKeyV2(orderno, address);
}
else
{
return this.BadRequest(radioKey);
}
radioKey = this.GetRadioKeyV2(pono, address);
}
else if (radioKeyType == 3)
else if (keyType == "K")
{
radioKey = this.GetRadioKeyCSD(serialno);
}
@ -44,47 +84,70 @@
return this.Ok(radioKey);
}
private String GetOrdernoAndAddress(Int32 serialno, out Int32 orderno, out Int64 address)
[HttpGet]
[Route("byaddress/{address}")]
public IHttpActionResult Get([FromUri] Int64 address)
{
orderno = 0;
address = 0;
var pono = default(Int32);
var serialno = default(Int32);
var keyType = default(String);
var result = default(String);
this.sqlConnection
.CreateCommand($@"
SELECT DISTINCT
aap.FertigungsauftragNr
, aps.SerienNr
, er.Adresse
, idn.KeyType
FROM (SELECT DISTINCT
__idn.IdentNr
, SUBSTRING(vm.Wert, 1, 1) AS KeyType
FROM (SELECT DISTINCT
_idn.IdentNr
, _idn.VakoCode
FROM Identnr AS _idn
JOIN VAKO_Merkmale AS vm
ON SUBSTRING(_idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(_idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
AND ((vm.Stelle = 26 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M'))
OR (vm.Stelle = 9 AND vm.Laenge = 1 AND vm.Charcode IN ('K', 'L', 'M')))
AND (vm.Wert LIKE '%eRegister%')) AS __idn
JOIN VAKO_Merkmale AS vm
ON SUBSTRING(__idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(__idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
WHERE vm.Schluessel = 'Funkschluessel') AS idn
JOIN AlleAuftragPositionen AS aap
ON idn.IdentNr = aap.IdentNr
JOIN AuftragPositionSerienNr AS aps
ON aap.AuftragNr = aps.AuftragNr
AND aap.PositionNr = aps.PositionNr
JOIN eRegister AS er
ON aps.SerienNr = er.Seriennummer
WHERE er.Adresse = @{nameof(address)}")
.SetParameter(nameof(address), address)
.FirstOrDefault(x =>
{
pono = x.GetValue<Int32>(0);
serialno = x.GetValue<Int32>(1);
keyType = x.GetValue<String>(3);
});
try
var radioKey = default(String);
if (keyType == "S")
{
var _orderno = 0;
var _address = 0L;
WebApiApplication
.GetService<SqlConnection>()
.CreateCommand($@"
SELECT DISTINCT TOP 1
aap.FertigungsauftragNr
, er.Adresse
FROM eRegister AS er
JOIN AuftragPositionSerienNr AS aps
ON er.Seriennummer = aps.SerienNr
JOIN AlleAuftragPositionen AS aap
ON aps.AuftragNr = aap.AuftragNr
AND aps.PositionNr = aap.PositionNr
WHERE er.Seriennummer = @{nameof(serialno)}")
.SetParameter(nameof(serialno), serialno)
.FirstOrDefault(reader =>
{
_orderno = reader.GetValue<Int32>(0);
_address = reader.GetValue<Int64>(1);
});
orderno = _orderno;
address = _address;
radioKey = SENSUS_STANDARD;
}
catch (Exception e)
else if (keyType == "Z")
{
result = e.Message;
radioKey = this.GetRadioKeyV2(pono, address);
}
else if (keyType == "K")
{
radioKey = this.GetRadioKeyCSD(serialno);
}
return result;
return this.Ok(radioKey);
}
private string GetRadioKeyCSD(Int32 serialno)
@ -93,17 +156,21 @@
try
{
radioKey = WebApiApplication
.GetService<SqlConnection>()
radioKey = this.sqlConnection
.CreateCommand($@"
SELECT DISTINCT
errk.Radiokey
FROM AlleAuftragPositionSerienNr AS aaps
JOIN AlleAuftragPositionVakoMerkmale AS aapvm
ON aaps.FertigungsauftragNr = aapvm.FertigungsauftragNr
JOIN eRegister_CSD_Radiokey AS errk
ON aapvm.Wert LIKE '%' + errk.CSD + '%'
WHERE aaps.SerienNr = @{nameof(serialno)}")
SELECT DISTINCT csd.Radiokey
FROM AuftragPositionSerienNr AS aps
JOIN AlleAuftragPositionen AS aap
ON aps.AuftragNr = aap.AuftragNr
AND aps.PositionNr = aap.PositionNr
JOIN Identnr AS idn
ON aap.IdentNr = idn.IdentNr
JOIN VAKO_Merkmale AS vm
ON SUBSTRING(idn.VakoCode, 1, LEN(vm.Basis)) = vm.Basis
AND SUBSTRING(idn.VakoCode, vm.Stelle, vm.Laenge) = vm.Charcode
JOIN eRegister_CSD_Radiokey AS csd
ON vm.Wert LIKE ('%' + csd.CSD + '%')
WHERE aps.SerienNr = @{nameof(serialno)}")
.SetParameter(nameof(serialno), serialno)
.FirstOrDefault(reader => reader.GetValue<String>(0));
}
@ -135,7 +202,14 @@
using (var httpResponseMessage = new HttpClient().SendAsync(httpRequestMessage).Result)
{
radioKey = httpResponseMessage?.Content?.ReadAsStringAsync()?.Result?.Trim('"');
if (httpResponseMessage.IsSuccessStatusCode)
{
radioKey = httpResponseMessage?.Content?.ReadAsStringAsync()?.Result?.Trim('"');
}
else
{
radioKey = httpResponseMessage.ReasonPhrase;
}
}
ServicePointManager.Expect100Continue = expect100Continue;

View File

@ -193,41 +193,11 @@
}
else
{
const String UrlFormat = "https://nodes.sms-esaap.com/keygenproxy/api/v2/keys/devices?orderNumber={0}&radioaddress={1}";
const String XNodeTokenHeaderName = "X-Node-Token";
const String XNodeTokenHeaderValue = "d5b8c0b2-81f6-4421-80d0-44eb2093e616";
var ponr = this.http
result = this.http
.SetBearer(this.bearer)
.Get<Int32>(request => request
.SetPath($"/LaaProductionWeb/api/search/pono/eregister/address/{token}"))
.Get<String>(request => request
.SetPath($"/LaaProductionWeb/api/eregister/radiokey/byaddress/{token}"))
.Value;
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, String.Format(UrlFormat, ponr, token)))
{
httpRequestMessage.Headers.Add(XNodeTokenHeaderName, XNodeTokenHeaderValue);
var expect100Continue = ServicePointManager.Expect100Continue;
var securityProtokol = ServicePointManager.SecurityProtocol;
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var httpResponseMessage = new HttpClient().SendAsync(httpRequestMessage).Result)
{
if (httpResponseMessage.IsSuccessStatusCode)
{
result = httpResponseMessage.Content?.ReadAsStringAsync()?.Result?.Trim('"');
}
else
{
result = httpResponseMessage.StatusCode.ToString();
}
}
ServicePointManager.Expect100Continue = expect100Continue;
ServicePointManager.SecurityProtocol = securityProtokol;
}
}
}
catch (Exception e)