scieee AI-readable full text Open interactive document viewer

Repositorio Institucional de Documentos

Abstract

El presente proyecto consiste en un SCADA para la monitorización y supervisión de autómatas programables de forma remota con un enfoque al control de procesos industriales. El SCADA ha de ser capaz de acceder a cualquier PLC sin importar la marca del mismo. Además del control de autómatas, el SCADA también dispone de funcionalidades como pueden ser alarmas asociadas a eventos y el manejo de usuarios dentro de la plataforma. Se ha diseñado utilizando Python como lenguaje de programación principal de la aplicación y adicionalmente JavaScript como lenguaje de programación en el interfaz de usuario, obteniendo así una aplicación web, accesible tanto para ordenadores como para móviles. Finalmente, señalar que el proyecto ha nacido de la Cátedra entre TAIM-WESER y la Universidad de Zaragoza. Garzo Castro, Ricardo; Ponce de León Vázquez, Jesús

Full text

Ricardo Garzo Castro 1 PROYECTO FIN DE CARRERA Ingeniería Técnica Industrial: Electrónica SCADA Online Autor Ricardo Garzo Castro Director Jesús Ponce de León Escuela de Ingeniería y Arquitectura – Universidad de Zaragoza Marzo 2014 Ricardo Garzo Castro 2 . Ricardo Garzo Castro 3 Resumen El presente proyecto consiste en un SCADA para la monitorización y supervisión de autómatas programables de forma remota con un enfoque al control de procesos industriales. El SCADA ha de ser capaz de acceder a cualquier PLC sin importar la marca del mismo. Además del control de autómatas, el SCADA también dispone de funcionalidades como pueden ser alarmas asociadas a eventos y el manejo de usuarios dentro de la plataforma. Se ha diseñado utilizando Python como lenguaje de programación principal de la aplicación y adicionalmente JavaScript como lenguaje de programación en el interfaz de usuario, obteniendo así una aplicación web, accesible tanto para ordenadores como para móviles. Durante el mes de Febrero y Marzo de 2014, la aplicación web estará a uso de los interesados en la siguiente dirección IP: http://155.210.159.208:80/home . La aplicación web se encuentra alojada en un servidor del laboratorio de audio y video del departamento de electrónica de la Escuela de Ingeniería y Arquitectura. Al servidor está conectado un autómata programable de Siemens además de un segundo autómata simulado por software, y ambos se podrán controlar. Los credenciales para acceder al sitio web serán:  Usuario: usuario  Contraseña: contraseña Finalmente, señalar que el proyecto ha nacido de la Cátedra entre TAIM-WESER y la Universidad de Zaragoza. Ricardo Garzo Castro 4 Ricardo Garzo Castro 5 Índice Resumen ........................................................................................................................................ 3 Índice de Figuras ........................................................................................................................... 8 1. Capítulo 1. Introducción y objetivos. .................................................................................. 11 1.1 Objetivos ..................................................................................................................... 11 1.2 Ideas previas a la realización del proyecto.................................................................. 11 1.3 Organización del documento ...................................................................................... 12 2. Capítulos 2. Estado del arte................................................................................................. 12 2.1 Conceptos previos ....................................................................................................... 12 2.2 Antecedentes .............................................................................................................. 13 3. Capítulo 3. Desarrollo .......................................................................................................... 15 3.1 Descripción y esquemas del trabajo realizado ............................................................ 15 3.2 Comunicación con los PLCs ......................................................................................... 17 3.2.1 Respecto a servidores OPC .................................................................................. 19 3.2.2 Respecto a los clientes OPC ................................................................................ 19 3.3 Interfaz gráfico ............................................................................................................ 20 3.3.1 Documentos HTML, CSS y Bootstrap. ................................................................. 22 3.3.2 Lenguaje de programación Javascript, jqPlot y librerías jQuery ......................... 22 3.4 El servidor de internet ................................................................................................. 25 3.4.1 Diálogo HTTP ....................................................................................................... 25 3.4.2 Componentes del servidor de Internet ............................................................... 27 3.4.3 Seguridad ............................................................................................................. 28 3.5 La aplicación web ........................................................................................................ 29 3.5.1 Django como framework de la aplicación web ................................................... 30 3.5.2 Los modelos de la aplicación web ....................................................................... 32 3.5.3 Supervisión y adquisición de datos. .................................................................... 35 3.5.4 Actividades periódicas: Almacenaje en base de datos. ...................................... 36 3.5.5 Actividades periódicas: Alarmas. ........................................................................ 40 4. Capítulo 4. Resultados ......................................................................................................... 42 5. Capítulo 5. Conclusiones ..................................................................................................... 47 6. Anexos ................................................................................................................................. 49 6.1 Código del servidor web .............................................................................................. 49 6.1.1 Fichero urls.py ..................................................................................................... 49 6.1.2 Fichero automataconnect.py .............................................................................. 50 Ricardo Garzo Castro 6 6.1.3 Fichero tasks.py ................................................................................................... 51 6.1.4 Fichero views.py ......................................................................................................... 53 6.2 Código del cliente ........................................................................................................ 58 6.2.1 Función get_variable .................................................................................................. 58 6.2.2 Función process_value ............................................................................................... 61 6.2.3 Función graph_plot ............................................................................................. 63 7. Manual de Usuario .............................................................................................................. 66 7.1 Introducción ...................................................................................................................... 66 7.2 Instrucciones de uso .......................................................................................................... 66 7.2.1 Acceso al menú de administrador .............................................................................. 66 7.2.3 Adición de variables y tareas periódicas .................................................................... 66 7.2.3 Creación de usuarios del sistema ............................................................................... 67 7.3 Instrucciones de instalación .............................................................................................. 68 7.4.1 Paquetes Python ........................................................................................................ 69 7.4.2 Archivo de configuración Apache............................................................................... 70 Ricardo Garzo Castro 7 Ricardo Garzo Castro 8 Índice de Figuras Figura 1 Imagen de una planta manejada por un sistema de control industrial. ....................... 14 Figura 2 PLC de la marca Siemens. .............................................................................................. 15 Figura 3, Esquema de conexión para el SCADA Online ............................................................... 16 Figura 4 Diagrama de bloques de la plataforma software construida ........................................ 17 Figura 5 Diagrama Cliente-Servidor OPC ..................................................................................... 18 Figura 6 Control por consola de comandos del cliente OPC “OpenOPC for Python” ................. 20 Figura 7 Interfaz gráfico en un navegador web de escritorio. .................................................... 21 Figura 8 Interfaz gráfico en un dispositivo móvil ........................................................................ 21 Figura 9 Extracto de un fichero con contenido HTML. ................................................................ 22 Figura 10, Formato dado a la página web. .................................................................................. 22 Figura 11 Función Javascript con comunicación asíncrona y manipulación de documento HTML. ..................................................................................................................................................... 24 Figura 12 Gráfica construida mediante el plugin jqPlot .............................................................. 24 Figura 13 Diagrama de bloques del servidor de Internet ........................................................... 25 Figura 14 Respuesta del servidor ante una petición HTTP de tipo GET. ..................................... 26 Figura 15 Petición HTTP con método POST. ................................................................................ 26 Figura 16 Respuesta HTTP del servidor ante una petición HTTP tipo POST. .............................. 26 Figura 17 Diagrama de flujo para la conversión de diversos formatos en JSON ........................ 27 Figura 18 Configuración del servidor Apache para alojar la aplicación Python. ......................... 28 Figura 19 Esquema de urls con sus funciones asociadas de un fichero Python ......................... 30 Figura 20 Logo de Django, framework usado para construir la aplicación web. ........................ 30 Figura 21 Estructura del directorio que contiene la aplicación creada para este proyecto. ...... 31 Figura 22 Modelo Variable y sus distintas propiedades. ............................................................ 32 Figura 23 Código de admins.py para la configuración del formulario para incluir nuevas variables. ..................................................................................................................................... 34 Figura 24 Formulario para la creación de una nueva variable a controlar en la base de datos . 34 Figura 25 Código del script automataconnect.py para lectura de variables. .............................. 35 Figura 26 Código para el envío de respuestas HTTP con un documento HTML y un diccionario python. ........................................................................................................................................ 36 Figura 27 Formulario para la configuración de una actividad periódica en el navegador web. . 38 Figura 28 Código de la tarea de guardado del valor de una variable. ........................................ 38 Figura 29 Base de datos del muestro periódico de una variable. ............................................... 39 Figura 30 Formulario web para la solicitud de rango de valores de una variable durante un intervalo de tiempo. .................................................................................................................... 39 Figura 31 Trozo de código de la función que filtra las entradas de la base de datos. ................ 40 Figura 32 Gráfica de la evolución temporal de una variable a partir de la base de datos. ......... 40 Figura 33 Formulario de tarea periódica empleado para alarmas.............................................. 41 Figura 34 Código de la tarea encargada de gestionar las alarmas del SCADA. ........................... 42 Figura 35 Email de notificación de alarma ocurrida en el SCADA. .............................................. 42 Figura 36 Estructura del sitio web creado para el SCADA Online. .............................................. 43 Figura 37 Página web para lectura de variables. ........................................................................ 43 Figura 38 Página web para escritura de variables....................................................................... 44 Figura 39 Página web para elección de variables a controlar ..................................................... 44 Figura 40 Página web para la representación gráfica del registro histórico de una variable. .... 45 Ricardo Garzo Castro 9 Figura 41 Página web para el muestro en tabla de la evolución histórica de una variable. ....... 45 Figura 42 Página web para la creación de una gráfica a tiempo real del estado de una variable ..................................................................................................................................................... 46 Figura 43 Página web para creación de alarmas configurables por el usuario. .......................... 46 Figura 44 Página web para la administración de la aplicación web desde el navegador. .......... 47 Figura 45 Menú desplegable del usuario. ................................................................................... 66 Figura 46 Menú de administrador para Variables. ..................................................................... 66 Figura 47 Menú de administrador para Tareas periódicas. ........................................................ 67 Figura 48 Menú de gestión de usuario del sistema SCADA. ....................................................... 67 Figura 49 Formulario de creación de un nuevo usuario. ............................................................ 68 Figura 50 Formulario para los permisos de usuario. ................................................................... 68 Figura 51 Ejemplo del uso de pip en la consola de comandos Windows. ................................... 69 Figura 52 Directivas aplicables al interfaz wsgi en Apache. ........................................................ 70 Ricardo Garzo Castro 16 Para el control de autómatas y la garantía de que el SCADA funcione con cualquier marca de PLC se ha utilizado el estándar OPC, que es un estándar para la interoperabilidad creado por la industria de la automática. La configuración hardware del proyecto queda de la siguiente manera: el usuario accede al SCADA mediante un dispositivo que pueda ejecutar un navegador web, y todos los documentos y datos que el usuario necesite se generan en un único ordenador al que estarán conectados todos los PLCs. En este ordenador se ejecutarán las tareas pertinentes para devolver al usuario la información que solicite. Es necesario recalcar que para este SCADA, al mismo ordenador al que se conecten los PLCs también deberá alojar la aplicación web y el servidor de internet. Así que si existen PLCs conectados a otro ordenador que no tenga la aplicación web y el servidor, no se podrán controlar mediante este SCADA. Figura 3, Esquema de conexión para el SCADA Online Para explicar el apartado de software del proyecto se empleará todo lo que resta de este capítulo de la memoria. Y para fines didácticos se van a dividir todas las tareas que se realizan en el SCADA en bloques funcionales. En la siguiente figura se muestra un diagrama de bloques del proyecto a nivel de software: Ricardo Garzo Castro 17 Figura 4 Diagrama de bloques de la plataforma software construida Para mayor comprensión del lector, se explicarán a continuación de manera breve que es lo que hacen los distintos bloques: 1. Comunicación PLC: Es un conjunto de herramientas software que hace posible la comunicación con los distintos PLCs 2. Interfaz gráfico: Permitirá al usuario interactuar con los PLCs mediante iconos gráficos e indicadores visuales y mandará peticiones de información al servidor de internet. 3. Servidor de internet: Recibe las peticiones de información del usuario y envía las respuestas de la información solicitada permitiendo la comunicación vía internet. Gestiona peticiones y respuestas HTTP. 4. Aplicación web: La aplicación que se encargará de traducir las peticiones del usuario en órdenes para los PLCs y de generar los documentos para proveer al usuario con la información solicitada. En los siguientes apartados de este capítulo se irá explicando con más detalle cada uno de los bloques, qué es lo que hace y que objetivos ayuda a cumplir. También cómo funciona y las tecnologías empleadas en este bloque, además de cómo interactúa con los demás bloques que le rodean. 3.2 Comunicación con los PLCs Con este bloque se asegura la comunicación con PLCs, tanto lectura como escritura de variables e independientemente de la marca de los mismos. Y por lo tanto, en este apartado se hablará de como el protocolo de interoperabilidad OPC logra este objetivo. Ricardo Garzo Castro 18 La comunicación universal aporta grandes ventajas que no se tendrían si hubiera incompatibilidades con distintas marcas. Por ejemplo:  A la hora de comprar nuevos PLCs, la marca sería un factor determinante que podría eliminar la posibilidad de adquirir PLCs de mayor calidad.  No existe un gasto en tiempo y dinero que habría que invertir cada vez que se comprasen PLCs de otra marca para hacerlos compatibles con el sistema que ya hubiera. La solución al problema radica en usar el estándar de interoperabilidad OPC creado por la OPC foundation para el propósito que aquí se quiere conseguir, la comunicación con un sistema de adquisición de datos con independencia del fabricante. El protocolo OPC funciona con un esquema cliente-servidor. Esto significa que existen dos paquetes de software, uno para el servidor y otro para el cliente:  Los PLCs conectados al ordenador se comunican con el servidor OPC, que transforma las instrucciones propias de la marca del PLC en instrucciones OPC.  El servidor OPC se comunica con el cliente OPC, que transforma las instrucciones OPC en otras instrucciones de diverso tipo, ya sea python, C, java… En la Figura 5 se ilustra lo explicado, empleando Python como lenguaje de las aplicaciones que harán uso de la comunicación con los PLCs. De este modo: Figura 5 Diagrama Cliente-Servidor OPC Ricardo Garzo Castro 19 La Figura 5 es un ejemplo práctico de cómo funciona la tecnología OPC: los PLCs de distintas marcas se conectan a un servidor OPC que es capaz de comunicarse con el protocolo de cada marca, a su vez los servidores se comunican con el cliente OPC mediante el protocolo OPC y finalmente este cliente sirve los datos requeridos a las distintas aplicaciones Python. 3.2.1 Respecto a servidores OPC Como ya se ha comentado, un servidor OPC traduce las instrucciones propias del PLC a instrucciones OPC. Por lo tanto, el servidor deberá conocer el protocolo de comunicación del PLC con el que se quiera comunicar. Los protocolos de los PLCs cambian de un fabricante a otro y son cerrados. Así que para la creación de un servidor OPC se necesita acceso a una serie de herramientas de desarrollo de software no gratuitas que son los protocolos de cada marca de PLC. Esto hace que no se haya podido encontrar un servidor OPC de software libre, aunque existen servidores OPC desarrollados por las propias empresas que fabrican los PLCs o terceras compañías de software y actualmente, con la compra de PLCs se suelen distribuir también paquetes de software que incluyen servidores OPC , por lo que en principio resulta fácil acceder a estos. Esto significa que para poder usar el SCADA creado en este proyecto el usuario deberá adquirir por su cuenta un servidor OPC que satisfaga sus necesidades. Respecto a cómo funciona un servidor OPC y teniendo en cuenta que inicialmente uno se encuentra únicamente con una I/O analógica o digital:  Cuando se programa la tarea a realizar por el PLC, se especifica que I/O digital o analógica será a su vez una variable OPC. Esto se hace en el propio compilador de la tarea  A continuación, en el software que es el servidor OPC se añaden las variables del PLC que se deseen controlar. Así que ahora la I/O del PLC queda asignada a su servidor OPC correspondiente con un nombre específico.  La I/O del PLC ha quedado etiquetada de manera univoca a una variable OPC. Durante la realización de este proyecto se emplearon dos servidores OPC:  Un servidor OPC con simulador de variables de PLCs para la fase de desarrollo del SCADA Online llamado “MatrikonOPC Server for Simulation”, de la empresa Matrikon.  Y el segundo, un servidor de siemens llamado “S7-200 PC Access” que se usó para realizar pruebas sobre un PLC real, y en este caso de Siemens. 3.2.2 Respecto a los clientes OPC El cliente OPC es una herramienta que se comunica con el servidor OPC para crear una aplicación, ya sea representar datos en gráficas, guardar registros en bases de datos o un listado de comandos en python para controlar PLCs, y este último caso es el de este proyecto, donde se ha escogido el cliente OPC “OpenOPC for Python” que será controlado por la aplicación web. Este cliente OPC funciona mediante comandos en línea, lo que le otorga la ventaja especial de ser controlado mediante un script. En este script está el código para controlar los PLCs y la Ricardo Garzo Castro 20 aplicación web llamaría a este script para ejecutar las instrucciones pertinentes en función de lo que pida el usuario. Esto será explicado con mayor detalle en el apartado de la aplicación web. Con el cliente “OpenOPC for Python” se pueden realizar las siguientes funciones:  Adquisición de datos: Lectura y escritura de variable.  Consulta de tiempo: A qué hora y fecha se ha realizado algo sobre la variable.  Consulta de propiedades de la variable: como que tipo de variable es y si se puede escribir. En la Figura 6, mediante consola Python se importa el cliente OPC llamado OpenOPC, y después de conectarse al servidor de Matrikon se efectúa la lectura y escritura de la variable Random.Int4 y Triangle Waves.Real8. Figura 6 Control por consola de comandos del cliente OPC “OpenOPC for Python” La combinación de todas estas funciones permite alcanzar todos los objetivos requeridos en este proyecto en cuanto al tipo de tareas de adquisición de datos que se necesitan realizar sobre los PLCs. 3.3 Interfaz gráfico El interfaz gráfico se ejecuta en el navegador web del usuario, y es un documento HTML que usa javascript como lenguaje de programación. A lo largo de este apartado se hablará de las distintas tecnologías empleadas para crear una página web dinámica, que es lo que se emplea como interfaz gráfico de usuario, además del framework Bootstrap para el desarrollo de los documentos HTML. También se hablará de: HTML, CSS, Javascript, JQuery, jqPlot y Bootstrap. En las Figura 7 y Figura 8, se puede apreciar el interfaz gráfico sobre un navegador de escritorio y un navegador móvil respectivamente. Ricardo Garzo Castro 21 Figura 7 Interfaz gráfico en un navegador web de escritorio. Figura 8 Interfaz gráfico en un dispositivo móvil A continuación se explicarán los procesos involucrados en la creación del interfaz gráfico. Es decir, como llega el interfaz gráfico al navegador del usuario y que función desempeñan las distintas tecnologías empleadas en la creación del mismo. Para que el usuario pueda acceder al interfaz gráfico para controlar el SCADA, ha de acceder a su navegador web e introducir una URL perteneciente al SCADA. Esta URL es una petición HTTP Ricardo Garzo Castro 22 al servidor que tiene alojada la aplicación web. Esto se explicará con más detalle en los próximos apartados. Entre la aplicación y el servidor se encargan de gestionar la petición enviada y devuelven, si todo ha ido bien, un fichero HTML que se ejecutará en el navegador del usuario. 3.3.1 Documentos HTML, CSS y Bootstrap. El contenido en HTML del documento es el encargado de posicionar todos los elementos del documento, definiendo la estructura; tanto los párrafos con texto, los botones que desencadenan acciones y las tablas de información. Esto corresponde a la parte estática del interfaz gráfico, pues ese documento HTML permanece de forma invariante en el servidor y se envía cada vez que es solicitado. Además, el documento HTML contiene todo el código de las funciones Javascript que se necesitan para permitir la funcionalidad del interfaz. Figura 9 Extracto de un fichero con contenido HTML. Por otra parte, se usa CSS como lenguaje de estilo para dar aspecto y formato al contenido mostrado mediante HTML. Se usa para dar una buena presentación al documento, ganando usabilidad. Todo lo referente a CSS, que es lo mismo que hablar de la estética, en este proyecto viene dado por las librerías del framework Bootstrap. El resultado final es una página web en la que además se ha buscado un diseño gráfico bonito, empleando por ejemplo botones y marcos redondeados de distintos colores, como se aprecia en la Figura 10. Figura 10, Formato dado a la página web. La importancia de usar Bootstrap como framework de trabajo para el desarrollo de los documentos HTML y CSS ha sido fundamental, pues dota de un diseño gráfico que se ha convertido en un referente actual y es similar al empleado en la página web Twitter y que además permite un uso en dispositivos móviles. Esto puede parecer algo trivial en un principio, pero representar la información de forma elegante e intuitiva al usuario es algo que busca cualquier desarrollador de páginas web pues permite que la experiencia de manejar el SCADA sea algo agradable y rápido. De esta manera se puede conseguir que el cliente utilice una solución SCADA frente a otra solo por el hecho de que resulte más atractivo de usar. 3.3.2 Lenguaje de programación Javascript, jqPlot y librerías jQuery Javascript es el lenguaje de programación usado en páginas web. Se trata de código que es alojado en la parte del usuario, dentro del fichero HTML, y se emplean para interactuar con el usuario, controlar el navegador, comunicarse de forma asíncrona con la aplicación web y Ricardo Garzo Castro 23 alterar el contenido del documento a mostrar. Un ejemplo de cómo funciona una función javascript que realiza las funciones descritas aparece en la Figura 11: Ricardo Garzo Castro 24 Figura 11 Función Javascript con comunicación asíncrona y manipulación de documento HTML. De esta forma se ha obtenido información de forma asíncrona que se ha alojado en el mismo documento HTML original. El hecho de que no se solicite un nuevo documento HTML, sino que sea el documento original el que vaya cambiando es lo que dota de dinamismo al interfaz gráfico. Y esto, que aunque no se pueda apreciar de forma tan directa como es diseño del interfaz, es otra de las características que definen a este interfaz gráfico. Es decir, un interfaz dinámico. Hasta ahora se ha hablado exclusivamente de Javascript como un lenguaje de programación aislado. Pero también hay que tener en cuenta la librería de funciones JavaScript que se ha estado usando, jQuery. Como cualquier librería, sirve para implementar funciones de forma más rápida y en concreto, está orientada a facilitar la manipulación del documento HTML, manejo de eventos y comunicación asíncrona. En el Anexo 6.2 se puede ver ejemplos del uso de estas librerías. Como combinación del lenguaje de programación Javascript y la librería jQuery se desarrolló jqPlot, que es un plugin para realizar gráficas dentro de documentos HTML y el autor ha empleado en este proyecto para visualización de variables tanto en tiempo real como para representar información de bases de datos. En el Anexo 6.2 se presentará el código con detalle y aquí se explicará la funcionalidad del plugin jqPlot. Su misión es representar datos en un elemento del documento HTML. Los datos, en este caso de los PLCs, son suministrados al plugin jqPlot para que este cree el elemento del documento HTML que el usuario ve como una gráfica. En la Figura 12 se observa una gráfica creada mediante el plugin jqPlot. Figura 12 Gráfica construida mediante el plugin jqPlot Ricardo Garzo Castro 25 3.4 El servidor de internet Gracias al servidor de internet se tiene la posibilidad de una comunicación remota, para alcanzar el control de los PLCs mediante internet. Dicho de otra manera, el servidor de internet gestiona todas las peticiones y respuestas HTTP, y se queda como el nexo de unión entre el interfaz gráfico y la aplicación web Python. Sirve pues para enviar al usuario todos los ficheros y datos que requiera para hacer uso del SCADA. En la siguiente figura se ha representado con un diagrama de bloques el servidor de Internet: Figura 13 Diagrama de bloques del servidor de Internet 3.4.1 Diálogo HTTP A continuación se detallará en qué consiste el concepto de peticiones y respuestas HTTP del que se ha hablado anteriormente, y como se usan estos elementos para alcanzar los objetivos del proyecto. Un servidor lo que hace es recibir peticiones HTTP del usuario y manda de vuelta respuestas HTTP. Las peticiones HTTP son solicitudes de información por parte del usuario y las respuestas HTTP son los datos de respuesta del servidor ante la solicitud. La petición HTTP del usuario es una llamada a una url dentro del dominio del servidor web y se puede realizar de forma asíncrona, esto es cada vez que el usuario necesite información puede solicitarla inmediatamente. Por otra parte, las respuestas HTTP del servidor pueden ser estáticas, cuando los datos de la respuesta son ficheros alojados en el servidor; o dinámica, cuando los datos de la respuesta han sido generados por la aplicación web a partir del momento que el usuario ha mandado la petición. Para realizar peticiones HTTP en este proyecto se han usado los métodos GET y POST, cómo se puede ver en los anexos. A continuación se explican en qué consisten estos métodos:  GET: Se solicita cierta información al servidor. Este método solo debería devolver información, el usuario no mandaría datos. Por ejemplo cuando se entra a una url determinada, el servidor devuelve un documento HTML. O cuando el usuario solicita actualizar las variables, el servidor devolverá los nuevos valores. Pero en ningún caso el usuario manda datos al servidor. La siguiente imagen es la respuesta del servidor ante una petición HTTP de tipo GET. La respuesta, en formato JSON, contiene el valor actualizado de las variables contenidas en el servidor OPC. Ricardo Garzo Castro 32  Views.py: Todo el resto de funciones para que la aplicación web pueda funcionar se encuentran aquí. Como consultar el estado de una variable por ejemplo. Aquí se encuentra prácticamente todo el código realizado para la aplicación web. 3.5.2 Los modelos de la aplicación web Con Django, uno puede crear variables personalizadas para la aplicación que desea crear. Esto se hace a través de modelos. Un modelo es una manera de almacenar información pues puede contener los campos y propiedades que se deseen. Visto desde el punto de vista de la base de datos un modelo es una tabla, como las de una hoja de cálculo, y cada campo del modelo correspondería a un campo de la tabla. Pero siendo más técnico un modelo se asocia al concepto de clase en la programación orientada a objetos. A lo largo de este apartado se tratará sobre los modelos que se han definido para esta aplicación, que propiedades contienen y como una vez creados el usuario introduce información nueva. Para esta aplicación web se han creado dos modelos. Uno para poder representar variables de los PLCs y el otro para guardar un registro histórico de los valores de los PLCs. El código que los define se encuentra en el fichero models.py. El modelo Variable es empleado para la representación de variables del PLC y contiene una serie de campos para representar propiedades relacionadas con una variable OPC. Así se ve en la siguiente figura: Figura 22 Modelo Variable y sus distintas propiedades. A continuación se explicará la figura superior:  Variable: Es la clase que se usa para crear objetos de tipo Variable o User: Hace referencia al usuario que controla la variable. El usuario a su vez también es un tipo de modelo que trae Django creado en sus archivos fuente y por lo tanto no tiene que ser configurado. o Server: Con este campo se asocia el servidor OPC de la variable. o Node: Dentro de un servidor, en qué nodo se encuentra. o Name: El nombre de la variable. o Value: Su valor en un momento dado. Ricardo Garzo Castro 33 o Quality: Si la variable se ha podido leer correctamente, o no, se indicará con este campo. o Data_type: Esto es una herencia del tipo de variables OPC. Las variables OPC pueden ser, por ejemplo, enteros de 4 bytes con signo y esto ha de ser indicado. o Access_rights: Aquí se especifica si la variable es de escritura o lectura. o Display: Si el usuario desea que sea visible en las distintas operaciones de control del SCADA. Poniendo un ejemplo, lo explicado quedaría así en una base de datos: User Server Node Name Value Quality Data_type Access_rights Display Ricardo Matrikon Random Int2 32 good VT_4 write True Antonio SiemensOPC None Real4 45 good VT_4 read True El otro modelo, llamado TimeSeries, es para el registro histórico del estado de las variables de los PLCs. Esto es porque se querrá hacer una visualización histórica del estado de alguna de las variables. El modelo queda representado gráficamente de la siguiente manera:  TimeSeries: Es la clase que se usará para crear objetos de tipo TimeSeries. o Server: Nombre del servidor donde está alojada la variable. o Name: El nombre de la variable. o Value: El valor de la variable en un momento dado. o Time: Registro de la fecha y hora de lectura de la variable. Una vez explicado el proceso de configuración de los modelos se va a hacer hincapié en la creación de los mismos. Base de datos Ricardo Garzo Castro 34 Cada vez que se quiera incluir un nuevo modelo, por ejemplo una nueva variable a controlar de un PLC, lo que se hace es introducir en la base de datos la nueva variable para que el usuario pueda acceder a ella cuando lo necesite. Para poder realizar esto, la aplicación web ha de crear una página en el SCADA donde el usuario pueda a través de un formulario introducir los nuevos campos de la variable que desea controlar y cuando la aplicación web reciba la solicitud, almacene la información en la base de datos. Todas estas tareas se crean automáticamente con el framework Django. Y únicamente el autor ha de configurar el archivo admin.py para configurar que mostrará el formulario que rellene el usuario, como se ve a continuación: Figura 23 Código de admins.py para la configuración del formulario para incluir nuevas variables. Este código indica cuales son los campos que ha de rellenar en el formulario el usuario para poder incluir una nueva variable. Se puede ver que solo se requieren los campos de servidor y nombre de la variable, los demás campos se rellenaran posteriormente con otras funciones. Django con esta información y la de sus ficheros fuente crea el siguiente formulario que es accesible por el usuario: Figura 24 Formulario para la creación de una nueva variable a controlar en la base de datos Ricardo Garzo Castro 35 Hay que tener en cuenta que las variables que un usuario guarde en su cuenta, no se asignarán a la cuenta de otro usuario. De esta manera, cada usuario tendrá un SCADA con las variables a controlar que el desee. Es decir, cada usuario tendrá un SCADA personalizado a sus necesidades. Para el otro tipo de modelo para el registro histórico de variables el proceso es algo diferente al tratarse de tareas programables en el tiempo y cómo se crean nuevas tareas será tratado en el apartado 3.5.4 de este capítulo. Finalmente, cuando el usuario desee guardar información sobre los modelos se guardarán en una base de datos que viene incluida en las librerías que forman Python llamada SQLite. 3.5.3 Supervisión y adquisición de datos. El SCADA, y por lo tanto la aplicación web, ha de proveer al usuario con tareas de supervisión y adquisición de datos. Este tipo de tareas son la lectura y escritura de variables de los PLCs. Este tipo de tareas recibe y envía datos al usuario mediante el protocolo HTTP y se comunica con los PLCs mediante el cliente OPC. Cómo se reciben y envían esos datos ya se ha tratado previamente así que este apartado se centra en la comunicación de la aplicación web con el cliente OPC y los algoritmos para las funciones de supervisión y adquisición de datos. La aplicación web para comunicarse con el cliente OPC utiliza un script realizado por el autor llamado automataconnect.py. A este script se le importa el cliente OPC en forma de módulo python que recibe el nombre de OpenOPC. El módulo python es una librería de funciones del cliente OPC. El script además tiene dos funciones python: una para leer y otra para escribir sobre variables de PLCs. Como argumentos se envían nombre y servidor en el primer caso; y nombre, servidor y valor de escritura en el segundo. Figura 25 Código del script automataconnect.py para lectura de variables. El usuario accede a las tareas de supervisión y adquisición de datos en el interfaz desde tres páginas web distintas: una con una tabla con los valores de las variables, otra con una gráfica en tiempo real del estado de una variable y la última también con una tabla pero para la escritura de valores. Estas tres páginas web utilizan el navegador web para crear la interfaz pero necesitan de datos y documentos que provee la aplicación web. Ricardo Garzo Castro 36 En una primera instancia la aplicación web recibe una petición HTTP cuando el usuario accede a una de estas páginas, y la aplicación devuelve en una respuesta HTTP el documento HTML correspondiente a la página web solicitada y un diccionario python. Este diccionario Python contiene los valores e información acerca de todas las variables controladas por el usuario y la sintaxis del documento HTML se encarga de colocar esta información en el interfaz de usuario. Con llamadas al script automataconnect.py se obtienen los datos que alberga el diccionario python . Figura 26 Código para el envío de respuestas HTTP con un documento HTML y un diccionario python. Una vez que el usuario tiene en su navegador web la página web solicitada, este puede querer actualizar los valores de la variable o enviar a que valores desea escribir en ciertas variables. De esta manera, se realiza una comunicación asíncrona navegador-servidor para que la aplicación web ejecute la función correspondiente. Nótese que en ninguno de estos casos se vuelve a enviar un documento HTML, sino que se envían datos en formato JSON creados en el mismo instante que los solicita el usuario. Se trata únicamente de respuestas dinámicas. En esta segunda instancia se emplea el siguiente flujo de operaciones para las páginas web descritas:  Para actualización de tabla de valores: Cuando el usuario manda la petición HTTP para realizar esta operación, la función python llama al script automataconnect.py para obtener de nuevo un diccionario con la información completa de las variables de los PLCs. El diccionario se codifica en formato JSON.  Para actualizar la gráfica de una variable: El usuario manda la variable que desea actualizar y la función python devuelve una string en formato JSON dando la información de la variable y el instante de tiempo en que fue capturada .  Para escritura de variables: Se decodifica del formato JSON los nuevos valores de las variables que el usuario ha enviado, y se escriben en los PLCs llamando al script automaconnect.py para que finalmente se devuelva al usuario, en formato JSON, mensajes informando si se ha podido o no llevar a cabo la operación. Mediante este apartado se ha pretendido dar a conocer conceptualmente los algoritmos de control pero para más detalle en profundidad acerca de las funciones y código python del fichero views.py se puede consultar el Anexo 6.1.4. 3.5.4 Actividades periódicas: Almacenaje en base de datos. Una característica interesante del SCADA es la posibilidad de incluir un registro histórico de las variables de PLCs para que de esta manera se puedan representar gráficas temporales de la Ricardo Garzo Castro 37 evolución de una variable a lo largo del tiempo. Para lograr esto es necesario estar almacenando durante un periodo de tiempo muestras de la variable a una frecuencia determinada. Algo que rítmicamente guarde información en la base de datos. Esto se consigue mediante un ejecutor de código acorde a un horario llamado Celery. El usuario deberá configurar qué variable quiere controlar y con qué frecuencia mediante el interfaz gráfico del navegador web. Configurando los ficheros de Django y Celery se le muestra el siguiente formulario web al usuario. Donde se puede ver que aparecen los campos necesarios en el siguiente orden de aparición:  Nombre que se le da a esta tarea periódica: “Muestro de variable Triangle Wave4”  El nombre de la función que ha de llevarse a cabo periódicamente: “variables.tasks.store_value”, que es la función encargada de almecenar el valor de una variable en la base de datos.  El intervalo de tiempo, que son cinco minutos en este ejemplo.  Los argumentos de la variable escritos en forma de string, que son el servidor “Matrikon.OPC.Simulation1” y el nombre de la variable “Triangle Waves.Real8”. Ricardo Garzo Castro 38 Figura 27 Formulario para la configuración de una actividad periódica en el navegador web. El formulario que ha rellenado el usuario es enviado a la aplicación web que ejecutará, en este caso, la tarea de almacenar el valor de la variable a la frecuencia estipulada a través del mecanismo de programación Celery. La tarea leerá el valor de la variable y almacenará en la base de datos el valor de la variable y su servidor al igual que la fecha y tiempo de lectura. Figura 28 Código de la tarea de guardado del valor de una variable. Ricardo Garzo Castro 39 En la siguiente figura se puede observar la tabla de la base de datos que se obtiene con la tarea periódica de guardado periódico. La frecuencia de muestro para este ejemplo es de cinco segundos aunque el muestro fue parado hasta en tres ocasiones: Figura 29 Base de datos del muestro periódico de una variable. Cuando el usuario desee acceder a esta información para poder representar en su navegador web deberá mediante un formulario solicitar a la aplicación web que variable y que rango de tiempo de tiempo desea consultar: Figura 30 Formulario web para la solicitud de rango de valores de una variable durante un intervalo de tiempo. Cuando la aplicación web recibe la petición del usuario, utiliza los valores del formulario para filtrar la información que haya en la base de datos y encontrar de esta manera los valores guardados para el rango de tiempo determinado. Las consultas a la base de datos se realizan mediante una capa de abstracción para bases de datos (del inglés Database Abstraction Layer) que proporciona Django. Esto es una API para facilitar la comunicación mediante la aplicación web python y el lenguaje propio de la base de datos, SQLite en este caso. En la siguiente figura se puede observar un trozo de la función que realiza lo descrito, más concretamente las líneas que filtran toda las entradas de la base de datos para que solo estén disponibles únicamente las del servidor y variable que ha solicitado el usuario. La función continúa filtrando el resto de parámetros hasta quedarse únicamente con las entradas correctas. Ricardo Garzo Castro 40 Figura 31 Trozo de código de la función que filtra las entradas de la base de datos. Finalmente la función devuelve en formato JSON al navegador web la información de la variable solicitada, si la hubiese, para que este la procese y la muestre en gráficas o en tablas. Figura 32 Gráfica de la evolución temporal de una variable a partir de la base de datos. 3.5.5 Actividades periódicas: Alarmas. El SCADA contiene una función de alarma para que alertar al usuario de que una variable ha alcanzado un valor no deseado. Para que esto sea posible ha de especificarse que variable hay que controlar, el rango de valores que se consideran peligrosos y la frecuencia de muestro de la variable. Como se puede observar se comparte una similitud con respecto al guardado periódico de variables y es que aquí también existe una componente de periodicidad. Aunque en este caso no se guardan valores en una base de datos. Ricardo Garzo Castro 41 Por lo tanto el usuario deberá rellenar el mismo formulario que para el guardado periódico solo que en esta ocasión se especificará que la función a repetir ha de ser la encargada de gestionar las alarmas y los argumentos serán: la variable a controlar, el servidor OPC donde se encuentra, el valor límite, la condición para que salte la alarma y el email donde se enviará la notificación. Figura 33 Formulario de tarea periódica empleado para alarmas. Cuando a la aplicación web le llega la petición del formulario ejecuta, a través de Celery, la tarea periódica encargada de las alarmas. Esta tarea lee el valor de la variable a controlar y si el valor actual no está dentro del rango seguro se envía un email alertando de lo ocurrido. En la Figura 34 se recoge un trozo del código de la tarea “alarm”. Esta función recibe los valores del formulario como parámetros. A continuación lee el valor de la variable y evalúa si está dentro del rango que ha especificado el usuario para mandar un email. Ricardo Garzo Castro 48 Por otra parte y en referencia al SCADA, pienso que el hecho de que lo haya decidido desarrollar para funcionar en un navegador web frente a realizar una aplicación de escritorio ha sido algo importante. Últimamente, en el mundo de la informática, se está tendiendo a la computación en internet. Hace unos años esto se traducía en almacenamiento de datos online, pero ahora es fácil ver plataformas de desarrollo de software que funcionan completamente Online como, “Salesforce.com Inc”, o de computación online de tareas. Por esto, este SCADA marca una diferencia frente a otro SCADA hecho mediante una aplicación de escritorio. Pues no en tanto en las funciones que pueda realizar como SCADA propiamente dicho, sino en la manera de ejecutarse, que es mediante internet. Ricardo Garzo Castro 49 6. Anexos A lo largo de la Memoria se ha ido explicando el funcionamiento del SCADA Online sin entrar con mucho detalle en el código que lo desarrolla. Por lo tanto, aquí se va a exponer y explicar con detalle el código desarrollado únicamente por el autor para este SCADA y así quedará clara para el lector la frontera entre lo que ha creado el autor y las librerías integradas en los distintos frameworks usados. 6.1 Código del servidor web En este apartado se mostrará y explicará el código relacionado con las funciones que componen la aplicación web. 6.1.1 Fichero urls.py Este fichero, urls.py, alojado dentro de la carpeta django_scada sirve para relacionar cada una de las urls del proyecto con su función python. Esta es la estructura de urls creada por el autor donde mediante la directiva url(r’^home/’, ‘variables.views.home’) se ha asociado a la url home/ la función home que está en el fichero views dentro de la carpeta variables . Esta directiva es empleada con el resteo de las urls del sistema como se ve en el siguiente conjunto de código. Ricardo Garzo Castro 50 urlpatterns = patterns('', #Url de la página de inicio. url(r'^home/', 'variables.views.home'), #Url del manual de usuario url(r'^manual/', 'variables.views.manual'), #Url de lecutras de vairable url(r'^read/', 'variables.views.read'), #Url para enviar datos mediante HTTP Request para refrescar variables url(r'^json/read_update/','variables.views.read_update'), #Url de escritura de variables url(r'^control/','variables.views.control'), #Url para enviar datos mediante HTTP Request para escribir variables url(r'^json/control_response/', 'variables.views.control_response'), #Url para selecionar las variables a mostrar url(r'^display_editor/','variables.views.display_editor'), #Url para intercambio de datos cliente-navegador mediante HTTP Request url(r'^json/display_editor_response/', 'variables.views.display_editor_response'), #Url para la página con la gráfica para variables url(r'^graph_live/', 'variables.views.graph_live'), #Url de intercambio asíncrono de datos para la gráfica mediante HTTP Request url(r'^json/graph_live/', 'variables.views.json_graph_live'), #Url para mostrar la gráfica de representación histórica de variables url(r'^graph_db/', 'variables.views.graph_db'), #Url para intercambio de datos mediante HTTP Request de la gráfica histórica url(r'^json/graph_db/', 'variables.views.json_query_db'), #Url para crear una tabla con los valores históricos de variables url(r'^log_db/', 'variables.views.log_db'), #Url para intecambio de datos mediante HTTP Request para la tabla de valores históricos url(r'^json/log_db/', 'variables.views.json_query_db'), #Url de django para el menú de administrador 6.1.2 Fichero automataconnect.py Con las funciones de este fichero se comunican las funciones de la aplicación web con el cliente OPC y de esta manera se puede considerar este fichero como una librería La función read tiene como parámetros de entrada el servidor y el nombre de la variable a leer. Con esta información se conecta al servidor indicado y hace una letura para el valor, calidad , fecha a la que se ha leído la variable y además los derechos de acceso a esa variable. Finalmente devuelve a la función de la que ha sido llamado todos los datos en formato string. En caso de que no se haya podido realizar la lectura, devuelve strings avisando del error. Ricardo Garzo Castro 51 def read(server,name): try: opc = OpenOPC.open_client('localhost') opc.connect(server) value, quality, time = opc.read(name) access_rights=opc.properties(name, id=5) opc.close() value=str(value) return value,quality,access_rights,time except Exception: opc.close() return None,'Error',None,None La función write, funciona de manera similar a la función read. Tiene como parámetros de entrada el servidor, nombre de la variable, valor de escritura y un vector. Una vez conectado al servidor indicado se realiza la escritura de variable. Finalmente añade al vector si la operación de escritura ha sido exitosa o no, y se devuelve ese vector a la función que hubiera llamado a la función write. def write(server,name,value,response_array): try: opc = OpenOPC.open_client('localhost') opc.connect(server) #Si la operación de lectura ha sido un exito if value: a=opc.write((name,value)) else: a=''#No se hace nada si el usuario no escribe nada response_array.append(a.lower()) return response_array except Exception: response_array.append('error') return (response_array) 6.1.3 Fichero tasks.py En este fichero se encuentran las tareas programables del sistema. Estas son las tareas que se pueden automatizar y ejecutar de manera periódica. La tarea store_value permite almacenar lecturas de las variables de los PLCs en la base de datos del sistema. Como parámetros de entrada tiene la variable a guardar y el servidor donde está alojada. Las operaciones son una lectura de la variable, calidad, derechos de acceso y fecha de lectura mediante una llamada a la función read del fichero automataconnect.py. Los datos de lectura son alojados en una variable que funciona modelo TimeSeries y finalmente se guarda el valor en la base de datos. Ricardo Garzo Castro 52 @task() def store_value(server,name): value,quality,access_rights,time=connect.read(server,name) t = TimeSeries(server=server, name=name, value=value, time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) t.save() return La tarea alarm tiene como función avisar al usuario mediante un email de que una variable ha salido del rango que él ha fijado. Como parámetros de entrada están el servidor, nombre de la variable, el tipo de condición para activar la alarma, el valor límite y el email al que mandar el aviso. Se realiza una lectura de la variable indicada y se evalúa el valor actual con el valor límite según la condición de activación de alarma dada. Si la alarma fuera activada se enviaré un email con los datos de la variable, el servidor y se indicaría que la evaluación del valor actual ha desencadenado la alarma. Las condiciones de activación de alarma son: mayor que, menor que, igual y no igual. Ricardo Garzo Castro 53 @task() def alarm(server,name,condition,value_limit,email): value,quality,access_rights,time=connect.read(server,name) #Lectura del valor del ciente opc if condition=='greater': value_limit=float(value_limit) #La variable se convierte de string a float value=float(value) #La variable se convierte de string a float if value > value_limit: send_mail('Online Scada Alarm', 'The variable ' + str(name) + ' on server ' + str(server) + ' is greater than its value limit '+ str(value_limit) + '. The actual value is '+str(value)+'.','[email protected]',[str(email)], fail_silently=False) if condition=='less': value_limit=float(value_limit) value=float(value) if value < value_limit: send_mail('Online Scada Alarm', 'The variable ' + str(name) + ' on server ' + str(server) + ' is lesser than its value limit '+ str(value_limit)+ '. The actual value is '+str(value)+'.','onlinescadap[email protected]m',['[email protected]'], fail_silently=False) if condition=='equal': value_limit=float(value_limit) value=float(value) if value == value_limit: send_mail('Online Scada Alarm', 'The variable ' + str(name) + ' on server ' + str(server) + ' is equal to its limit '+ str(value_limit), '[email protected]',['[email protected]'], fail_silently=False) if condition=='not equal': value_limit=float(value_limit) value=float(value) if value != value_limit: send_mail('Online Scada Alarm', 'The variable ' + str(name) + ' on server ' + str(server) + ' is not equal to '+ str(value_limit)+ '. The actual value is '+str(value)+'.','onlinescadap[email protected]m',['[email protected]'], fail_silently=False) return 6.1.4 Fichero views.py Este fichero contiene las funciones que han de ejecutarse cuando el usuario accede a la url asociada. Ricardo Garzo Castro 54 Existe un conjunto de funciones cuya única misión es facilitar el documento HTML al cliente. Como parámetro de entrada tienen el contenido de la petición HTTP que ha mandado el cliente al servidor, las funciones home y manual devuelven los ficheros home.html y manual.html respectivamente cuando son llamadas. @login_required def home(request): return render_to_response('home.html',context_instance=RequestContext(request)) @login_required def manual(request): return render_to_response('manual.html',context_instance=RequestContext(request)) Otro conjunto de funciones realiza una operación similar pero además añaden un diccionario con información relativa a las variables de los PLCs que se están controlando. De los datos que contiene ese diccionario se rellenarán las distintas tablas o gráficas de las páginas webs. Ricardo Garzo Castro 55 @login_required def read(request): variable_list=get_variables(request.user) return render_to_response('read.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) @login_required def control(request): variable_list=get_writable_variables(request.user) return render_to_response('control.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) @login_required def display_editor(request): variable_list=get_variables(request.user) return render_to_response('display_editor.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) @login_required def graph_live(request): variable_list=get_variables(request.user) return render_to_response('graph_live.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) @login_required def graph_db(request): variable_list=get_variables(request.user) return render_to_response('graph_db.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) @login_required def log_db(request): variable_list=get_variables(request.user) return render_to_response('log_db.html', {'variable_list': variable_list} , context_instance=RequestContext(request)) Para conseguir el diccionario con los valores actuales de las variables se utiliza en todas las funciones enunciadas hasta ahora la función get_variables. Esta función tiene como parámetro de entrada el usuario que ha mandado la petición HTTP a la aplicación web, y crea una lista de todas las variables que ha guardado ese usuario llamando a la función variable_list_django_db, que está explicada más adelante. Una vez creada la lista de variable, se crea otra con los valores de las operaciones de lectura, que es la que finalmente se devuelve como parámetro de salida. Ricardo Garzo Castro 56 def get_variables(user): variable_list=variable_list_django_db(user) i=0 while i<len(variable_list): variable_list[i].value,variable_list[i].quality,variable_list[i].access_rights,t ime=connect.read(variable_list[i].server,variable_list[i].name) i=i+1 return variable_list En la función variable_list_django_db, que tiene como parámetro de entrada el usuario que ha realizado la petición HTTP se realiza una consulta a la base de datos para extraer todas las variables almacenadas por ese usuario. Las variables son filtradas de tal manera que si el usuario hubiera introducido la misma variable más de una vez por error el sistema lo detecta y no muestra la variable por duplicado en el SCADA. def variable_list_django_db(user): server_list=[] raw_variable_list=Variable.objects.filter(user=user) variable_list = [] for e in raw_variable_list: i=0 encontrado=False while i<len(variable_list): if variable_list[i].server==e.server and variable_list[i].name==e.name: encontrado=True break else: encontrado=False i=i+1 if not encontrado: variable_list.append(e) return variable_list La función control_response se utiliza para generar los datos de vuelta cuando el usuario decide enviar una petición HTTP parar escribir sobre las variables de los PLCs. Como parámetro de entrada tiene el cuerpo de la petición HTTP, en este cuerpo se encuentran los datos de las variables a modificar y los valores de escritura. La función verifica si el usuario ha mandado los datos de forma correcta y escribe llamando a la función write del fichero automataconnect.py en los PLCs. Finalmente, se envía un vector codificado en formato json donde se indica si las operaciones de escritura se han realizado con éxito. Ricardo Garzo Castro 57 @permission_required('variables.change_Variable',raise_exception=True) def control_response (request): #Verifica si los datos de la petición HTTP son correctos. if request.method == 'POST': json_data = simplejson.loads(request.body) try: data = json_data['data'][0] except KeyError: return HttpResponseServerError("Malformed data!") #Crea vector con datos de respuesta response_array=[] i=0 while i<len(json_data['data']): server,name,value=json_data['data'][i]['server'],json_data['data'][i]['name'] ,json_data['data'][i]['value'] response_array=connect.write(server,name,value,response_array) i=i+1 return HttpResponse(json.dumps(response_array), mimetype='application/json') La función read_update devuelve, ante una petición HTTP del usuario, los datos actualizados de lectura de los PLCs. Como parámetro de entrada está el cuerpo de la petición HTTP conteniendo los datos de las variables a leer. Cuando la función ha realizado las operaciones de lectura de todas las variables se crea un diccionario que se codifica en formato json para enviarlo al usuario. @login_required def read_update(request): json_data={"variables":[]} variable_list=get_variables(request.user) for e in variable_list: dict={} dict['server']=e.server dict['name']=e.name dict['value'],dict['quality'],dict['access_rights'],time=connect.read(e.serve r,e.name) json_data['variables'].append(dict) return HttpResponse(json.dumps(json_data), mimetype='application/json') La función json_query_db es una función que realiza una consulta a la base datos para extraer los valores históricos de una variable determinada durante un intervalo de tiempo concretado por el usuario para finalmente devolver un diccionario python con los valores requeridos. El parámetro de entrada es una petición HTTP, en cuyo cuerpo se encuentran los datos de la consulta: variable y su servidor, fecha de inicio de búsqueda y fecha de fin de búsqueda. Cuando la función ha realizado una consulta, donde se extraen todos los valores históricos de todas las variables almacenadas, se filtran los resultados en función de los parámetros que ha indicado el usuario. Y finalmente se transforma la variable, que se encuentra en un formato propio de la base de datos a un diccionario python. Ricardo Garzo Castro 64 function graph_plot(){ $('#date').empty(); $('#date').append(spinner.el); //Se recogen los datos que ha seleccionado el usuario response = {"data" : []} $("select").each(function(index, domele) { var obj={}; obj['server'] = $(this).find('option:selected').attr('id'); obj['name'] = $(this).find('option:selected').attr('class'); response.data.push(obj); }); //Se codifican en formato json los datos del usuario json_response = JSON.stringify(response); //Se verifica si la variable a mostrar ha cambiado. if (previous_server != "None"){ if (!(previous_server == obj['server'] && previous_variable == obj['name'])){ new_data=true; } } previous_variable = obj['name']; previous_server = obj['server']; //Llamada al servidor con envío de datos mediante $.post $.post("/json/graph_live/", json_response).success(function(dta) { //Codigo para añadir el nuevo data al vector de la gráfica y dibujarla var value = parseInt(dta.value,10); if (new_data){ line1=[[dta.time,value]]; Ricardo Garzo Castro 65 var displayDate = hours + ':' + minutes + ':' + seconds + ' ' + (myDate.getDate()) + '/' + ( '0' + (myDate.getMonth()+1) ).slice( -2 ) + '/' + myDate.getFullYear(); $('#date').empty(); $('#date').append('<p>Last Update: <strong>' + displayDate + '</strong></p>'); }); }; Ricardo Garzo Castro 66 7. Manual de Usuario 7.1 Introducción En este documento se explica cómo se ha de realizar la instalación del software para el SCADA Online y además contiene un manual de instrucciones de uso. El sistema se puede instalar en plataformas Windows, Mac y Linux; pero este manual está orientado a la instalación en una plataforma Windows. 7.2 Instrucciones de uso En la página web, que está alojada en la IP http://155.210.159.208:80/home, se encuentra un manual básico del funcionamiento de la aplicación web. Por lo tanto, este documento se centra en un manual para un uso más avanzado. 7.2.1 Acceso al menú de administrador La aplicación web creada por el framework de Django pone a disposición un menú en el navegador web del usuario final donde se pueden editar los modelos además de un conjunto de cosas relacionadas con la aplicación, que en este caso son las tareas periódicas. Para acceder a este menú, a la derecha de la barra de navegación de la página web se encuentra un menú desplegable donde el usuario pulsando el botón Settings puede acceder al menú de administrador, como se ve en la Figura 1. Figura 45 Menú desplegable del usuario. 7.2.3 Adición de variables y tareas periódicas La inclusión de variables y tareas periódicas nuevas se trata en los apartados 3.5.2 y 3.5.4, respectivamente, de la Memoria de este proyecto, entonces este apartado solo se centrará en cómo acceder al menú descrito en los apartados explicativos de la memoria, que están dentro del menú de administrador, en los apartados Variables->Variables y Djcelery->Periodic Tasks, respectivamente y como se puede apreciar en la Figura 2 y Figura 3. Figura 46 Menú de administrador para Variables. Ricardo Garzo Castro 67 Figura 47 Menú de administrador para Tareas periódicas. 7.2.3 Creación de usuarios del sistema Al igual que para las variables y las tareas periódicas, existe un menú para el control de usuario del sistema. A través de este menú, el usuario que actúa como superusuario puede añadir usuarios nuevos y dotarles de los credenciales para acceder a las distintas tareas del SCADA. De esta manera se puede configurar que es lo qué haría un usuario en el sistema: se puede configurar que pueda entrar al SCADA pero solo para realizar tareas de lectura, otro que pueda realizar operaciones de control en los PLCs pero no añadir usuarios nuevos o también un usuario que pueda tener la funcionalidad completa del SCADA su disposición. Para gestionar los usuarios se acceder a Auth->Users dentro del menú de administrador. Como se ve en la Figura Figura 48 Menú de gestión de usuario del sistema SCADA. Durante el proceso de creación de un nuevo usuario se pasa por formularios para indicar el nuevo nombre y contraseña, como indica la Figura 5 Ricardo Garzo Castro 68 Figura 49 Formulario de creación de un nuevo usuario. En el siguiente apartado del formulario se indica el nivel de acceso que tendrá el usuario al sistema. En el ejemplo de la Figura 6 se puede observar un usuario con un conjunto de permisos que se pueden configurar para determinar el nivel de acceso deseado para el usuario a crear.  Can add user: para añadir usuarios nuevos al sistema.  Can add periodic task: podrá añadir nuevas tareas periódicas.  Can add variable: nuevas variables se pueden controlar en el sistema.  Can change variable: permite realizar operaciones de escritura en las variables. Figura 50 Formulario para los permisos de usuario. 7.3 Instrucciones de instalación En este apartado se enunciará los paquetes de software a instalar y se explicará cómo se han de incorporar los archivos del autor además de la configuración de los programas pertinentes. Si se está en una plataforma Windows, los paquetes están incluidos en el CD del proyecto. Ricardo Garzo Castro 69 Software a instalar:  Python 2.7: Lenguaje de programación usado en el proyecto. Disponible en la web de Python.  Pip: Herramienta para la instalación y manejo de paquetes Python. Disponible en la web de pip.  Pywin32: Extensiones de Python para Windows. Disponible en la página web de Pywin320  OpenOPC: Cliente OPC usado en el SCADA. Disponible en la página web de OpenOPC for Python.  Apache2.2: Servidor HTTP recomendado para el proyecto. Disponible en la página web de Apache.  RabbitMQ: Para las tareas automatizadas. Disponible en la web de RabbitMQ. Adicionalmente a estos paquetes de software, que son archivos ejecutables en la plataforma Windows, se instalarán paquetes python a través de la consola de comandos. Esto se detallará a continuación. 7.4.1 Paquetes Python Como se ha explicado, python es el lenguaje de programación predominante en la aplicación. Aquí se detallan los paquetes adicionales a instalar. Estos paquetes pueden ser instalados en cualquier plataforma, pero aquí se usará Windows como ejemplo. Para manejar Python en Windows desde la consola de comandos han de configurarse las variables del entorno donde se añadirán a la variable “Path” la siguiente directiva:  “;C:\Python27;” Con esto se consigue accede a la consola de Python desde la consola de commandos. A través de Pip instalaremos los siguientes paquetes de Python con las siguientes directivas:  “pip install django” Django es el framework de la aplicación web.  “pip install django-celery” Celery es un ejecutor de tareas.  “pip install pyro” Librería Django para objetos. Figura 51 Ejemplo del uso de pip en la consola de comandos Windows. Ricardo Garzo Castro 70 7.4.2 Archivo de configuración Apache A la hora de configurar el servidor Apache, hay que tener en cuenta:  Módulo “mod_wsgi”  Configuración de “http.conf” El primer módulo hay que incluirlo en el directorio de módulos de Apache, y sirve para comunicar al servidor con la aplicación Python del SCADA. El módulo se puede bajar de la web de mod_wsgi para la plataforma necesaria. Para el archivo de configuración http.conf, se puede sustituir el que viene por defecto y usar el que se suministra en el CD de instalación. A continuación se indican los cambios que habría que hacer en el archivo http.conf de no quererse sustituir completamente:  “ServerRoot “C:/Apache2.2””. O donde esté instalado Apache.  “LoadModule wsgi_module modules/mod_wsgi.so”. Para indicar que cargamos el módulo wsgi y el directorio donde está alojado.  “DocumentRoot “C:/Apache2.2/htdocs”.”  Las siguientes directivas que se recogen en la imagen corresponden a la configuración para el interfaz wsgi. Sirven para definir, donde se encuentra el archivo para comunicar la aplicación web con el servidor Apache y los directorios en los que Apache puede acceder para suministrar archivos al usuario como son los documentos estáticos por ejemplo. Figura 52 Directivas aplicables al interfaz wsgi en Apache.