{"id":384,"date":"2023-03-29T19:24:00","date_gmt":"2023-03-29T18:24:00","guid":{"rendered":"https:\/\/jorgeturiel.es\/?p=384"},"modified":"2023-03-31T21:36:27","modified_gmt":"2023-03-31T20:36:27","slug":"webservice-en-robots-industriales-abb","status":"publish","type":"post","link":"https:\/\/jorgeturiel.es\/?p=384","title":{"rendered":"WebService en robots industriales ABB"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Conectando Free Pascal con un Robot ABB<\/h2>\n\n\n\n<p>Un <strong>servicio web<\/strong> (en ingl\u00e9s, <em>web service<\/em> o <em>web services<\/em>) es una tecnolog\u00eda que utiliza un conjunto de protocolos y est\u00e1ndares que sirven para intercambiar datos entre aplicaciones. Distintas aplicaciones de software desarrolladas en lenguajes de programaci\u00f3n diferentes, y ejecutadas sobre cualquier plataforma, pueden utilizar los servicios web para intercambiar datos (<a rel=\"noreferrer noopener\" href=\"https:\/\/es.wikipedia.org\/wiki\/Servicio_web\" target=\"_blank\">fuente <\/a><a href=\"https:\/\/es.wikipedia.org\/wiki\/Servicio_web\" target=\"_blank\" rel=\"noreferrer noopener\">W<\/a><a rel=\"noreferrer noopener\" href=\"https:\/\/es.wikipedia.org\/wiki\/Servicio_web\" target=\"_blank\">ikipedia<\/a>).<\/p>\n\n\n\n<p>Los robots ABB de la generaci\u00f3n <a rel=\"noreferrer noopener\" href=\"https:\/\/new.abb.com\/products\/robotics\/es\/controladores\/omnicore\" target=\"_blank\">Omnicore<\/a>, disponen  de un servicio web llamado<a rel=\"noreferrer noopener\" href=\"https:\/\/developercenter.robotstudio.com\/api\/RWS\" target=\"_blank\"> <em>Robot Web Services<\/em><\/a>, el cual usa un servicio <em>REST<\/em>. Vamos a ver como hacer uso de este servicio con Free Pascal y Lazarus.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Para acceder a este servicio necesitas tener un robot ABB conectado en red. O bien podemos acceder a un controlador virtual, si usamos el programa <a rel=\"noreferrer noopener\" href=\"https:\/\/new.abb.com\/products\/robotics\/es\/robotstudio\" target=\"_blank\">RobotStudio <\/a>de ABB. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Consideraciones iniciales<\/h2>\n\n\n\n<p>Para conectarse al robot, debemos usar una conexi\u00f3n Http segura. Adem\u00e1s debemos enviar el usuario y clave como una autorizaci\u00f3n b\u00e1sica. Adem\u00e1s el tipo de contenido, tanto el que enviamos como el que aceptamos debe ser del tipo: <em>application\/xhtml+xml;v=2.0<\/em><\/p>\n\n\n\n<p>Teniendo todo lo anterior en cuenta, vamos a programar una peque\u00f1a aplicaci\u00f3n que solicite la informaci\u00f3n al robot y nos la muestre por pantalla.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Programando<\/h2>\n\n\n\n<p>Crea un nuevo proyecto en Lazarus, que se a de tipo programa<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"338\" height=\"416\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusCrearProyecto.jpg\" alt=\"\" class=\"wp-image-386\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusCrearProyecto.jpg 338w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusCrearProyecto-244x300.jpg 244w\" sizes=\"auto, (max-width: 338px) 100vw, 338px\" \/><figcaption class=\"wp-element-caption\">Nuevo proyecto<\/figcaption><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"563\" height=\"334\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusEscogerProyecto.jpg\" alt=\"\" class=\"wp-image-388\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusEscogerProyecto.jpg 563w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/LazarusEscogerProyecto-300x178.jpg 300w\" sizes=\"auto, (max-width: 563px) 100vw, 563px\" \/><figcaption class=\"wp-element-caption\">Seleccionar tipo de proyecto<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Para enviar una petici\u00f3n http necesitamos usar la unidad <em>fphttpclient<\/em>. Y para que sea  segura a\u00f1adiremos <em>opensslsockets<\/em>. Adem\u00e1s la autentificaci\u00f3n es tipo b\u00e1sico. Lo que significa que el usuario y la clave van codificados en Base64. Y para terminar necesitamos la unida <em>sysutils<\/em>, para gestionar las excepciones y preparar una cadena con el usuario y la clave. As\u00ed que la clausula <em>Uses<\/em> del programa ser\u00e1 algo as\u00ed:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi mark:6,7,8,9 decode:true \" >uses\n {$IFDEF UNIX}\n  cthreads,\n  {$ENDIF}\n  Classes { you can add units after this },\n  SysUtils,\n  opensslsockets,\n  fphttpclient,\n  base64;    <\/pre><\/div>\n\n\n\n<p>Creamos una objeto <em>Http<\/em>, y un objeto <em>TStringList<\/em>. EL primero ser\u00e1 el que usemos para lanzar la petici\u00f3n, y el segundo para contendr\u00e1 la respuesta que nos devuelva el robot.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">PeticionHttp := TFPHTTPClient.Create(nil);\nRespuesta := TStringList.Create;     <\/pre><\/div>\n\n\n\n<p>Ahora preparamos el usuario y la clave para enviar junto a la petici\u00f3n<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">usuario := 'Default User';\npassword := 'robotics';\nclave := Format('%s:%s', [usuario, password]);\nclave := EncodeStringBase64(clave);<\/pre><\/div>\n\n\n\n<p>Como el sistema de autentificaci\u00f3n en del tipo b\u00e1sico, el formato es una cadena d\u00f3nde se env\u00eda el usuario y la clave separados por dos puntos, y toda ella codificada en Base64.<\/p>\n\n\n\n<p>Tanto, la autentificaci\u00f3n, como la informaci\u00f3n sobre el tipo del contenido que enviamos como el que aceptamos se debe enviar en las cabeceras de la petici\u00f3n. Las cuales preparamos y luego realizamos la petici\u00f3n. Pas\u00e1ndole la direcci\u00f3n Ip, al objeto <em>PeticionHttp<\/em>, adem\u00e1s de un objeto <em>TStringList<\/em> para contendr\u00e1 la respuesta del robot.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">AddHeader('Authorization', 'Basic ' + clave);\nAddHeader('Content-Type', 'application\/xhtml+xml;v=2.0');\nAddHeader('Accept', 'application\/xhtml+xml;v=2.0');\n\/\/Direcci\u00f3n IP del robot. Localhost, puerto 80 si el controlador es virtual\nget('https:\/\/localhost:80\/', Respuesta); <\/pre><\/div>\n\n\n\n<p>Ahora solo queda procesar la respuesta. EL objeto <em>PeticionHttp<\/em> contiene el resultado de la petici\u00f3n. Nos devuelve un c\u00f3digo http, adem\u00e1s de unas cabeceras con informaci\u00f3n. Y el objeto <em>Respuesta<\/em>, nos devuelve el documento XML, con la respuesta del robot.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">WriteLn('Status:');\nWriteln(ResponseStatusText);\nWriteLn(ResponseStatusText + ' ' + IntToStr(ResponseStatusCode));\nWriteLn('');\nWriteLn('ResponseHeaders:');\nWriteln(ResponseHeaders.Text);\nWriteln('');\nWriteLn('Respuesta:');\nWriteln(Respuesta.Text);           <\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>La respuesta, si todo ha ido bien, la respuesta es un archivo XML, y su contenido puede ser algo as\u00ed.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"577\" src=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/RespuestaRobotAbb-1024x577.jpg\" alt=\"\" class=\"wp-image-391\" srcset=\"https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/RespuestaRobotAbb-1024x577.jpg 1024w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/RespuestaRobotAbb-300x169.jpg 300w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/RespuestaRobotAbb-768x433.jpg 768w, https:\/\/jorgeturiel.es\/wp-content\/uploads\/2023\/03\/RespuestaRobotAbb.jpg 1115w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Respuesta del robot<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Os dejo el c\u00f3digo completo del ejemplo.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:delphi decode:true \">program project1;\n\n{$mode objfpc}{$H+}\n\nuses\n {$IFDEF UNIX}\n  cthreads,\n    {$ENDIF}\n  Classes { you can add units after this },\n  SysUtils,\n  opensslsockets,\n  fphttpclient,\n  base64;\n\nvar\n  PeticionHttp: TFPHTTPClient;\n  Respuesta: TStringList;\n  clave, password, usuario: string;\nbegin\n\n  PeticionHttp := TFPHTTPClient.Create(nil);\n  Respuesta := TStringList.Create;\n  try\n    try\n      usuario := 'Default User';\n      password := 'robotics';\n      clave := Format('%s:%s', [usuario, password]);\n      clave := EncodeStringBase64(clave);\n      with PeticionHttp do\n      begin\n        AddHeader('Authorization', 'Basic ' + clave);\n        AddHeader('Content-Type', 'application\/xhtml+xml;v=2.0');\n        AddHeader('Accept', 'application\/xhtml+xml;v=2.0');\n        \/\/Direcci\u00f3n IP del robot. Localhost, puerto 80 si el controlador es virtual\n        get('https:\/\/localhost:80\/', Respuesta);\n        WriteLn('Status:');\n        Writeln(ResponseStatusText);\n        WriteLn(ResponseStatusText + ' ' + IntToStr(ResponseStatusCode));\n        WriteLn('');\n        WriteLn('ResponseHeaders:');\n        Writeln(ResponseHeaders.Text);\n        Writeln('');\n        WriteLn('Respuesta:');\n        Writeln(Respuesta.Text);\n      end;\n    except\n      on E: Exception do\n      begin\n        writeln('Error: ' + E.Message);\n      end;\n    end;\n  finally\n    PeticionHttp.Free;\n    Respuesta.Free;\n    WriteLn('Pulsa una tecla para continuar');\n    ReadLn()\n  end;\nend.     <\/pre><\/div>\n\n\n\n<p>Saludos<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Conectando Free Pascal con un Robot ABB Un servicio web (en ingl\u00e9s, web service o web services) es una tecnolog\u00eda que utiliza un conjunto de protocolos y est\u00e1ndares que sirven para intercambiar datos entre aplicaciones. Distintas aplicaciones de software desarrolladas en lenguajes de programaci\u00f3n diferentes, y ejecutadas sobre cualquier plataforma, pueden utilizar los servicios web [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":392,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,27,25,26,35],"tags":[30,32,23,33,31],"class_list":["post-384","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-abb","category-lazarus","category-pascal","category-programacion","category-robots","tag-abb","tag-free-pascal","tag-lazarus","tag-restapi","tag-robots"],"_links":{"self":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/384","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=384"}],"version-history":[{"count":7,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/384\/revisions"}],"predecessor-version":[{"id":397,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/posts\/384\/revisions\/397"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=\/wp\/v2\/media\/392"}],"wp:attachment":[{"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=384"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=384"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jorgeturiel.es\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=384"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}