diff --git a/PLCViewModel.cs b/PLCViewModel.cs index 5737870..10d7b2c 100644 --- a/PLCViewModel.cs +++ b/PLCViewModel.cs @@ -52,6 +52,11 @@ namespace LibS7Adv private bool IsConfigured { get; set; } + // Añade una bandera para controlar el estado de actualización + private bool _isUpdating = false; + private DateTime _lastUpdateStartTime = DateTime.MinValue; + private TimeSpan _updateTimeout = TimeSpan.FromSeconds(10); // Timeout para reintentar después de un tiempo + [ObservableProperty] PlcData plcData = new PlcData(); @@ -123,20 +128,39 @@ namespace LibS7Adv private void Instance_OnSoftwareConfigurationChanged(IInstance instance, SOnSoftwareConfigChangedParameter event_param) { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Actualizar cuando recibimos el evento UpdateTagList(); + + // Cuando la actualización se completa exitosamente, desactivar la bandera + if (IsConfigured) + { + _isUpdating = false; + } + else + { + // Si no se pudo configurar, programar un reintento después de un tiempo + Task.Delay(1000).ContinueWith(_ => UpdateTagList()); + } } public void UpdateTagList() { IsConfigured = false; + _isUpdating = true; + try { - Instance?.UpdateTagList(ETagListDetails.IO | ETagListDetails.DB | ETagListDetails.M, true); // ETagListDetails.IO | ETagListDetails.DB + Instance?.UpdateTagList(ETagListDetails.IO | ETagListDetails.DB | ETagListDetails.M, true); IsConfigured = true; + _isUpdating = false; // Éxito en la actualización } catch (Exception ex) { PlcData.LastError = ex.Message; + // Mantener _isUpdating = true ya que hubo un error } } @@ -149,6 +173,22 @@ namespace LibS7Adv PlcData.LastError = "Not Connected"; return false; } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada, + // posiblemente se quedó trabado, intentamos de nuevo + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return false; + } + if (sTag == null) { return false; } var tag = ParseTagAddress(sTag); @@ -168,7 +208,21 @@ namespace LibS7Adv } catch (Exception ex) { - PlcData.LastError = sTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = sTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = sTag + ":" + ex.Message; + } return false; } } @@ -182,6 +236,22 @@ namespace LibS7Adv PlcData.LastError = "Not Connected"; return false; } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada, + // posiblemente se quedó trabado, intentamos de nuevo + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return false; + } + if (sTag == null) { return false; } var tag = ParseTagAddress(sTag); @@ -202,12 +272,25 @@ namespace LibS7Adv } catch (Exception ex) { - PlcData.LastError = sTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = sTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = sTag + ":" + ex.Message; + } return false; } } - public string? LeerNumber(string sTag, bool Signed = false) { try @@ -217,6 +300,21 @@ namespace LibS7Adv PlcData.LastError = "Not Connected"; return ""; } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return ""; + } + if (sTag == null) { return ""; } @@ -274,7 +372,21 @@ namespace LibS7Adv } catch (Exception ex) { - PlcData.LastError = sTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = sTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = sTag + ":" + ex.Message; + } return ""; } } @@ -285,11 +397,39 @@ namespace LibS7Adv { try { + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return false; + } + return Instance?.OutputArea.ReadBit(pByte, (byte)pBit) ?? false; } catch (Exception ex) { - PlcData.LastError = ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = ex.Message; + } return false; } } @@ -298,56 +438,223 @@ namespace LibS7Adv { try { + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return; + } + Instance?.InputArea.WriteBit(pByte, (byte)pBit, pValue); } catch (Exception ex) { - PlcData.LastError = ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = "Byte " + pByte + ", Bit " + pBit + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = ex.Message; + } } } + public void EscribirTag(string pTag, SDataValue Value) { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return; + } + Instance?.Write(pTag, Value); } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } } } + public SDataValue LeerTag(string pTag) { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return new SDataValue(); + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return new SDataValue(); + } + return Instance.Read(pTag); } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } return new SDataValue(); } } + public void EscribirTagBool(string pTag, bool pValue) { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return; + } + Instance?.WriteBool(pTag, pValue); } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } } } public void EscribirTagInt16(string pTag, int pValue) { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return; + } + Instance?.WriteInt16(pTag, (short)pValue); } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } } } @@ -355,12 +662,46 @@ namespace LibS7Adv { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return false; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return false; + } + bool result = Instance?.ReadBool(pTag) ?? false; return result; } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } return false; } } @@ -369,12 +710,46 @@ namespace LibS7Adv { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return 0; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return 0; + } + int? result = Instance?.ReadInt16(pTag); return result; } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } return 0; } } @@ -383,12 +758,46 @@ namespace LibS7Adv { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return 0; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar leer durante la actualización + return 0; + } + int? result = Instance?.ReadInt32(pTag); return result; } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } return 0; } } @@ -397,11 +806,45 @@ namespace LibS7Adv { try { + if (!isConnected) + { + PlcData.LastError = "Not Connected"; + return; + } + + // Verificar si estamos en proceso de actualización + if (_isUpdating) + { + // Si ha pasado mucho tiempo desde la última actualización intentada + if (DateTime.Now - _lastUpdateStartTime > _updateTimeout) + { + _lastUpdateStartTime = DateTime.Now; + UpdateTagList(); + } + + // No intentar escribir durante la actualización + return; + } + Instance?.WriteInt32(pTag, pValue); } catch (Exception ex) { - PlcData.LastError = pTag + ":" + ex.Message; + // Verificar si el error es NotUpToDate y activar la bandera si es así + if (ex.Message.Contains("NotUpToDate") || ex is SimulationRuntimeException sre && sre.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate) + { + _isUpdating = true; + _lastUpdateStartTime = DateTime.Now; + + // Iniciar actualización de tags + Task.Run(() => UpdateTagList()); + + PlcData.LastError = pTag + ": Tags no actualizados, reintentando..."; + } + else + { + PlcData.LastError = pTag + ":" + ex.Message; + } } }