{"id":8125,"date":"2019-09-11T14:43:22","date_gmt":"2019-09-11T17:43:22","guid":{"rendered":"http:\/\/kb.elipse.com.br\/?p=8125"},"modified":"2024-03-26T11:22:50","modified_gmt":"2024-03-26T14:22:50","slug":"criando-algoritmos-em-python-para-o-epm-processor","status":"publish","type":"post","link":"https:\/\/kb.elipse.com.br\/en\/criando-algoritmos-em-python-para-o-epm-processor\/","title":{"rendered":"Criando Algoritmos em Python para o EPM Processor."},"content":{"rendered":"<h2>Introdu\u00e7\u00e3o<\/h2>\n<p>O <strong>EPM Processor<\/strong> \u00e9 o m\u00f3dulo do <strong>Elipse Plant Manager<\/strong> respons\u00e1vel pela execu\u00e7\u00e3o de c\u00f3digos em linguagem <strong>Python <\/strong>baseados em eventos simulados ou de tempo real.<\/p>\n<p>Quando se deseja implementar um algoritmo para ser utilizado no <strong>EPM Processor<\/strong>, seja em produ\u00e7\u00e3o ou simula\u00e7\u00e3o, este algoritmo deve ser codificado dentro de uma fun\u00e7\u00e3o em linguagem <strong>Python<\/strong> que, neste caso, \u00e9 designada por <strong>Application Method<\/strong>, ou simplesmente de <strong>Method<\/strong> (<em>m\u00e9todo<\/em>, em portugu\u00eas).<\/p>\n<blockquote>\n<ul>\n<li>O termo <em>m\u00e9todo<\/em> adv\u00e9m do paradigma de programa\u00e7\u00e3o orientada a objetos, onde se refere \u00e0 uma fun\u00e7\u00e3o definida em uma classe espec\u00edfica.<\/li>\n<\/ul>\n<\/blockquote>\n<p>Para que uma fun\u00e7\u00e3o seja apresentada como um m\u00e9todo do <strong>EPM Processor<\/strong> nas configura\u00e7\u00f5es das <strong>Applications<\/strong>, \u00e9 necess\u00e1rio que esta fun\u00e7\u00e3o seja identificada como tal. Isto \u00e9 realizado atrav\u00e9s do uso de um <em>decorator<\/em>, a ser visto mais adiante.<\/p>\n<blockquote>\n<ul>\n<li><em>Decorator<\/em> \u00e9 um termo que designa um padr\u00e3o de projeto de software que permite agregar dinamicamente funcionalidades adicionais a um dado objeto.<\/li>\n<\/ul>\n<\/blockquote>\n<p>A imagem a seguir mostra o fluxo de cria\u00e7\u00e3o e utiliza\u00e7\u00e3o de um m\u00e9todo para aplica\u00e7\u00f5es no <strong>EPM Processor<\/strong>.<\/p>\n<p><a href=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\/blob\/master\/guiadousuario\/images\/algoritmos_fluxo.PNG\" target=\"_blank\" rel=\"noopener noreferrer\"><img title=\"Fluxo de cria\u00e7\u00e3o e utiliza\u00e7\u00e3o de m\u00e9todos no EPM Processor\" src=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\/raw\/master\/guiadousuario\/images\/algoritmos_fluxo.PNG\" alt=\"fluxo algoritmo\" \/><\/a><\/p>\n<p>Existem duas bibliotecas que sempre devem ser importadas no c\u00f3digo, uma do pr\u00f3prio <strong>EPM Processor<\/strong> e outra para acessar informa\u00e7\u00f5es e dados de um <strong>EPM Server<\/strong>, conforme o c\u00f3digo a seguir.<\/p>\n<p><code>import epmprocessor as epr<\/code><\/p>\n<p><code>import epmwebapi as epm<\/code><\/p>\n<p>Estas bibliotecas proveem todas as funcionalidades utilizadas nos exemplos a seguir.<\/p>\n<p>&nbsp;<\/p>\n<h2>O Decorator epr.applicationMethod<\/h2>\n<p>Este <em>decorator<\/em> deve ser utilizado em todas as fun\u00e7\u00f5es em linguaguem <strong>Python<\/strong> expostas como m\u00e9todos para utiliza\u00e7\u00e3o nas <strong>Applications<\/strong>, como no exemplo a seguir.<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmprocessor <span class=\"pl-k\">as<\/span> epr\n<span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>MyMethod<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">my_method<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">param1<\/span>, <span class=\"pl-smi\">param2<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Documentation<span class=\"pl-pds\">'''<\/span><\/span>\n\n    <span class=\"pl-c1\">...<\/span><\/pre>\n<\/div>\n<p>No exemplo anterior foi utilizado o par\u00e2metro <code>session<\/code>. Este par\u00e2metro deve sempre receber o tipo <strong>session<\/strong> na entrada de dados do m\u00e9todo. Atrav\u00e9s deste par\u00e2metro s\u00e3o acess\u00edveis informa\u00e7\u00f5es relativas ao evento, contexto de execu\u00e7\u00e3o e informa\u00e7\u00f5es sobre a \u00faltima execu\u00e7\u00e3o, entre outras.<\/p>\n<p>O exemplo a seguir mostra o uso das propriedades <code>timeEvent<\/code> e <code>range<\/code> do par\u00e2metro <code>session<\/code> para trabalhar com o per\u00edodo de uma consulta relativo ao momento em que o m\u00e9todo \u00e9 executado.<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmprocessor <span class=\"pl-k\">as<\/span> epr\n<span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n<span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>MyMethod<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">my_method<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">param1<\/span>, <span class=\"pl-smi\">param2<\/span>):\n\n    endtime <span class=\"pl-k\">=<\/span> session.timeEvent\n    initime <span class=\"pl-k\">=<\/span> endtime <span class=\"pl-k\">-<\/span> datetime.timedelta(session.range)\n\n    queryPeriod <span class=\"pl-k\">=<\/span> epm.QueryPeriod(initime,endtime)\n\n    <span class=\"pl-k\">pass<\/span><\/pre>\n<\/div>\n<p>A tabela a seguir cont\u00e9m a descri\u00e7\u00e3o das propriedades do par\u00e2metro <code>session<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<table>\n<thead>\n<tr>\n<th>Propriedade<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>timeEvent<\/td>\n<td>Data e hora do evento que gerou a execu\u00e7\u00e3o do m\u00e9todo. Pode ser informado manualmente em caso de teste, em tempo real no caso de uma <strong>Production<\/strong> ou simulado no caso de uma <strong>Simulation<\/strong><\/td>\n<\/tr>\n<tr>\n<td>range<\/td>\n<td>Intervalo de tempo. Usualmente utilizado em conjunto com o par\u00e2metro <code>timeEvent<\/code> para determinar as datas de in\u00edcio e t\u00e9rmino das consultas aos dados de processo<\/td>\n<\/tr>\n<tr>\n<td>processInterval<\/td>\n<td>Intervalo de tempo de processamento usado em consultas com agrega\u00e7\u00e3o<\/td>\n<\/tr>\n<tr>\n<td>parametersMap<\/td>\n<td>Lista de par\u00e2metros globais de uma <strong>Application<\/strong>, criados atrav\u00e9s da op\u00e7\u00e3o <strong>New Session Parameter<\/strong><\/td>\n<\/tr>\n<tr>\n<td>userCache<\/td>\n<td>Mem\u00f3ria de execu\u00e7\u00e3o que pode ser usada para transferir informa\u00e7\u00f5es entre uma execu\u00e7\u00e3o e outra<\/td>\n<\/tr>\n<tr>\n<td>lastExecutedInfo<\/td>\n<td>Informa\u00e7\u00f5es sobre a \u00faltima execu\u00e7\u00e3o<\/td>\n<\/tr>\n<tr>\n<td>connections<\/td>\n<td>Vari\u00e1vel que cont\u00e9m todas as <strong>Connections<\/strong> utilizadas pelos par\u00e2metros de um m\u00e9todo que exigem conex\u00f5es com um <strong>EPM Server<\/strong><\/td>\n<\/tr>\n<tr>\n<td>scopeContext<\/td>\n<td>Cont\u00e9m informa\u00e7\u00f5es sobre o contexto de execu\u00e7\u00e3o, ou seja, se a avalia\u00e7\u00e3o do m\u00e9todo est\u00e1 sendo realizada a partir de um teste, de uma execu\u00e7\u00e3o em produ\u00e7\u00e3o ou de uma simula\u00e7\u00e3o.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<blockquote>\n<ul>\n<li>Ao construir m\u00e9todos, deve-se considerar que o n\u00famero de par\u00e2metros \u00e9 fixo e configurado atrav\u00e9s do <strong>Workbench<\/strong>. Portanto, os m\u00e9todos que utilizam o <em>decorator<\/em> <code>epr.applicationMethod<\/code> n\u00e3o devem utilizar <code>args<\/code> ou <code>kwargs<\/code> na cria\u00e7\u00e3o.<\/li>\n<\/ul>\n<\/blockquote>\n<blockquote>\n<ul>\n<li>\u00c9 poss\u00edvel criar par\u00e2metros adicionais para o par\u00e2metro <code>session<\/code> atrav\u00e9s da op\u00e7\u00e3o <strong>New Session Parameter<\/strong>. Esta op\u00e7\u00e3o est\u00e1 dispon\u00edvel na \u00e1rea <strong>Test<\/strong> do <strong>Code Package<\/strong>. Para efetivamente usar em <strong>Solutions<\/strong>, estes par\u00e2metros adicionais devem ser configurados nas respectivas <strong>Applications<\/strong>.<\/li>\n<\/ul>\n<\/blockquote>\n<h2><\/h2>\n<h2>Par\u00e2metros de um M\u00e9todo<\/h2>\n<p>A tabela a seguir cont\u00e9m os tipos de dados dispon\u00edveis para serem usados na entrada de par\u00e2metros de m\u00e9todos.<\/p>\n<table>\n<thead>\n<tr>\n<th>Tipo de Dados<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>int<\/strong><\/td>\n<td>Tipo de dados inteiro da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>intArray<\/strong><\/td>\n<td>Sequ\u00eancia de inteiros, como por exemplo <code>[1, 3, 5, 6]<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>float<\/strong><\/td>\n<td>Tipo de dados de ponto flutuante da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>floatArray<\/strong><\/td>\n<td>Sequ\u00eancia de pontos flutuantes, como por exemplo <code>[1.0, 3.5, 5.0, 6.1]<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>string<\/strong><\/td>\n<td>Tipo de dados de cadeia de caracteres da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>stringArray<\/strong><\/td>\n<td>Sequ\u00eancia de cadeia de caracteres, como por exemplo <code>['abc','def','123']<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>bool<\/strong><\/td>\n<td>Tipo de dados booleano da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>boolArray<\/strong><\/td>\n<td>Sequ\u00eancia de booleanos, como por exemplo <code>[true, false, false]<\/code><\/td>\n<\/tr>\n<tr>\n<td><strong>dictionary<\/strong><\/td>\n<td>Tipo de dados dicionario ordenado da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>datetime<\/strong><\/td>\n<td>Tipo de dados de data e hora da linguagem <strong>Python<\/strong>. O <strong>Workbench<\/strong> ajuda a preencher este campo com a ferramenta de calend\u00e1rio<\/td>\n<\/tr>\n<tr>\n<td><strong>datetimeArray<\/strong><\/td>\n<td>Vetor de tipos de dados <strong>datetime<\/strong>. O <strong>Workbench<\/strong> ajuda a preencher este campo com a ferramenta de calend\u00e1rio<\/td>\n<\/tr>\n<tr>\n<td><strong>session<\/strong><\/td>\n<td>Tipo de dados exclusivo do <strong>EPM Processor<\/strong>. Recebe as propriedades <strong>datetime<\/strong>, <strong>range<\/strong> e <strong>process<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>epmconnection<\/strong><\/td>\n<td>Tipo de dados exclusivo do <strong>EPM Processor<\/strong>. Recebe uma das conex\u00f5es configuradas em <strong>EPM Connections<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>dataobject<\/strong><\/td>\n<td>Tipo de dados exclusivo do <strong>EPM Processor<\/strong>. Recebe uma das conex\u00f5es configuradas em <strong>EPM Connections<\/strong> e um nome de <strong>dataobject<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>dataobjectArray<\/strong><\/td>\n<td>Lista de tipos de dados <strong>dataobjects<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>epmobjectDict<\/strong><\/td>\n<td>Tipo de dados exclusivo do <strong>EPM Processor<\/strong>. Recebe um das conex\u00f5es configuradas em <strong>EPM Connections<\/strong>, um filtro baseado no nome do objeto (os filtros n\u00e3o diferenciam mai\u00fasculas e min\u00fasculas) e um tipo de dados e monta um dicion\u00e1rio ordenado da linguagem <strong>Python<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Os t\u00f3picos a seguir apresentam exemplos de uso dos par\u00e2metros de um m\u00e9todo.<\/p>\n<h3><\/h3>\n<h2>Leitura de Dados de Data Objects<\/h2>\n<h4>historyReadRaw()<\/h4>\n<p>Utilize este m\u00e9todo para realizar consultas aos dados brutos (como foram armazenados) de um objeto de dados de um <strong>EPM Server<\/strong>, passando apenas o per\u00edodo de tempo da consulta como argumento. Para trabalhar com per\u00edodos de tempo, utilize a classe <strong>QueryPeriod<\/strong>.<\/p>\n<p>O retorno deste m\u00e9todo corresponde a um <strong>array<\/strong> do m\u00f3dulo <strong>numpy<\/strong> com o cabe\u00e7alho <code>Value<\/code>, <code>Timestamp<\/code> e <code>Quality<\/code>. Exemplo:<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n<span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>GetHistoryRaw<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">get_history_raw<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmdataobject<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Get one hour raw historic data from epm dataobject<span class=\"pl-pds\">'''<\/span><\/span>\n\n     endtime <span class=\"pl-k\">=<\/span> session.timeEvent\n\n     initime <span class=\"pl-k\">=<\/span> endtime <span class=\"pl-k\">-<\/span> datetime.timedelta(session.range)\n\n     queryperiod <span class=\"pl-k\">=<\/span> epm.QueryPeriod(initime, endtime)\n\n    <span class=\"pl-k\">try<\/span>:\n        data <span class=\"pl-k\">=<\/span> epmdataobject.historyReadRaw(queryperiod)\n    <span class=\"pl-k\">except<\/span>:\n        <span class=\"pl-k\">raise<\/span> <span class=\"pl-c1\">Exception<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Error reading raw data.<span class=\"pl-pds\">'<\/span><\/span>)<\/pre>\n<\/div>\n<blockquote>\n<ul>\n<li>Recomenda-se sempre colocar as consultas hist\u00f3ricas dentro de um bloco <code>try\/except<\/code> da linguagem <strong>Python<\/strong>.<\/li>\n<\/ul>\n<\/blockquote>\n<h4><\/h4>\n<h4>historyReadAggregate()<\/h4>\n<p>Este m\u00e9todo realiza consultas agregadas aos dados de processo conforme o padr\u00e3o OPC UA. \u00c9 preciso passar como par\u00e2metro o per\u00edodo da consulta, o tipo de agrega\u00e7\u00e3o e o intervalo da agrega\u00e7\u00e3o. Neste caso utiliza-se, al\u00e9m da classe <strong>QueryPeriod<\/strong>, a classe <strong>AggregateDetails<\/strong>.<\/p>\n<p>O retorno deste m\u00e9todo corresponde a um <strong>array<\/strong> do m\u00f3dulo <strong>numpy<\/strong> com o cabe\u00e7alho <code>Value<\/code>, <code>Timestamp<\/code> e <code>Quality<\/code>. Exemplo:<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n<span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>GetHistoryInterpolative<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">get_history_interpolative<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmdataobject<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Get interpolative data from epm dataobject<span class=\"pl-pds\">'''<\/span><\/span>\n\n    endtime <span class=\"pl-k\">=<\/span> session.timeEvent\n    initime <span class=\"pl-k\">=<\/span> endtime <span class=\"pl-k\">-<\/span> datetime.timedelta(session.range)\n\n    <span class=\"pl-k\">try<\/span>:\n        queryperiod <span class=\"pl-k\">=<\/span> epm.QueryPeriod(initime,endtime)\n        processInterval <span class=\"pl-k\">=<\/span> datetime.timedelta(<span class=\"pl-v\">seconds<\/span><span class=\"pl-k\">=<\/span>session.processInterval)\n        aggregationdetails <span class=\"pl-k\">=<\/span> epm.AggregateDetails(processInterval, epm.AggregateType.Interpolative)\n        data <span class=\"pl-k\">=<\/span> epmdataobject.historyReadAggregate(aggregationdetails,queryperiod)\n    <span class=\"pl-k\">except<\/span>:\n        <span class=\"pl-k\">raise<\/span> <span class=\"pl-c1\">Exception<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Error reading processed data.<span class=\"pl-pds\">'<\/span><\/span>)\n<\/pre>\n<\/div>\n<blockquote>\n<ul>\n<li>Recomenda-se sempre colocar as consultas hist\u00f3ricas dentro de um bloco <code>try\/except<\/code> da linguagem <strong>Python<\/strong>.<\/li>\n<\/ul>\n<\/blockquote>\n<p>&nbsp;<\/p>\n<h4><\/h4>\n<h4>read()<\/h4>\n<p>Este m\u00e9todo realiza a consulta do valor atual da vari\u00e1vel. N\u00e3o \u00e9 preciso informar ao m\u00e9todo nenhum par\u00e2metro.<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre>bvname <span class=\"pl-k\">=<\/span> <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>bv_name<span class=\"pl-pds\">'<\/span><\/span>\nbv <span class=\"pl-k\">=<\/span> connection.getDataObjects(bvname)\ndata <span class=\"pl-k\">=<\/span> obj.read()\n\nvalue <span class=\"pl-k\">=<\/span> data.value\ntimestamp <span class=\"pl-k\">=<\/span> data.timestamp<\/pre>\n<\/div>\n<h3><\/h3>\n<h2>Escrita de Dados em uma Basic Variable<\/h2>\n<p>Existem dois m\u00e9todos para escrita de dados em uma <strong>Basic Variable<\/strong> de um <strong>EPM Server<\/strong>, cada um servindo a uma situa\u00e7\u00e3o.<\/p>\n<ul>\n<li><strong>write<\/strong>: Utiliza a via de tempo real do <strong>EPM Server<\/strong>. Deve ser utilizado quando se deseja escrever um valor \u00fanico em uma <strong>Basic Variable<\/strong>. Para que o <strong>dataobject<\/strong> receba uma escrita atrav\u00e9s deste m\u00e9todo \u00e9 necess\u00e1rio que n\u00e3o exista v\u00ednculo da <strong>Basic Variable<\/strong> com um endere\u00e7o do <strong>Interface Server<\/strong> e que estejam habilitadas as op\u00e7\u00f5es <strong>Enable Real Time<\/strong> e <strong>Record<\/strong> da <strong>Basic Variable<\/strong>.<\/li>\n<li><strong>historyUpdate<\/strong>: Utiliza a via de dados hist\u00f3ricos do <strong>EPM Server<\/strong>. Utilizado para escrever uma sequ\u00eancia de valores em uma <strong>Basic Variable<\/strong>. Como argumento deve-se passar uma estrutura de dados do tipo <strong>numpy array<\/strong> como mostrada no exemplo a seguir.<\/li>\n<\/ul>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> numpy <span class=\"pl-k\">as<\/span> np\narray_format <span class=\"pl-k\">=<\/span> np.dtype([(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Value<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>>f8<span class=\"pl-pds\">'<\/span><\/span>), (<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Timestamp<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>object<span class=\"pl-pds\">'<\/span><\/span>), (<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Quality<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>>i4<span class=\"pl-pds\">'<\/span><\/span>)])\n<\/pre>\n<\/div>\n<p>Neste exemplo, a coluna <strong>Value<\/strong> foi definida para o tipo de dados <strong>floating point<\/strong> (<code>>f8<\/code>) da linguagem <strong>Python<\/strong>. Caso os dados sejam de outro tipo, \u00e9 necess\u00e1rio adequar este par\u00e2metro para o tipo de dados correspondente. A coluna <strong>Timestamp<\/strong> deve sempre receber dados do tipo <strong>datetime<\/strong> da linguagem <strong>Python<\/strong>, e sempre em ordem cronol\u00f3gica natural, ou seja, dos mais antigos para os mais novos. A coluna <strong>Quality<\/strong> deve corresponder a uma qualidade do padr\u00e3o OPC UA. Para valores com qualidade boa, o valor correspondente \u00e9 0 (zero).<\/p>\n<blockquote>\n<ul>\n<li>Evite a escrita de dados fora de ordem cronol\u00f3gica. Quando o <strong>EPM Server<\/strong> recebe um valor fora de sequ\u00eancia, precisa de processamento extra para inseri-lo no ponto correto.<\/li>\n<\/ul>\n<\/blockquote>\n<h4><\/h4>\n<h4>basicvariable.write(data)<\/h4>\n<p>Exemplo de uso:<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Write<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">write<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmdataobject<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Write one value in epmdataobject<span class=\"pl-pds\">'''<\/span><\/span>\n\n    date <span class=\"pl-k\">=<\/span> datetime.datetime.now()\n    value <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">100<\/span>\n    quality <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">0<\/span> <span class=\"pl-c\">#zero is Good in OPC UA<\/span>\n\n    <span class=\"pl-k\">try<\/span>:\n        epmdataobject.write(value, date, quality)\n    <span class=\"pl-k\">except<\/span>:\n        <span class=\"pl-k\">raise<\/span> <span class=\"pl-c1\">Exception<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Error writing data.<span class=\"pl-pds\">'<\/span><\/span>)<\/pre>\n<\/div>\n<h4><\/h4>\n<h4>basicvariable.historyUpdate(data)<\/h4>\n<p>Neste exemplo tamb\u00e9m \u00e9 verificado o contexto de execu\u00e7\u00e3o do m\u00e9todo, <strong>Test<\/strong>, <strong>Simulation<\/strong> ou <strong>Production<\/strong>. Consulte a documenta\u00e7\u00e3o da biblioteca <strong>epmprocessor<\/strong> para mais informa\u00e7\u00f5es.<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmprocessor <span class=\"pl-k\">as<\/span> epr\n<span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n<span class=\"pl-k\">import<\/span> numpy <span class=\"pl-k\">as<\/span> np\n<span class=\"pl-k\">import<\/span> pandas <span class=\"pl-k\">as<\/span> pd\n<span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>HistoryUpdate<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">history_update<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmdataobject<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Update epmdataobject with five itens<span class=\"pl-pds\">'''<\/span><\/span>\n\n    <span class=\"pl-c\">#pandas generate a range of dates<\/span>\n    newdates <span class=\"pl-k\">=<\/span> pd.date_range(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>1\/1\/2018<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-v\">periods<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-c1\">5<\/span>,<span class=\"pl-v\">freq<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>H<span class=\"pl-pds\">'<\/span><\/span> )\n\n    <span class=\"pl-c\">#just a five itens list<\/span>\n    newvalues <span class=\"pl-k\">=<\/span> [<span class=\"pl-c1\">50<\/span>,<span class=\"pl-c1\">60<\/span>,<span class=\"pl-c1\">30<\/span>,<span class=\"pl-c1\">40<\/span>,<span class=\"pl-c1\">10<\/span>]\n    base <span class=\"pl-k\">=<\/span> datetime.datetime(<span class=\"pl-c1\">2018<\/span>,<span class=\"pl-c1\">1<\/span>,<span class=\"pl-c1\">1<\/span>)\n    newdates <span class=\"pl-k\">=<\/span> np.array([base <span class=\"pl-k\">+<\/span> datetime.timedelta(<span class=\"pl-v\">hours<\/span><span class=\"pl-k\">=<\/span>i) <span class=\"pl-k\">for<\/span> i <span class=\"pl-k\">in<\/span> <span class=\"pl-c1\">range<\/span>(<span class=\"pl-c1\">5<\/span>)])\n\n    <span class=\"pl-c\"># epm ndarray data format.<\/span>\n    desc <span class=\"pl-k\">=<\/span> np.dtype([(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Value<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>>f8<span class=\"pl-pds\">'<\/span><\/span>), (<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Timestamp<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>object<span class=\"pl-pds\">'<\/span><\/span>), (<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Quality<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>>i4<span class=\"pl-pds\">'<\/span><\/span>)])\n    datatemp <span class=\"pl-k\">=<\/span> np.empty(<span class=\"pl-c1\">len<\/span>(newvalues), <span class=\"pl-v\">dtype<\/span><span class=\"pl-k\">=<\/span>desc)\n\n    <span class=\"pl-c\">#loop to populate the object before send to EPM<\/span>\n    i<span class=\"pl-k\">=<\/span><span class=\"pl-c1\">0<\/span>\n    <span class=\"pl-k\">while<\/span> i <span class=\"pl-k\"><<\/span> <span class=\"pl-c1\">len<\/span>(newvalues):\n        datatemp[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Value<span class=\"pl-pds\">'<\/span><\/span>][i] <span class=\"pl-k\">=<\/span> newvalues[i]\n        datatemp[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Timestamp<span class=\"pl-pds\">'<\/span><\/span>][i] <span class=\"pl-k\">=<\/span> newdates[i]\n        datatemp[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Quality<span class=\"pl-pds\">'<\/span><\/span>][i] <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">0<\/span>\n        i <span class=\"pl-k\">=<\/span> i<span class=\"pl-k\">+<\/span><span class=\"pl-c1\">1<\/span>\n    <span class=\"pl-k\">try<\/span>:\n\n        <span class=\"pl-k\">if<\/span> session.scopeContext <span class=\"pl-k\">==<\/span> epr.ScopeContext.Test:\n            <span class=\"pl-c1\">print<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Resultado: <span class=\"pl-c1\">{valor}<\/span> - <span class=\"pl-c1\">{timestamp}<\/span><span class=\"pl-pds\">'<\/span><\/span>.format(<span class=\"pl-v\">valor<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-c1\">str<\/span>(datatemp[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Value<span class=\"pl-pds\">'<\/span><\/span>][<span class=\"pl-k\">-<\/span><span class=\"pl-c1\">1<\/span>]),\n                                                                <span class=\"pl-v\">timestamp<\/span><span class=\"pl-k\">=<\/span>datatemp[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Timestamp<span class=\"pl-pds\">'<\/span><\/span>][<span class=\"pl-k\">-<\/span><span class=\"pl-c1\">1<\/span>].isoformat()))\n        <span class=\"pl-k\">else<\/span>:  <span class=\"pl-c\"># Production ou Simulation<\/span>\n            epmdataobject.historyUpdate(datatemp)\n\n    <span class=\"pl-k\">except<\/span>:\n        <span class=\"pl-k\">raise<\/span> <span class=\"pl-c1\">Exception<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Error in historyUpdate<span class=\"pl-pds\">'<\/span><\/span>)<\/pre>\n<\/div>\n<h2><\/h2>\n<h2>Acesso aos Resources<\/h2>\n<p>\u00c9 poss\u00edvel acessar a estrutura de arquivos dos recursos do <strong>EPM Webserver<\/strong> atrav\u00e9s da API. S\u00e3o acess\u00edveis tanto recursos do pr\u00f3prio <strong>EPM Processor<\/strong> como do <strong>EPM Portal<\/strong>. Para acessar os recursos, \u00e9 necess\u00e1rio ter um par\u00e2metro do tipo <strong>epmconnection<\/strong>. Para isto, utilize o c\u00f3digo a seguir.<\/p>\n<p><code>resource_manager = epmconnection.getProcessorResourcesManager()<\/code><\/p>\n<p>Para recursos do <strong>EPM Portal<\/strong>, utilize o c\u00f3digo a seguir.<\/p>\n<p><code>resource_manager = epmconnection.getPortalResourcesManager()<\/code><\/p>\n<h3><\/h3>\n<h3>Exemplos<\/h3>\n<h4><\/h4>\n<h4>Download de Recursos<\/h4>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>ResourceAccess<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">resource_access<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmconnection<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Access resource from EPM Processor <span class=\"pl-pds\">'''<\/span><\/span>\n\n    resource_manager <span class=\"pl-k\">=<\/span> epmconnection.getProcessorResourcesManager()\n    image_resource <span class=\"pl-k\">=<\/span> resource_manager.getResource(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>folder\/image.png<span class=\"pl-pds\">'<\/span><\/span>)\n    image <span class=\"pl-k\">=<\/span> image_resource.download(epm.DownloadType.Binary)   \n<\/pre>\n<\/div>\n<h4><\/h4>\n<h4>Upload de Imagem para uma Pasta do EPM Portal<\/h4>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>UploadImage<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">upload_image<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmconnection<\/span>, <span class=\"pl-smi\">pathname<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Upload matplotlib .png chart to EPM Portal resources folder <span class=\"pl-pds\">'''<\/span><\/span>\n\n    some_data <span class=\"pl-k\">=<\/span> [<span class=\"pl-c1\">1<\/span>,<span class=\"pl-c1\">2<\/span>,<span class=\"pl-c1\">3<\/span>,<span class=\"pl-c1\">4<\/span>,<span class=\"pl-c1\">5<\/span>]\n    <span class=\"pl-k\">import<\/span> matploptlib.pyplot <span class=\"pl-k\">as<\/span> plt\n    <span class=\"pl-k\">import<\/span> io\n    <span class=\"pl-k\">import<\/span> mimetypes\n\n    plt.plot(some_data)    \n    buffer <span class=\"pl-k\">=<\/span> io.BytesIO()    \n    plt.savefig(buffer, <span class=\"pl-v\">format<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>png<span class=\"pl-pds\">'<\/span><\/span>) <span class=\"pl-c\">#salva figura em buffer<\/span>\n    buffer.seek(<span class=\"pl-c1\">0<\/span>)\n\n    resource_manager <span class=\"pl-k\">=<\/span> epmconnection.getPortalResourcesManager()\n    folder <span class=\"pl-k\">=<\/span> resource_manager.getResource(pathname)\n\n    <span class=\"pl-c\">#faz upload do buffer com o tipo .png<\/span>\n    resource <span class=\"pl-k\">=<\/span> imgFolder.upload(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>image.png<span class=\"pl-pds\">'<\/span><\/span>, buffer, <span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>matplotlib plot<span class=\"pl-pds\">'<\/span><\/span>,\n                                mimetypes.types_map[<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>.png<span class=\"pl-pds\">'<\/span><\/span>], <span class=\"pl-v\">overrideFile<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-c1\">True<\/span>)<\/pre>\n<\/div>\n<h4><\/h4>\n<h4>Apagando um Resource<\/h4>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Delete<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">delete_image<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">epmconnection<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Delete EPM Portal resource<span class=\"pl-pds\">'''<\/span><\/span>  \n\n    resource_manager <span class=\"pl-k\">=<\/span> epmconnection.getPortalResourcesManager()    \n    resource_manager.getResource(<span class=\"pl-s\"><span class=\"pl-k\">u<\/span><span class=\"pl-pds\">'<\/span>folder\/image.png<span class=\"pl-pds\">'<\/span><\/span>).delete()<\/pre>\n<\/div>\n<h2><\/h2>\n<h2>Objetos do Elipse Data Model (Aplica\u00e7\u00f5es do E3 ou Elipse Power)<\/h2>\n<p>O <strong>Elipse DataModel<\/strong> permite replicar a estrutura de dados dos sistemas SCADA da <strong>Elipse Software<\/strong> (<strong>E3<\/strong> ou <strong>Elipse Power<\/strong>). Uma vez que esta estrutura exista no <strong>EPM Server<\/strong>, \u00e9 poss\u00edvel localizar e trabalhar com seus elementos no c\u00f3digo.<\/p>\n<p>Uma das formas de obter estes elementos \u00e9 utilizando o tipo de dados <strong>epmobjectDic<\/strong> como par\u00e2metro de entrada. Desta forma o filtro \u00e9 realizado no <strong>EPM Server<\/strong> e o par\u00e2metro cont\u00e9m um objeto do tipo de dados dicion\u00e1rio ordenado da linguagem <strong>Python<\/strong> com o resultado do filtro.<\/p>\n<p><a href=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\/blob\/master\/guiadousuario\/images\/algoritmos_epmobjectDict.PNG\" target=\"_blank\" rel=\"noopener noreferrer\"><img title=\"Configura\u00e7\u00e3o de par\u00e2metros\" src=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\/raw\/master\/guiadousuario\/images\/algoritmos_epmobjectDict.PNG\" alt=\"epmobjectdict\" \/><\/a><\/p>\n<p>A tabela a seguir descreve as op\u00e7\u00f5es mostradas na imagem anterior.<\/p>\n<table>\n<thead>\n<tr>\n<th>Op\u00e7\u00e3o<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>EPM Connection<\/strong><\/td>\n<td>Uma das conex\u00f5es configuradas em <strong>EPM Connections<\/strong><\/td>\n<\/tr>\n<tr>\n<td><strong>Filter<\/strong><\/td>\n<td>Nome ou parte do nome do objeto. O filtro diferencia entre mai\u00fasculas e min\u00fasculas<\/td>\n<\/tr>\n<tr>\n<td><strong>Type<\/strong><\/td>\n<td>Tipo do objeto<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3><\/h3>\n<h3>Exemplo<\/h3>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n<span class=\"pl-k\">import<\/span> epmprocessor <span class=\"pl-k\">as<\/span> epr\n<span class=\"pl-k\">import<\/span> datetime\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>GetHistoryRaw<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">get_history_raw<\/span>(<span class=\"pl-smi\">session<\/span>, <span class=\"pl-smi\">obj_dict<\/span>):\n    <span class=\"pl-s\"><span class=\"pl-pds\">'''<\/span>Get one hour raw historic data from epm dataobject<span class=\"pl-pds\">'''<\/span><\/span>\n\n    endtime <span class=\"pl-k\">=<\/span> session.timeEvent\n\n    initime <span class=\"pl-k\">=<\/span> endtime <span class=\"pl-k\">-<\/span> datetime.timedelta(session.range)\n\n    queryperiod <span class=\"pl-k\">=<\/span> epm.QueryPeriod(initime, endtime)\n\n    <span class=\"pl-k\">for<\/span> obj <span class=\"pl-k\">in<\/span> obj_dict.values():\n        <span class=\"pl-c1\">print<\/span>(obj.historyReadRaw(queryperiod))\n\n    <span class=\"pl-k\">return<\/span> epr.ScopeResult(<span class=\"pl-c1\">True<\/span>)<\/pre>\n<\/div>\n<h2><\/h2>\n<h2>Contexto<\/h2>\n<p>Atrav\u00e9s de um par\u00e2metro da <code>session<\/code> \u00e9 poss\u00edvel verificar qual \u00e9 o contexto em que o m\u00e9todo est\u00e1 sendo executado.<\/p>\n<ul>\n<li><strong>Test<\/strong>: Quando \u00e9 executado atrav\u00e9s da op\u00e7\u00e3o <strong>Test<\/strong> do <strong>Code Package<\/strong><\/li>\n<li><strong>Simulation<\/strong>: Quando \u00e9 executado a partir de uma <strong>Simulation<\/strong><\/li>\n<li><strong>Production<\/strong>: Quando \u00e9 executado a partir de uma <strong>Production<\/strong><\/li>\n<\/ul>\n<p>Pode ser interessante criar execu\u00e7\u00f5es diferenciadas para cada um dos casos. Por exemplo, em <strong>Test<\/strong> ou <strong>Simulation<\/strong> pode n\u00e3o ser interessante escrever o resultado em vari\u00e1veis do <strong>EPM Server<\/strong>, mas sim mostrar o resultado utilizando o m\u00e9todo <code>print<\/code>.<\/p>\n<div class=\"highlight highlight-source-python\">\n<pre><span class=\"pl-k\">import<\/span> epmprocessor <span class=\"pl-k\">as<\/span> epr\n<span class=\"pl-k\">import<\/span> epmwebapi <span class=\"pl-k\">as<\/span> epm\n\n<span class=\"pl-en\">@epr.applicationMethod<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>ScopeContext<span class=\"pl-pds\">'<\/span><\/span>)\n<span class=\"pl-k\">def<\/span> <span class=\"pl-en\">scope_context<\/span>(<span class=\"pl-smi\">session<\/span>):\n\n    <span class=\"pl-k\">if<\/span> session.scopeContext <span class=\"pl-k\">==<\/span> session.scopeContext.Test:\n        <span class=\"pl-c\">#do it in test<\/span>\n        <span class=\"pl-c1\">print<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Test Context<span class=\"pl-pds\">'<\/span><\/span>)\n\n    <span class=\"pl-k\">if<\/span> session.scopeContext <span class=\"pl-k\">==<\/span> session.scopeContext.Simulation:\n        <span class=\"pl-c\">#do it in simulation<\/span>\n        <span class=\"pl-c1\">print<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Simulation Context<span class=\"pl-pds\">'<\/span><\/span>)\n\n    <span class=\"pl-k\">if<\/span> session.scopeContext <span class=\"pl-k\">==<\/span> session.scopeContext.Production:\n        <span class=\"pl-c\">#do it in production<\/span>\n        <span class=\"pl-c1\">print<\/span>(<span class=\"pl-s\"><span class=\"pl-pds\">'<\/span>Production Context<span class=\"pl-pds\">'<\/span><\/span>)\n<\/pre>\n<p>Para mais informa\u00e7\u00f5es sobre o EPM Processor, acesse:<br \/>\n<a href=\"https:\/\/www.elipse.com.br\/produto\/elipse-plant-manager\/\">https:\/\/www.elipse.com.br\/produto\/elipse-plant-manager\/<\/a><br \/>\n<a href=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\">https:\/\/github.com\/elipsesoftware\/epmprocessor.<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introdu\u00e7\u00e3o O EPM Processor \u00e9 o m\u00f3dulo do Elipse Plant Manager respons\u00e1vel pela execu\u00e7\u00e3o de c\u00f3digos em linguagem Python baseados em eventos simulados ou de tempo real. Quando se deseja&hellip;<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0},"categories":[676],"tags":[870,882,883],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Criando algoritmos em Python para o EPM Processor da Elipse Software<\/title>\n<meta name=\"description\" content=\"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Criando algoritmos em Python para o EPM Processor da Elipse Software\" \/>\n<meta property=\"og:description\" content=\"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\" \/>\n<meta property=\"og:site_name\" content=\"Elipse Knowledgebase\" \/>\n<meta property=\"article:publisher\" content=\"http:\/\/www.facebook.com\/elipsesoftware\" \/>\n<meta property=\"article:published_time\" content=\"2019-09-11T17:43:22+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-03-26T14:22:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.com\/elipsesoftware\/epmprocessor\/raw\/master\/guiadousuario\/images\/algoritmos_fluxo.PNG\" \/>\n<meta name=\"author\" content=\"Lucas Kotres\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Lucas Kotres\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\"},\"author\":{\"name\":\"Lucas Kotres\",\"@id\":\"https:\/\/kb.elipse.com.br\/#\/schema\/person\/e57d707c58cf7aa3231eb5fdcc2ec379\"},\"headline\":\"Criando Algoritmos em Python para o EPM Processor.\",\"datePublished\":\"2019-09-11T17:43:22+00:00\",\"dateModified\":\"2024-03-26T14:22:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\"},\"wordCount\":3549,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/kb.elipse.com.br\/#organization\"},\"keywords\":[\"EPM Processor\",\"Processor\",\"Python\"],\"articleSection\":[\"Elipse Plant Manager\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\",\"url\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\",\"name\":\"Criando algoritmos em Python para o EPM Processor da Elipse Software\",\"isPartOf\":{\"@id\":\"https:\/\/kb.elipse.com.br\/#website\"},\"datePublished\":\"2019-09-11T17:43:22+00:00\",\"dateModified\":\"2024-03-26T14:22:50+00:00\",\"description\":\"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.\",\"breadcrumb\":{\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"In\u00edcio\",\"item\":\"https:\/\/kb.elipse.com.br\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Criando Algoritmos em Python para o EPM Processor.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/kb.elipse.com.br\/#website\",\"url\":\"https:\/\/kb.elipse.com.br\/\",\"name\":\"Elipse Knowledgebase\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/kb.elipse.com.br\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/kb.elipse.com.br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/kb.elipse.com.br\/#organization\",\"name\":\"Elipse Software\",\"url\":\"https:\/\/kb.elipse.com.br\/\",\"sameAs\":[\"http:\/\/www.facebook.com\/elipsesoftware\"],\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/kb.elipse.com.br\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/kb.elipse.com.br\/wp-content\/uploads\/2019\/05\/schererelipse-com-br\/logoElipse.png\",\"contentUrl\":\"https:\/\/kb.elipse.com.br\/wp-content\/uploads\/2019\/05\/schererelipse-com-br\/logoElipse.png\",\"width\":161,\"height\":58,\"caption\":\"Elipse Software\"},\"image\":{\"@id\":\"https:\/\/kb.elipse.com.br\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/kb.elipse.com.br\/#\/schema\/person\/e57d707c58cf7aa3231eb5fdcc2ec379\",\"name\":\"Lucas Kotres\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/kb.elipse.com.br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/faa3c53fb2e8ab0c35c4b8c90a691931?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/faa3c53fb2e8ab0c35c4b8c90a691931?s=96&d=mm&r=g\",\"caption\":\"Lucas Kotres\"},\"url\":\"https:\/\/kb.elipse.com.br\/en\/author\/kotres\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Criando algoritmos em Python para o EPM Processor da Elipse Software","description":"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/","og_locale":"en_US","og_type":"article","og_title":"Criando algoritmos em Python para o EPM Processor da Elipse Software","og_description":"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.","og_url":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/","og_site_name":"Elipse Knowledgebase","article_publisher":"http:\/\/www.facebook.com\/elipsesoftware","article_published_time":"2019-09-11T17:43:22+00:00","article_modified_time":"2024-03-26T14:22:50+00:00","og_image":[{"url":"https:\/\/github.com\/elipsesoftware\/epmprocessor\/raw\/master\/guiadousuario\/images\/algoritmos_fluxo.PNG"}],"author":"Lucas Kotres","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Lucas Kotres","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#article","isPartOf":{"@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/"},"author":{"name":"Lucas Kotres","@id":"https:\/\/kb.elipse.com.br\/#\/schema\/person\/e57d707c58cf7aa3231eb5fdcc2ec379"},"headline":"Criando Algoritmos em Python para o EPM Processor.","datePublished":"2019-09-11T17:43:22+00:00","dateModified":"2024-03-26T14:22:50+00:00","mainEntityOfPage":{"@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/"},"wordCount":3549,"commentCount":0,"publisher":{"@id":"https:\/\/kb.elipse.com.br\/#organization"},"keywords":["EPM Processor","Processor","Python"],"articleSection":["Elipse Plant Manager"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/","url":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/","name":"Criando algoritmos em Python para o EPM Processor da Elipse Software","isPartOf":{"@id":"https:\/\/kb.elipse.com.br\/#website"},"datePublished":"2019-09-11T17:43:22+00:00","dateModified":"2024-03-26T14:22:50+00:00","description":"Quando se deseja implementar algoritmos para serem utilizados no EPM Processor, estes devem ser codificado dentro de uma fun\u00e7\u00e3o em linguagem Python.","breadcrumb":{"@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/kb.elipse.com.br\/criando-algoritmos-em-python-para-o-epm-processor\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"In\u00edcio","item":"https:\/\/kb.elipse.com.br\/en\/"},{"@type":"ListItem","position":2,"name":"Criando Algoritmos em Python para o EPM Processor."}]},{"@type":"WebSite","@id":"https:\/\/kb.elipse.com.br\/#website","url":"https:\/\/kb.elipse.com.br\/","name":"Elipse Knowledgebase","description":"","publisher":{"@id":"https:\/\/kb.elipse.com.br\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/kb.elipse.com.br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/kb.elipse.com.br\/#organization","name":"Elipse Software","url":"https:\/\/kb.elipse.com.br\/","sameAs":["http:\/\/www.facebook.com\/elipsesoftware"],"logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kb.elipse.com.br\/#\/schema\/logo\/image\/","url":"https:\/\/kb.elipse.com.br\/wp-content\/uploads\/2019\/05\/schererelipse-com-br\/logoElipse.png","contentUrl":"https:\/\/kb.elipse.com.br\/wp-content\/uploads\/2019\/05\/schererelipse-com-br\/logoElipse.png","width":161,"height":58,"caption":"Elipse Software"},"image":{"@id":"https:\/\/kb.elipse.com.br\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/kb.elipse.com.br\/#\/schema\/person\/e57d707c58cf7aa3231eb5fdcc2ec379","name":"Lucas Kotres","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/kb.elipse.com.br\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/faa3c53fb2e8ab0c35c4b8c90a691931?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/faa3c53fb2e8ab0c35c4b8c90a691931?s=96&d=mm&r=g","caption":"Lucas Kotres"},"url":"https:\/\/kb.elipse.com.br\/en\/author\/kotres\/"}]}},"_links":{"self":[{"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/posts\/8125"}],"collection":[{"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/comments?post=8125"}],"version-history":[{"count":47,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/posts\/8125\/revisions"}],"predecessor-version":[{"id":16094,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/posts\/8125\/revisions\/16094"}],"wp:attachment":[{"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/media?parent=8125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/categories?post=8125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kb.elipse.com.br\/en\/wp-json\/wp\/v2\/tags?post=8125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}