common/ProductionUiCordonel/ProductionProcesses/Actions/ProductionProcessRadioCheck.cs
2026-04-23 17:50:07 +02:00

474 lines
15 KiB
C#

using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ProductionUiCordonelLegacy.ProductionProcesses.Enum;
using ProductionUiCordonelLegacy.UserControls.FinalTest;
using SIRTCOM;
using Xylem.Common.CommonCore.Configuration;
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.Consts;
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
using Xylem.Common.Logic.SoftwareAccessHelper;
using Button = System.Windows.Controls.Button;
using UserControl = System.Windows.Controls.UserControl;
namespace ProductionUiCordonelLegacy.ProductionProcesses.Actions
{
public class ProductionProcessRadioCheck : BaseProductionProcess
{
private UcRadioCheck UserControl;
public ProductionProcessRadioCheck()
{
name = "Radio Check";
currentProcessState = ProductionProcessState.Waiting;
}
public override void InitUserControl()
{
UserControl = new UcRadioCheck();
UserControl.OnRetryRequested += delegate { GetRssi(); };
UserControl.OnResetRequested += delegate { Reset(); };
UserControl.OnForceAPam += delegate { forcePush(); };
UserControl.OnDoneRequested += delegate
{
currentProcessState = ProductionProcessState.Done;
};
}
public override UserControl GetControl()
{
if (UserControl == null)
{
throw new Exception($"UserControl {GetType()} not Ready");
}
return UserControl;
}
public override void ProcessDone()
{
if (SENSUSRADIO_WakeupInterval != null)
{
var ret = Meter.WriteRegister("SENSUSRADIO_WakeupInterval", SENSUSRADIO_WakeupInterval, true, true);
if (!ret)
{
currentProcessState = ProductionProcessState.Error;
}
}
//clear
}
private Byte[] SENSUSRADIO_WakeupInterval;
public override void StartProcess()
{
//readout adress, freq,
if (Meter.RadioFrequencyMhz.HasValue)
{
var freq = RegisterConverter.ByteArrayToValue<UInt32>(Meter.ReadRegister("SENSUSRADIO_FrequencyIndicator"));
RadioAdress = RegisterConverter.ByteArrayToValue<UInt32>(Meter.ReadRegister("SENSUSRADIO_RadioAddress"));
Comport = Convert.ToByte(ConfigurationManager.AppSettings[$"SirtComport{freq}"]);
var enc = Meter.ReadRegister("SENSUSRADIO_EncryptionKey", 16);
EncyptionKey = LocalWebRequest.GetRequest($"{ServiceUrls.GenesisFinalCheckServiceUrl()}GetEncryptionKey?PcbID={Meter.PcbId}", 80000).ToUpper().Trim('\"');
if (!EncyptionKey.Equals(BitConverter.ToString(enc.ToArray()).Replace("-", "")))
{
MessageBox.Show("Funkschlüssel überprüfen!");
}
EncyptionKey = BitConverter.ToString(enc.ToArray()).Replace("-", "");
//if (freq == 868)
//{
// Comport = 8;
//}
//else
//{
// Comport = 7;
//}
BoxNr = Convert.ToByte(ConfigurationManager.AppSettings["SirtBoxNr"]);
DebugMessage($"Start RadioCheck Comport:{Comport} ,BoxNr:{BoxNr}, freq: {freq}, RadioAddress:{RadioAdress}s\r\n");
Meter.WriteRegister("SENSUSRADIO_IrDAModulePresent", 1, true, true);
SENSUSRADIO_WakeupInterval = Meter.ReadRegister("SENSUSRADIO_WakeupInterval");
Meter.WriteRegister("SENSUSRADIO_WakeupInterval", 0);
GetRssi();
}
else
{
currentProcessState = ProductionProcessState.Done;
}
}
#region FormerForm
private SaveData saveData;
private Statemashine stm;
private static HttpClient httpclient;
private Byte? RSSI_PAM_Min;
private Byte? RSSI_PAM_Max;
private Byte? RSSI_PAM;
private Byte? RSSI_SEMI_Min;
private Byte? RSSI_SEMI_Max;
private Byte? RSSI_SEMI;
public Byte BoxNr;
public Int32 Ordernumber;
public UInt32 RadioAdress;
public Byte Comport;
public String EncyptionKey = "";
private void enableBtn(Button btn, Boolean enable)
{
btn.Dispatcher.Invoke(DispatcherPriority.Send,
new Action(() =>
{
btn.IsEnabled = enable;
}
));
}
private void SetUi()
{
UserControl.SetUi(new UcRadioCheck.UIContainer(RSSI_PAM_Min, RSSI_SEMI_Min, RSSI_PAM, RSSI_SEMI, RSSI_PAM_Max, RSSI_SEMI_Max));
}
private async void GetRssi()
{
//StartProcess();
enableBtn(UserControl.btnGetRssi, false);
DebugMessage("");
saveData = new SaveData();
SetUi();
//Meter.WriteRegister("SENSUSRADIO_PowerLevel", 67, true, true);
//Meter.WriteRegister("SENSUSRADIO_PowerLevelOption", 59, true, true);
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeNew", 2992, true, true);
//Meter.WriteRegister("SENSUSRADIO_ImpedanceCodeOption", 2936, true, true);
try
{
await GetRssiMinMaxAsync(BoxNr, Ordernumber);
SetUi();
GetRSSI((Int32)RadioAdress, Comport, EncyptionKey);
SetUi();
}
catch (Exception ex)
{
DebugMessage($"Fehler in buttonSende_Click():\r\n{ex.Message}\r\n{ex.InnerException}", true);
}
enableBtn(UserControl.btnGetRssi, true);
}
private void clearRssi()
{
RSSI_PAM_Min = null;
RSSI_PAM_Max = null;
RSSI_PAM = null;
RSSI_SEMI_Min = null;
RSSI_SEMI_Max = null;
RSSI_SEMI = null;
}
private void Reset()
{
if (!(stm == null))
{
stm.ClearPam();
stm.Stop();
}
DebugMessage("Reset\r\n");
clearRssi();
SetUi();
StartProcess();
}
private class SaveData
{
public Int32 RadioAdress { get; set; }
public Byte RSSI_PAM { get; set; }
public Byte RSSI_SEMI { get; set; }
public Int32 LimitId { get; set; }
public Byte Result { get; set; }
}
/// <summary>
/// Speichert das gefüllte saveData Objekt via SaveRSSI Webservice
/// </summary>
private async void SaveDataToDB()
{
DebugMessage("Calling SaveRSSI Webservice...", true);
try
{
saveData.RadioAdress = (Int32)RadioAdress; // 0-4294967295
String url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}SaveRSSI";
String body = JsonConvert.SerializeObject(saveData);
await PostDataAsync(url, body);
DebugMessage(" Ready\r\n", true);
}
catch (Exception ex)
{
DebugMessage($"Fehler in SaveDataToDB():\r\n{ex.Message}\r\n{ex.InnerException}", true);
}
}
private async Task GetRssiMinMaxAsync(Byte BoxNr, Int32 FaNr)
{
//DebugMessage("Calling GetLimits Webservice...", true);
try
{
// TODO anpassen
String url = $"{ServiceUrls.GenesisRadioCheckServiceUrl()}GetLimits/{BoxNr}/{FaNr}";
String body = await GetResponseAsync(url);
JObject o = JObject.Parse(body);
saveData.LimitId = Convert.ToInt32(o.SelectToken("LimitId").ToString());
RSSI_PAM_Min = Convert.ToByte(o.SelectToken("RSSI_PAM_Min").ToString());
RSSI_PAM_Max = Convert.ToByte(o.SelectToken("RSSI_PAM_Max").ToString());
RSSI_SEMI_Min = Convert.ToByte(o.SelectToken("RSSI_SEMI_Min").ToString());
RSSI_SEMI_Max = Convert.ToByte(o.SelectToken("RSSI_SEMI_Max").ToString());
DebugMessage(" Ready\r\n", true);
}
catch (Exception ex)
{
saveData.LimitId = 0;
RSSI_PAM_Min = 100;
RSSI_PAM_Max = 200;
RSSI_SEMI_Min = 100;
RSSI_SEMI_Max = 200;
// RSSI_PAM_Min RSSI_PAM_Max RSSI_SEMI_Min RSSI_SEMI_Max
//145 164 182
// throw new Exception("Fehler in GetRssiMinMax()", ex);
}
}
private void GetRSSI(Int32 RadioAdress, Int32 ByteCOMPort, String strKey)
{
RSSI_PAM = null;
RSSI_SEMI = null;
stm = new Statemashine();
Byte P81_1 = 0;
saveData.RadioAdress = RadioAdress;
stm.initialise((Byte)ByteCOMPort);
Wrapper wrp = new Wrapper();
stm.StartLoggin("C:\\GenesisLog\\log.txt");
// ist wohl nicht nötig da der SIRT richtig konfiguroert ist:
// wrp.ActivateSirt(byte modul1, byte modul2, byte actTimeout, out byte outP12_01, out byte outP12_02);
DebugMessage($"Sending PAM to {RadioAdress.ToString()} ...", true);
stm.ClearPam();
stm.Timeout_s = 60;
if (strKey == "")
{
// Dummy PAM 00 OHNE Funkschlüssel
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, "", "0", false);
}
else
{
// Dummy PAM 00 mit Funkschlüssel
stm.SendPAM(RadioAdress.ToString(), "00", "", P81_1, 1, 0, strKey, "0", true);
}
stm.OnStateChanged += Stm_OnStateChanged;
stm.Start(); // Start polling
DebugMessage(" OK\r\n", true);
Meter.ResetAlarm(Alarm.EMPTY_PIPE);
Thread.Sleep(5000);
//Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x01, true, false);
forcePush();
if (false)
{
GotRSSICallback(1, 1);
}
}
private void forcePush()
{
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x55);
Meter.WriteRegister("SENSUSRADIO_SYSTEMSTATE", 0x02);
}
public void DebugMessage(String value, Boolean Append = false)
{
NewStatus(value);
}
private void GotRSSICallback(Byte Rssi_Semi_Sirt, Byte Rssi_Pam_Cord)
{
// RSSI beim Empfangen der PAM gemessen vom Cordonel (Sendestärke des SIRT verpackt in SEMI, byte 20)
DebugMessage($"RSSI Cord of PAM (Sirt => Cord):{Rssi_Pam_Cord}\r\n", true);
RSSI_PAM = Rssi_Pam_Cord;
RSSI_SEMI = Rssi_Semi_Sirt;
// RSSI beim Empfangen der SEMI gemessen vom SIRT (Sendestärke des Cordonel in byte 4)
DebugMessage($"RSSI Sirt of SEMI (Cord => Sirt):{Rssi_Semi_Sirt}\r\n", true);
saveData.RSSI_PAM = Rssi_Pam_Cord;
saveData.RSSI_SEMI = Rssi_Semi_Sirt;
saveData.Result = 1;
if (RSSI_PAM < RSSI_PAM_Min)
{
saveData.Result = 0;
}
if (RSSI_SEMI < RSSI_SEMI_Min)
{
saveData.Result = 0;
}
if (RSSI_PAM > RSSI_PAM_Max)
{
saveData.Result = 0;
}
if (RSSI_SEMI > RSSI_SEMI_Max)
{
saveData.Result = 0;
}
SaveDataToDB();
SetUi();
if (saveData.Result == 1)
{
UserControl.ViewResult();
}
}
private void Stm_OnStateChanged(Object sender, MyEventArgs e)
{
// our Pam
PAM Pam = stm.GetPAM(1);
if (Pam.State == PAM.PAMStates.Timeout)
{
DebugMessage($"Timeout nach {Pam.GetTime()} s\r\n");
}
if (Pam.CountSemi > 0)
{
// we recieved the SEMI
//btnGetRssi.IsEnabled = true;
stm.Stop();
stm.ClearPam();
String HexbytesSEMI = Pam.Semi.HexData.Replace(" ", "");
Byte[] SEMI_bytes = new Byte[HexbytesSEMI.Length / 2];
for (Int32 i = 0; i < HexbytesSEMI.Length; i += 2)
{
SEMI_bytes[i / 2] = Convert.ToByte(HexbytesSEMI.Substring(i, 2), 16);
}
// SEMI Status
if (SEMI_bytes[19] == 0)
{
// RSSI beim Empfangen der SEMI gemessen vom Sirt
Byte Semi_Rssi_Sirt = SEMI_bytes[2];
// RSSI beim Empfangen der PAM gemessen vom Cordonel
Byte Pam_Rssi_Cord = SEMI_bytes[20];
GotRSSICallback(Semi_Rssi_Sirt, Pam_Rssi_Cord);
}
else
{
// SEMI Status ist nicht 0.
DebugMessage(Pam.Semi.GetPamErrorMessage(), true);
}
stm.ClearPam();
}
else
{
DebugMessage($"BUPS:{Pam.CountBup}\r\n", true);
}
}
public static async Task<String> PostDataAsync(String url, String data)
{
httpclient = new HttpClient();
// 20 Sekunden Timeout
httpclient.Timeout = new TimeSpan(0, 0, 20);
StringContent queryString = new StringContent(data, Encoding.UTF8, "application/json");
HttpResponseMessage response = await httpclient.PostAsync(url, queryString);
response.EnsureSuccessStatusCode();
String content = await response.Content.ReadAsStringAsync();
return content;
}
private static async Task<String> GetResponseAsync(String url)
{
httpclient = new HttpClient();
// 20 Sekunden Timeout
httpclient.Timeout = new TimeSpan(0, 0, 20);
HttpResponseMessage response = httpclient.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
String content = await response.Content.ReadAsStringAsync();
return content;
}
#endregion
}
}