Quickstart - Dicas básicas para entendimento e início de desenvolvimento

Conectando ao EPM Webserver

In [3]:
import epmwebapi as epm
import numpy as np
import datetime

##Método para não expor usuário e senha do EPM no código fonte
import getpass
user = input('EPM user:')
password = getpass.getpass("EPM password:")

#crie o objeto de conexão informando os endereços do EPM Webserver(Authentication Port e WEB API Port), usuário e senha.
connection = epm.EpmConnection('http://localhost:44333', 'http://localhost:44332', user, password)
EPM user:sa
EPM password:········

Leitura de dados históricos brutos(Raw)

In [4]:
bvname = 'ADM_Temperature'

bv = connection.getDataObjects([bvname])

end_date = datetime.datetime.now()
ini_date= end_date - datetime.timedelta(minutes=10)
queryPeriod = epm.QueryPeriod(ini_date,end_date)

data = bv[bvname].historyReadRaw(queryPeriod)

print(data)
[]

Leitura usando agregação de dados (Baseados na norma OPC UA) Para informações sobre os tipos de agregações, consulte o Apêndice A do Guia do Usuário: https://github.com/elipsesoftware/epmprocessor/blob/master/guiadousuario/Agregacoes.md

In [5]:
bvname = 'ADM_Temperature'

bv = connection.getDataObjects([bvname])

end_date = datetime.datetime.now()
ini_date= end_date - datetime.timedelta(hours=1)

queryPeriod = epm.QueryPeriod(ini_date,end_date)

processInterval = datetime.timedelta(minutes=10)
aggDetails = epm.AggregateDetails(processInterval, epm.AggregateType.Interpolative)


data = bv[bvname].historyReadAggregate(aggDetails, queryPeriod)

print(data)
[(26.37188 , datetime.datetime(2018, 11, 6, 13, 17, 55, 383483, tzinfo=tzutc()), 0)
 (26.60276 , datetime.datetime(2018, 11, 6, 13, 27, 55, 383483, tzinfo=tzutc()), 0)
 (26.711302, datetime.datetime(2018, 11, 6, 13, 37, 55, 383483, tzinfo=tzutc()), 0)
 (26.855967, datetime.datetime(2018, 11, 6, 13, 47, 55, 383483, tzinfo=tzutc()), 0)
 (26.821869, datetime.datetime(2018, 11, 6, 13, 57, 55, 383483, tzinfo=tzutc()), 0)
 (26.781046, datetime.datetime(2018, 11, 6, 14, 7, 55, 383483, tzinfo=tzutc()), 0)]

Escrita de conjuntos de dados históricos no EPM Server

In [ ]:
import numpy as np

bvname = 'bvname'

bv = connection.getDataObjects([bvname])

#some values for write tests
newvalues = [50,60,30,40,10]
base = datetime.datetime(2018, 1, 1)
newdates = np.array([base + datetime.timedelta(hours=i) for i in range(5)])

# epm ndarray data format.
desc = np.dtype([('Value', '>f8'), ('Timestamp', 'object'), ('Quality', '>i4')])
datatemp = np.empty(len(newvalues), dtype=desc)

#loop to populate the object before send to EPM
i=0
while i < len(newvalues):
    datatemp['Value'][i] = newvalues[i]
    datatemp['Timestamp'][i] = newdates[i]
    datatemp['Quality'][i] = 0
    i = i+1
    
bv[bvname].historyUpdate(datatemp)

Escrita de valores no EPM Server

In [ ]:
bvname = 'bvname'

bv = connection.getDataObjects([bvname])

date = datetime.datetime.now()
value = 100
quality = 0 #zero is Good in OPC UA

bv[bvname].write(value, date, quality)

Leitura do valor de tempo real da variável

In [15]:
bvname = 'ADM_Temperature'

bv = connection.getDataObjects(bvname)

data = bv[bvname].read()

print(data.value)
print(data.timestamp)
25.299999237060547
2018-11-06T16:22:06.94Z

Filtro de variáveis

Vamos ler todas as variáveis do tipo Basic Variable, que contenha "Temperature" no final do nome e estejam configuradas com o tipo Continuous.

In [16]:
from epmwebapi.dataobjectattributes import DataObjectAttributes
from epmwebapi.dataobjectsfilter import DataObjectsFilter
from epmwebapi.dataobjectsfilter import DataObjectsFilterType
from epmwebapi.domainfilter import DomainFilter

