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(Meter.ReadRegister("SENSUSRADIO_FrequencyIndicator")); RadioAdress = RegisterConverter.ByteArrayToValue(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; } } /// /// Speichert das gefüllte saveData Objekt via SaveRSSI Webservice /// 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 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 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 } }