En multitud de ocasiones tenemos que testear ciertos sistemas de monitorización, para lo cual necesitamos variables cambiando a donde poder apuntar. En este articulo vamos a ver como crear un servidor y cliente OPC UA sencillo, y lo haremos con Copilot en Visual Code.
La idea del artículo es doble: por un lado, proporcionar una forma de generar un servidor y cliente OPC UA y por otro, ver como las herramientas del Copilot Edits nos facilitan la programación, hasta el punto de que sentirás que el copiloto realmente eres tú…
El mundo de la programación, ha cambiado radicalmente, por lo menos para el desarrollo de micro servicios y aplicaciones. Basta con tener clara la idea y plantearla lo mejor posible, para que el Copilot Edits haga maravillas.
Contenido
- Generación del código
- Arrancando el servidor OPC
- Visualización gráfica – Cliente OPC Web
- Conclusiones
Generación del código
Como se observa en la imagen, estoy utilizando el modelo “Claude 3.7 Sonnet Thinking (Preview)” de Anthropic. Es un modelo que según mis pruebas, es muy capaz y resuelve mejor tanto el backend como el frontend de las aplicaciones que he hecho.
Obviamente tengo instalado Python en mi PC y la versión de pago de Copilot. Para este ejemplo, con el modelo gratuito de Copilot, usando gpt 4o, hubiese bastado.
Copilot Edits: es el asistente de programación que ACTÚA sobre el sistema; se le pasan los ficheros (o los crea) y los modifica. A diferencia del predecesor, Copilot chat, que era como el chatgpt, copiábamos y pegábamos. La diferencia es muy considerable.

Código generado, totalmente funcional y a la primera:
import time
import math
import random
from datetime import datetime
from opcua import Server, ua
def main():
# Inicializar el servidor
server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
# Configurar el espacio de nombres
uri = "http://example.org/dynamic-opcua-server"
idx = server.register_namespace(uri)
# Obtener el nodo de Objetos
objects = server.get_objects_node()
# Crear un objeto personalizado para nuestras variables
myobj = objects.add_object(idx, "DynamicVariables")
# Crear 10 variables de diferentes tipos con diferentes patrones
# 1. Booleano - alterna cada 5 segundos
bool_var = myobj.add_variable(idx, "BooleanVariable", False, ua.VariantType.Boolean)
bool_var.set_writable()
# 2. Entero - incremento lineal
int_var = myobj.add_variable(idx, "IntegerVariable", 0, ua.VariantType.Int32)
int_var.set_writable()
# 3. Float - patrón senoidal
float_var = myobj.add_variable(idx, "FloatVariable", 0.0, ua.VariantType.Float)
float_var.set_writable()
# 4. Double - crecimiento exponencial
double_var = myobj.add_variable(idx, "DoubleVariable", 1.0, ua.VariantType.Double)
double_var.set_writable()
# 5. String - cadenas aleatorias
string_var = myobj.add_variable(idx, "StringVariable", "Inicial", ua.VariantType.String)
string_var.set_writable()
# 6. DateTime - hora actual
datetime_var = myobj.add_variable(idx, "DateTimeVariable", datetime.now(), ua.VariantType.DateTime)
datetime_var.set_writable()
# 7. UInt16 - valores aleatorios
uint_var = myobj.add_variable(idx, "UInt16Variable", 0, ua.VariantType.UInt16)
uint_var.set_writable()
# 8. Byte - patrón circular (0-255)
byte_var = myobj.add_variable(idx, "ByteVariable", 0, ua.VariantType.Byte)
byte_var.set_writable()
# 9. Int64 - función cuadrática
int64_var = myobj.add_variable(idx, "Int64Variable", 0, ua.VariantType.Int64)
int64_var.set_writable()
# 10. Float Array - múltiples patrones senoidales
float_array_var = myobj.add_variable(idx, "FloatArrayVariable", [0.0, 0.0, 0.0, 0.0, 0.0], ua.VariantType.Float)
float_array_var.set_writable()
# Iniciar el servidor
server.start()
print(f"Servidor iniciado en {server.endpoint}")
try:
# Bucle de actualización
count = 0
while True:
time.sleep(1)
count += 1
# 1. Booleano - alterna cada 5 segundos
if count % 5 == 0:
bool_val = bool_var.get_value()
bool_var.set_value(not bool_val)
# 2. Entero - incremento lineal
int_var.set_value(count)
# 3. Float - patrón senoidal
float_var.set_value(math.sin(count * 0.1) * 10)
# 4. Double - crecimiento exponencial (reinicia para evitar desbordamiento)
exp_value = math.exp(count % 10) / 1000
double_var.set_value(exp_value)
# 5. String - cadenas aleatorias
strings = ["Alpha", "Beta", "Gamma", "Delta", "Epsilon"]
string_var.set_value(random.choice(strings))
# 6. DateTime - hora actual
datetime_var.set_value(datetime.now())
# 7. UInt16 - valores aleatorios
uint_var.set_value(random.randint(0, 65535))
# 8. Byte - patrón circular (0-255)
byte_var.set_value(count % 256)
# 9. Int64 - función cuadrática
int64_var.set_value((count % 20) ** 2)
# 10. Float Array - múltiples patrones senoidales con diferentes fases
float_array = [
math.sin(count * 0.1) * 10, # Senoidal normal
math.sin(count * 0.1 + 1) * 10, # Desfasado
math.cos(count * 0.1) * 10, # Cosenoidal
math.sin(count * 0.05) * 5, # Frecuencia diferente
math.sin(count * 0.1) * count % 10 # Amplitud variable
]
float_array_var.set_value(float_array)
print(f"Variables actualizadas, contador: {count}")
finally:
# Cerrar el servidor
server.stop()
if __name__ == "__main__":
main()
El propio Copilot ha generado los archivos y ha instalado los requerimientos:

Arrancando el servidor OPC
Y ya nos queda hacer la ejecución del archivo (por hacer algo…)
python opc_server.py
Y observamos como el servidor arranca correctamente:

Y verificamos en el UA Expert:

No es exagerado decir, que esto lleva menos de dos minutos desde que lo piensas hasta que lo tienes funcionando.
Visualización gráfica – Cliente OPC Web
Ya que estos 2 minutos, se han hecho cortos, vamos a pedirle algo de interfaz. Necesitamos otra aplicación web, que mediante un cliente OPC, que visualice todos los datos de forma estética y organizada.
El resultado es brutal, solo un intento y ya ha creado toda la estructura web necesaria así como la lógica en Python. Mi prompt era muy sencillo:

Resultado: toda la estructura generada.

Y otra vez…
python opc_client_web.py
Parece que todo ha ido bien.

Veamos la web:


Se están actualizando todas perfectamente y la web incluso tiene un aspecto chulo.
Conclusiones
- Hemos visto como crear un servidor y cliente OPC UA en cuestión de minutos con Copilot Edits y el modelo Claude 3.7 de Anthropic.
- Los resultados son impresionante, ya que la inversión de recursos es mínima para resultados de alta calidad.
- Podemos conseguir aplicaciones o microservicios en tiempo récord, que nos permiten enfocarnos en tareas de valor añadido.
- Estas aplicaciones, son fácilmente empaquetarles en docker, que funcionen e forma independiente del SO. Lo veremos en futuros artículos.
- En mi experiencia, los modelos “thinking” son cruciales para conseguir soluciones de programación sin demasiadas iteraciones. Son capaces de entender bien el contexto si se les acota debidamente mediante la indicación de los archivos clave.