Files
laatzen/Common/Ui/Common.UI/ViewModels/EregisterVM.cs
T

393 lines
12 KiB
C#

namespace Common.UI.ViewModels
{
using Common.Hardware.Ports;
using Common.Hardware.SIRT;
using Common.Hardware.SIRT.Parameters;
using Common.Hardware.WaterMeter.eRegister;
using Common.Hardware.WaterMeter.eRegister.Features;
using Common.Hardware.WaterMeter.eRegister.Models;
using Common.UI.Data;
using Common.UI.Infrastructure;
using Common.UI.Models;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Input;
internal class EregisterVM : ViewModel<EregisterVM>
{
private readonly SIRTFactory sirtFactory;
private readonly DeviceManager deviceManager;
private readonly EregisterPropertiesModel eregister;
private SIRTBroadcaster broadcaster;
public EregisterVM() : base()
{
this.IsConnectEnabled = true;
this.eregister = new EregisterPropertiesModel();
this.sirtFactory = AppHost.GetService<SIRTFactory>();
this.deviceManager = AppHost.GetService<DeviceManager>();
this.deviceManager.COMPortsChanged += this.UpdateComports;
this.COMPorts = new ObservableCollection<string>();
this.Addresses = new ObservableCollection<uint>();
this.EregisterProperties = new ObservableCollection<KvpViewModel>();
this.ConnectCommand = new Command(this.ConnectCommandHandler);
this.DisconnectCommand = new Command(this.DisconnectCommandHandler);
this.PickAddressCommand = new Command<uint>(this.PickAddressCommandHandler);
this.RemoveAddressCommand = new Command(this.RemoveAddressCommandHandler);
this.StartProgrammingCommand = new Command(this.StartProgrammingCommandHandler);
}
private string comPort;
public string COMPort
{
get => this.comPort;
set => this.Set(vm => vm.comPort = value);
}
private string sirtId;
public string SirtId
{
get => this.sirtId;
set => this.Set(vm => vm.sirtId = value);
}
private string frequency;
public string Frequency
{
get => this.frequency;
set => this.Set(vm => vm.frequency = value);
}
private bool? connected;
public bool? IsConnected
{
get => this.connected;
set => this.Set(vm => vm.connected = value);
}
private bool connectEnabled;
public bool IsConnectEnabled
{
get => this.connectEnabled;
set => this.Set(vm => vm.connectEnabled = value);
}
private bool disconnectEnabled;
public bool IsDisconnectEnabled
{
get => this.disconnectEnabled;
set => this.Set(vm => vm.disconnectEnabled = value);
}
private string addressesCount;
public string AddressesCount
{
get => this.addressesCount;
set => this.Set(vm => vm.addressesCount = value);
}
private uint? address;
public uint? Address
{
get => this.address;
set => this.Set(vm => vm.address = value);
}
private bool addressSelected;
public bool AddressSelected
{
get => this.addressSelected;
set => this.Set(vm => vm.addressSelected = value);
}
public ICommand ConnectCommand { get; }
public ICommand DisconnectCommand { get; }
public ICommand PickAddressCommand { get; }
public ICommand RemoveAddressCommand { get; }
public ICommand StartProgrammingCommand { get; }
public ObservableCollection<string> COMPorts { get; }
public ObservableCollection<uint> Addresses { get; }
public ObservableCollection<KvpViewModel> EregisterProperties { get; }
internal override void ViewModel_Loaded()
{
this.UpdateComports();
foreach (var property in this.eregister.GetProperties())
{
this.EregisterProperties.Add(new KvpViewModel
{
Key = property.Key,
Value = property.Value,
Row = this.EregisterProperties.Count
});
}
}
private void ConnectCommandHandler()
{
if (!string.IsNullOrWhiteSpace(this.COMPort))
{
this.broadcaster = this.sirtFactory.ConnectSIRT(this.COMPort);
this.broadcaster.Activated += this.Broadcaster_Activated;
this.broadcaster.Connected += this.Broadcaster_Connected;
this.broadcaster.Disconnected += this.Broadcaster_Disconnected;
this.broadcaster.Logging += this.Broadcaster_Log;
this.broadcaster.MessageReceived += this.GetAvailableAddresses;
this.IsConnected = false;
this.IsConnectEnabled = false;
this.IsDisconnectEnabled = false;
}
}
private void GetAvailableAddresses(SIRTMessage message)
{
if (message.Cmd != SIRTMessage.FROMAIR)
{
return;
}
var address = message.Address;
if (uint.MinValue >= address || address >= uint.MaxValue)
{
return;
}
var rssi = new RSSI(message.P2, this.broadcaster.Frequency);
if (rssi.Dbm < -70)
{
this.InvokeAsync(() => this.Addresses.Remove(address));
}
else
{
bool? inserted = false;
for (var i = 0; i < this.Addresses.Count; i++)
{
var _address = this.Addresses[i];
if (_address == address)
{
inserted = null;
break;
}
else if (_address > address)
{
this.InvokeAsync(() => this.Addresses.Insert(i, address));
inserted = true;
break;
}
}
if (inserted != null && inserted == false)
{
this.InvokeAsync(() => this.Addresses.Add(address));
}
}
this.AddressesCount = $"e-registers count: {this.Addresses.Count}";
}
private void Broadcaster_Log(string message)
{
}
private void Broadcaster_Disconnected()
{
this.IsConnected = null;
this.IsConnectEnabled = true;
this.IsDisconnectEnabled = false;
this.SirtId = default(string);
this.Frequency = default(string);
this.broadcaster.Activated -= this.Broadcaster_Activated;
this.broadcaster.Connected -= this.Broadcaster_Connected;
this.broadcaster.Disconnected -= this.Broadcaster_Disconnected;
this.broadcaster.Logging -= this.Broadcaster_Log;
this.broadcaster.MessageReceived -= this.GetAvailableAddresses;
}
private void Broadcaster_Connected()
{
this.InvokeAsync(() =>
{
this.IsConnected = false;
this.IsConnectEnabled = false;
this.IsDisconnectEnabled = true;
});
}
private void Broadcaster_Activated()
{
this.InvokeAsync(() =>
{
this.IsConnected = true;
this.IsConnectEnabled = false;
this.IsDisconnectEnabled = true;
this.SirtId = this.broadcaster.HexId;
this.Frequency = $"{this.broadcaster.Frequency}Mhz";
this.broadcaster.MessageReceived += this.GetAvailableAddresses;
});
}
private void DisconnectCommandHandler()
{
this.IsConnectEnabled = false;
this.IsDisconnectEnabled = false;
this.broadcaster.MessageReceived -= this.GetAvailableAddresses;
this.Addresses.Clear();
this.RemoveAddressCommandHandler();
Task.Run(() => this.sirtFactory.CloseConnection(this.COMPort));
}
private void UpdateComports()
{
this.InvokeAsync(() =>
{
this.COMPorts.Clear();
foreach (var comPort in this.deviceManager.COMPorts)
{
this.COMPorts.Add(comPort);
}
});
}
private void PickAddressCommandHandler(uint address)
{
this.RemoveAddressCommandHandler();
if (address > 0 && address < uint.MaxValue)
{
this.Address = address;
this.AddressSelected = true;
}
}
private void RemoveAddressCommandHandler()
{
this.Address = null;
this.AddressSelected = false;
}
private async void StartProgrammingCommandHandler()
{
var parametersList = AuftragDbContext.LoadEregisterProgrammingParametersListForSharedId(1);
var parameters = parametersList.FirstOrDefault();
if (parameters is null)
{
return;
}
var encryptionKey = default(string);
var uriFormat = Appsettings.Get("EncryptionKeisUrl");
var httpClient = new HttpClient();
using (var httpResponeMessage = await httpClient.GetAsync(string.Format(uriFormat, parameters.SerienNr)))
{
if (httpResponeMessage.IsSuccessStatusCode)
{
var content = await httpResponeMessage.Content?.ReadAsStringAsync();
encryptionKey = content?.Trim('"');
}
}
var features = new EregisterFeatures
{
SlotNr = parameters.Slotno,
SerialNr = parameters.SerienNr,
PoNr = parameters.FertigungsauftragNr,
RequestAddress = parameters.RequestAddress,
ResponseAddress = parameters.ResponseAddress,
Frequency = parameters.Frequency,
EncryptionKey = parameters.EncryptionKey.GetEncryptionKey(),
//ChangeRadioId = new ChangeRadioId
//{
// Address = 2000000000
//},
//ChangeMeterReading = new ChangeMeterReading
//{
// DisplayVolume = parameters.DisplayVolume
//}
Debug = new EregisterDebugFeatures
{
RequestDebugTelegram = new RequestDebugTelegram()
}
};
var pams = features.BuildPams();
foreach (var pam in features.BuildPams())
{
var task = new EregisterTask(this.broadcaster.Frequency)
{
P1 = new P811
{
DelPamSemi = true,
WakeUpCmd = true
},
RequestAddress = 4291189262,
ResponseAddress = 2000000000,
Data = pam.Value,
IsEncrypted = true,
EncryptionKey = encryptionKey.GetEncryptionKey()
};
task.Telegram += this.UpdateParameters;
task.Completed += this.TaskCompleted;
this.broadcaster.EnqueueTask(task);
}
}
private void TaskCompleted(SIRTTask task)
{
if (task is EregisterTask _task)
{
_task.Telegram -= this.UpdateParameters;
_task.Completed -= this.TaskCompleted;
}
}
private void UpdateParameters(object telegram)
{
if (telegram != null)
{
this.InvokeAsync(() =>
{
this.eregister.AddMessage(telegram);
foreach (var kvp in this.eregister.GetProperties())
{
var property = this.EregisterProperties.FirstOrDefault(x => x.Key == kvp.Key);
if (property != null)
{
property.Value = kvp.Value;
}
}
});
}
}
}
}