Filter = DataObjectsFilter(DataObjectsFilterType.BasicVariable, '*Temperature', None, None, DomainFilter.Continuous)

properties = DataObjectAttributes.Description | DataObjectAttributes.LowLimit | DataObjectAttributes.HighLimit | DataObjectAttributes.EU
#A query retorna um OrderedDict
query = connection.filterDataObjects(Filter, properties)


#percorre todos as variáveis encontradas e executa o método read()
for item in list(query.values()):
    
    data = item.read()
    print('{} >>> {}'.format(item.name,data.value))   
ADM_Temperature >>> 25.200000762939453
TI_Temperature >>> 24.899999618530273
TechnicalSupportTemperature >>> 24.399999618530273
E3Dev_Temperature >>> 24.100000381469727
EPMDev_Temperature >>> 24.200000762939453
MeetingRoom11th_Temperature >>> 26.200000762939453
MeetingRoom10th_Temperature >>> 26.100000381469727
PowerDev_Temperature >>> 24.200000762939453
TIServidores_Temperature >>> 19.600000381469727
Auditorio_Temperature >>> 22.5
Treinamento_Temperature >>> 26.200000762939453
MeetingRoom12th_Temperature >>> 26.100000381469727
Dev12th_Temperature >>> 22.5
MobileDev_Temperature >>> 21.799999237060547
Dev11th_Temperature >>> 24.399999618530273

Percorrendo a estrutura do Elipse DataModel

O Elipse DataModel replica a estrutura dos sistemas SCADA E3 e Elipse Power e automatiza a expansão. Isso facilita a elaboração de análises que se adaptam ao crescimento contínuo do sistema, como a entrada de mais variáveis e estruturas. Essa é a estrutura do ECC, sistema de dados da Elipse, vamos percorrer a estrutura para encontra a propriedade Description de cada filial: ECC DataModel

In [17]:
#endereço da raiz da estrutura do EPM
basePath = '/Models/ElipseDataModel/DataModel/Elipse'

#busca do endereço no EPM Server
itens = connection.getObjects(basePath)

#percorre a lista de itens da raiz
for item in list(itens.values()):    
    
    #lista o primeiro nível
    filiais = list(item.enumObjects().values())
    
    #percorre o segundo nível 
    for filial in filiais:
        
        #lista o segundo nível e escolhe a segunda propriedade(índice 1), chamada Description
        obj = list(filial.enumProperties().values())[1]
        
        # faz a leitura do objeto
        data = obj.read()
        #imprime a propriedade value
        print(data.value)
Elipse Software - Filial SP
Elipse Software - Filial RJ
Elipse Software - Filial Taiwan
Elipse Software - Filial MG
Elipse Software - Matriz RS
Elipse Software - Filial PR

Escrevendo Anotações

A estrutura de dados do EPM permite que se escrevam anotações nas variáveis. A anotação consiste em mensagem, estampa de tempo e usuário. Nesse exemplo vamos escrever uma anotação no valor máximo da variável no período consultado.

In [ ]:
bvname = 'ADM_Temperature'

bv = connection.getDataObjects([bvname])

end_date = datetime.datetime.now()
ini_date= end_date - datetime.timedelta(minutes=10)
queryPeriod = epm.QueryPeriod(ini_date,end_date)
data = bv[bvname].historyReadRaw(queryPeriod)

max_value = data['Value'].max()

max_index = np.argwhere(data['Value'] == max_value)

print(max_index)

print(data['Timestamp'][max_index][0])

#escrevendo anotação
message = 'valor maximo encontrado no periodo'
timestamp = data['Timestamp'][max_index]
bv[bvname].writeAnnotation(timestamp,message)

Consultando anotações

In [19]:
bvname = 'ADM_Temperature'

bv = connection.getDataObjects([bvname])

end_date = datetime.date(2018, 10, 19)
ini_date = end_date - datetime.timedelta(hours=24)

annotations = bv[bvname].readAnnotations(ini_date,end_date)
print(annotations)
[(datetime.datetime(2018, 10, 18, 12, 51, 39, tzinfo=tzutc()), 'sa', 'Valor mínimo encontrado em 18/10/2018'), (datetime.datetime(2018, 10, 18, 18, 4, 18, tzinfo=tzutc()), 'sa', 'Valor máximo registrado no dia 18/10/2018.')]

Fechando a conexão

É importante fechar a conexão para liberá-la para outros possíveis clients.

In [ ]:
connection.close()