Skip to content
Snippets Groups Projects
Commit 624fc1a6 authored by Stefano Di Frischia's avatar Stefano Di Frischia
Browse files

Merge branch 'L2SS-234-inspect-archive-from-python' into 'master'

L2SS-234: Inspect archive from python

Closes L2SS-234

See merge request !59
parents 649b4bdf f0f4eb70
Branches
Tags
1 merge request!59L2SS-234: Inspect archive from python
...@@ -17,7 +17,7 @@ sys.path.append(parentdir) ...@@ -17,7 +17,7 @@ sys.path.append(parentdir)
# PyTango imports # PyTango imports
from tango import DevState from tango import DevState
from tango.server import run, Device, attribute, command from tango.server import run, Device, attribute, command
from numpy import random from numpy import random, double
__all__ = ["Random_Data", "main"] __all__ = ["Random_Data", "main"]
......
#! /usr/bin/env python3 #! /usr/bin/env python3
from clients.attribute_wrapper import attribute_wrapper
from tango import DeviceProxy from tango import DeviceProxy
from datetime import datetime, timedelta
from sqlalchemy import create_engine, and_
from sqlalchemy.orm import sessionmaker
from .archiver_base import *
def add_attribute_to_archiver(attribute: str, polling_period: float, event_period: float, archive_manager: str = 'archiving/hdbpp/confmanager01', archiver: str = 'archiving/hdbpp/eventsubscriber01'): class Archiver():
am = DeviceProxy(archive_manager) """
am.write_attribute('SetAttributeName', attribute) The Archiver class implements the basic operations to perform attributes archiving
am.write_attribute('SetArchiver', archiver) """
am.write_attribute('SetStrategy', 'ALWAYS') def __init__(self, cm_name: str = 'archiving/hdbpp/confmanager01', es_name: str = 'archiving/hdbpp/eventsubscriber01'):
am.write_attribute('SetPollingPeriod', int(polling_period)) self.cm_name = cm_name
am.write_attribute('SetPeriodEvent', int(event_period)) self.cm = DeviceProxy(cm_name)
am.AttributeAdd() self.es_name = es_name
am.AttributeStart(attribute) self.es = DeviceProxy(es_name)
def remove_attribute_from_archiver(attribute: str, archive_manager: str = 'archiving/hdbpp/confmanager01'): def add_attribute_to_archiver(self, attribute: str, polling_period: float = 1000, event_period: float = 1000, strategy: str = 'ALWAYS'):
am = DeviceProxy(archive_manager) """
am.AttributeStop(attribute) Takes as input the attribute name, polling period (ms), event period (ms) and archiving strategy,
am.AttributeRemove(attribute) and adds the selected attribute to the subscriber's list of archiving attributes.
The ConfigurationManager and EventSubscriber devices must be already up and running.
The archiving-DBMS must be already properly configured.
"""
self.cm.write_attribute('SetAttributeName', attribute)
self.cm.write_attribute('SetArchiver', self.es_name)
self.cm.write_attribute('SetStrategy', strategy)
self.cm.write_attribute('SetPollingPeriod', int(polling_period))
self.cm.write_attribute('SetPeriodEvent', int(event_period))
self.cm.AttributeAdd()
def remove_attribute_from_archiver(self, attribute: str):
"""
Stops the data archiving of the attribute passed as input, and remove it from the subscriber's list.
"""
self.cm.AttributeStop(attribute)
self.cm.AttributeRemove(attribute)
class Retriever():
"""
The Retriever class implements retrieve operations on a given DBMS
"""
def __init__(self, cm_name: str = 'archiving/hdbpp/confmanager01'):
self.cm_name = cm_name
self.session = self.connect_to_archiving_db()
def get_db_credentials(self):
"""
Retrieves the DB credentials from the Tango properties of Configuration Manager
"""
cm = DeviceProxy(self.cm_name)
config_list = cm.get_property('LibConfiguration')['LibConfiguration'] # dictionary {'LibConfiguration': list of strings}
host = str([s for s in config_list if "host" in s][0].split('=')[1])
dbname = str([s for s in config_list if "dbname" in s][0].split('=')[1])
port = str([s for s in config_list if "port" in s][0].split('=')[1])
user = str([s for s in config_list if "user" in s][0].split('=')[1])
pw = str([s for s in config_list if "password" in s][0].split('=')[1])
return host,dbname,port,user,pw
def connect_to_archiving_db(self):
"""
Returns a session to a MySQL DBMS using default credentials.
"""
host,dbname,port,user,pw = self.get_db_credentials()
engine = create_engine('mysql+pymysql://'+user+':'+pw+'@'+host+':'+port+'/'+dbname)
Session = sessionmaker(bind=engine)
return Session()
def get_all_archived_attributes(self):
"""
Returns a list of the archived attributes in the DB.
"""
attrs = self.session.query(Attribute).order_by(Attribute.att_conf_id).all()
# Returns the representation as set in __repr__ method of the mapper class
return attrs
def get_archived_attributes_by_device(self,device_fqname: str):
"""
Takes as input the fully-qualified name of a device and returns a list of its archived attributes
"""
try:
[domain, family, member] = device_fqname.split('/')
except:
print("Device name error. Use FQDN - eg: LTS/Device/1")
return
attrs = self.session.query(Attribute).filter(and_(Attribute.domain == domain, Attribute.family == family, \
Attribute.member == member)).all()
# Returns the representation as set in __repr__ method of the mapper class
return attrs
def get_attribute_id(self,attribute_fqname: str):
"""
Takes as input the fully-qualified name of an attribute and returns its id.
"""
try:
[domain, family, member, name] = attribute_fqname.split('/')
except:
print("Attribute name error. Use FQDN - eg: LTS/Device/1/Attribute")
return
try:
result = self.session.query(Attribute.att_conf_id).filter(and_(Attribute.domain == domain, Attribute.family == family, \
Attribute.member == member, Attribute.name == name)).one()
return result[0]
except TypeError:
print("Attribute not found!")
return
def get_attribute_datatype(self,attribute_fqname: str):
"""
Takes as input the fully-qualified name of an attribute and returns its Data-Type.
Data Type name indicates the type (e.g. string, int, ...) and the read/write property. The name is used
as DB table name suffix in which values are stored.
"""
try:
[domain, family, member, name] = attribute_fqname.split('/')
except:
print("Attribute name error. Use FQDN - eg: LTS/Device/1/Attribute")
return
try:
result = self.session.query(DataType.data_type).join(Attribute,Attribute.att_conf_data_type_id==DataType.att_conf_data_type_id).\
filter(and_(Attribute.domain == domain, Attribute.family == family, Attribute.member == member, Attribute.name == name)).one()
return result[0]
except TypeError:
print("Attribute not found!")
return
def get_attribute_value_by_hours(self,attribute_fqname: str, hours: float = 1.0):
"""
Takes as input the attribute fully-qualified name and the number of past hours since the actual time
(e.g. hours=1 retrieves values in the last hour, hours=8.5 retrieves values in the last eight hours and half).
Returns a list of timestamps and a list of values
"""
attr_id = self.get_attribute_id(attribute_fqname)
attr_datatype = self.get_attribute_datatype(attribute_fqname)
attr_table_name = 'att_'+str(attr_datatype)
# Retrieves the class that maps the DB table given the tablename
base_class = get_class_by_tablename(attr_table_name)
# Retrieves the timestamp
time_now = datetime.now()
time_delta = time_now - timedelta(hours=hours)
# Converts the timestamps in the right format for the query
time_now_db = str(time_now.strftime("%Y-%m-%d %X"))
time_delta_db = str(time_delta.strftime("%Y-%m-%d %X"))
result = self.session.query(base_class).\
join(Attribute,Attribute.att_conf_id==base_class.att_conf_id).\
filter(and_(Attribute.att_conf_id == attr_id,base_class.data_time >= time_delta_db, \
base_class.data_time <= time_now_db)).order_by(base_class.data_time).all()
return result
def get_attribute_value_by_interval(self,attribute_fqname: str, start_time: datetime, stop_time: datetime):
'''
Takes as input the attribute name and a certain starting and ending point-time.
The datetime format is pretty flexible (e.g. "YYYY-MM-dd hh:mm:ss").
Returns a list of timestamps and a list of values
'''
attr_id = self.get_attribute_id(attribute_fqname)
attr_datatype = self.get_attribute_datatype(attribute_fqname)
attr_table_name = 'att_'+str(attr_datatype)
# Retrieves the class that maps the DB table given the tablename
base_class = get_class_by_tablename(attr_table_name)
result = self.session.query(base_class).\
join(Attribute,Attribute.att_conf_id==base_class.att_conf_id).\
filter(and_(Attribute.att_conf_id == attr_id,base_class.data_time >= str(start_time), \
base_class.data_time <= str(stop_time))).order_by(base_class.data_time).all()
return result
#! /usr/bin/env python3
from sqlalchemy.dialects.mysql.types import INTEGER
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.dialects.mysql import DOUBLE,TIMESTAMP,BLOB, FLOAT, BIGINT
from sqlalchemy.sql.expression import table
from typing import List
from itertools import groupby
import numpy as np
#Declarative system used to define classes mapped to relational DB tables
Base = declarative_base()
class Attribute(Base):
"""
Class that represents a Tango Attribute mapped to table 'att_conf'
"""
__tablename__ = 'att_conf'
__table_args__ = {'extend_existing': True}
att_conf_id = Column(Integer, primary_key=True)
att_name = Column(String)
att_conf_data_type_id = Column(Integer)
att_ttl = Column(Integer)
facility = Column(String)
domain = Column(String)
family = Column(String)
member = Column(String)
name = Column(String)
def __repr__(self):
return "<Attribute(fullname='%s',data_type ='%s',ttl='%s',facility ='%s',domain ='%s',family ='%s',member ='%s',name ='%s')>" \
% (self.att_name,self.att_conf_data_type_id,self.att_ttl,self.facility,self.domain,self.family,self.member,self.name)
class DataType(Base):
"""
Class that represents a Tango Data Type mapped to table 'att_conf_data_type'
"""
__tablename__ = 'att_conf_data_type'
__table_args__ = {'extend_existing': True}
att_conf_data_type_id = Column(Integer, primary_key=True)
data_type = Column(String)
def __repr__(self):
return "<DataType(type='%s')>" \
% (self.data_type)
class Scalar(Base):
"""
Abstract class that represents Super-class of Scalar mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
# Primary key is not defined for tables which store values, but SQLAlchemy requires a mandatory
# primary key definition. Anyway, this definition is on Python-side and does not compromise
# DBMS architecture
att_conf_id = Column(Integer, primary_key=True)
data_time = Column(TIMESTAMP)
recv_time = Column(TIMESTAMP)
insert_time = Column(TIMESTAMP, primary_key=True)
quality = Column(Integer)
att_error_desc_id = Column(Integer)
class Scalar_Boolean(Scalar):
"""
Abstract class that represents Parent class of Scalar Boolean mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Scalar_Boolean_RO(Scalar_Boolean):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devdouble_ro'
"""
__tablename__ = 'att_scalar_devboolean_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Boolean_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Boolean_RW(Scalar_Boolean):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devdouble_rw'
"""
__tablename__ = 'att_scalar_devboolean_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(Integer)
def __repr__(self):
return "<Scalar_Boolean_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Double(Scalar):
"""
Abstract class that represents Parent class of Scalar Double mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(DOUBLE)
class Scalar_Double_RO(Scalar_Double):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devdouble_ro'
"""
__tablename__ = 'att_scalar_devdouble_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Double_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Double_RW(Scalar_Double):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devdouble_rw'
"""
__tablename__ = 'att_scalar_devdouble_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(DOUBLE)
def __repr__(self):
return "<Scalar_Double_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Encoded(Scalar):
"""
Abstract class that represents Parent class of Scalar Encoded mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(BLOB)
class Scalar_Encoded_RO(Scalar_Encoded):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devencoded_ro'
"""
__tablename__ = 'att_scalar_devencoded_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Encoded_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Encoded_RW(Scalar_Encoded):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devencoded_rw'
"""
__tablename__ = 'att_scalar_devencoded_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(BLOB)
def __repr__(self):
return "<Scalar_Encoded_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Enum(Scalar):
"""
Abstract class that represents Parent class of Scalar Enum mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Scalar_Enum_RO(Scalar_Enum):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devenum_ro'
"""
__tablename__ = 'att_scalar_devenum_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Enum_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Enum_RW(Scalar_Enum):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devenum_rw'
"""
__tablename__ = 'att_scalar_devenum_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(Integer)
def __repr__(self):
return "<Scalar_Enum_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Float(Scalar):
"""
Abstract class that represents Parent class of Scalar Float mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(FLOAT)
class Scalar_Float_RO(Scalar_Float):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devfloat_ro'
"""
__tablename__ = 'att_scalar_devfloat_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Float_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Float_RW(Scalar_Float):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devfloat_rw'
"""
__tablename__ = 'att_scalar_devfloat_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(FLOAT)
def __repr__(self):
return "<Scalar_Float_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Long64(Scalar):
"""
Abstract class that represents Parent class of Scalar Long64 mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(BIGINT)
class Scalar_Long64_RO(Scalar_Long64):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devlong64_ro'
"""
__tablename__ = 'att_scalar_devlong64_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Long64_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Long64_RW(Scalar_Long64):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devlong64_rw'
"""
__tablename__ = 'att_scalar_devlong64_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(BIGINT)
def __repr__(self):
return "<Scalar_Long64_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Long(Scalar):
"""
Abstract class that represents Parent class of Scalar Long mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(INTEGER)
class Scalar_Long_RO(Scalar_Long):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devlong_ro'
"""
__tablename__ = 'att_scalar_devlong_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Long_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Long_RW(Scalar_Long):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devlong_rw'
"""
__tablename__ = 'att_scalar_devlong_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(INTEGER)
def __repr__(self):
return "<Scalar_Long_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_Short(Scalar):
"""
Abstract class that represents Parent class of Scalar Short mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Scalar_Short_RO(Scalar_Short):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devshort_ro'
"""
__tablename__ = 'att_scalar_devshort_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_Short_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_Short_RW(Scalar_Short):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devshort_rw'
"""
__tablename__ = 'att_scalar_devshort_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(Integer)
def __repr__(self):
return "<Scalar_Short_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_State(Scalar):
"""
Abstract class that represents Parent class of Scalar State mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Scalar_State_RO(Scalar_State):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devstate_ro'
"""
__tablename__ = 'att_scalar_devstate_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_State_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_State_RW(Scalar_State):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devstate_rw'
"""
__tablename__ = 'att_scalar_devstate_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(Integer)
def __repr__(self):
return "<Scalar_State_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Scalar_String(Scalar):
"""
Abstract class that represents Parent class of Scalar String mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(String)
class Scalar_String_RO(Scalar_String):
"""
Class that represents a Tango Scalar Read-Only Value mapped to table 'att_scalar_devstring_ro'
"""
__tablename__ = 'att_scalar_devstring_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Scalar_String_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.quality,self.att_error_desc_id)
class Scalar_String_RW(Scalar_String):
"""
Class that represents a Tango Scalar Read-Write Value mapped to table 'att_scalar_devstring_rw'
"""
__tablename__ = 'att_scalar_devstring_rw'
__table_args__ = {'extend_existing': True}
value_w = Column(String)
def __repr__(self):
return "<Scalar_String_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',value_r='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.value_r,self.value_w,self.quality,self.att_error_desc_id)
class Array(Base):
"""
Abstract class that represents Super-class of Array mapper classes
"""
__abstract__ = True
# Primary key is not defined for tables which store values, but SQLAlchemy requires a mandatory
# primary key definition. Anyway, this definition is on Python-side and does not compromise
# DBMS architecture
att_conf_id = Column(Integer, primary_key=True)
data_time = Column(TIMESTAMP)
recv_time = Column(TIMESTAMP)
insert_time = Column(TIMESTAMP, primary_key=True)
idx = Column(Integer, primary_key=True)
dim_x_r = Column(Integer)
dim_y_r = Column(Integer)
quality = Column(Integer)
att_error_desc_id = Column(Integer)
class Array_Boolean(Array):
"""
Abstract class that represents Parent class of Array Boolean mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Array_Boolean_RO(Array_Boolean):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devboolean_ro'
"""
__tablename__ = 'att_array_devboolean_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Boolean_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Boolean_RW(Array_Boolean):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devboolean_rw'
"""
__tablename__ = 'att_array_devboolean_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(Integer)
def __repr__(self):
return "<Array_Boolean_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Double(Array):
"""
Abstract class that represents Parent class of Array Double mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(DOUBLE)
class Array_Double_RO(Array_Double):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devdouble_ro'
"""
__tablename__ = 'att_array_devdouble_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Double_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Double_RW(Array_Double):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devdouble_rw'
"""
__tablename__ = 'att_array_devdouble_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(DOUBLE)
def __repr__(self):
return "<Array_Double_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Encoded(Array):
"""
Abstract class that represents Parent class of Array Encoded mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(BLOB)
class Array_Encoded_RO(Array_Encoded):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devencoded_ro'
"""
__tablename__ = 'att_array_devencoded_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Encoded_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Encoded_RW(Array_Encoded):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devencoded_rw'
"""
__tablename__ = 'att_array_devencoded_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(BLOB)
def __repr__(self):
return "<Array_Encoded_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Enum(Array):
"""
Abstract class that represents Parent class of Array Enum mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Array_Enum_RO(Array_Enum):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devenum_ro'
"""
__tablename__ = 'att_array_devenum_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Enum_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Enum_RW(Array_Enum):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devenum_rw'
"""
__tablename__ = 'att_array_devenum_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(Integer)
def __repr__(self):
return "<Array_Enum_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Float(Array):
"""
Abstract class that represents Parent class of Array Float mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(FLOAT)
class Array_Float_RO(Array_Float):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devfloat_ro'
"""
__tablename__ = 'att_array_devfloat_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Float_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Float_RW(Array_Float):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devfloat_rw'
"""
__tablename__ = 'att_array_devfloat_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(FLOAT)
def __repr__(self):
return "<Array_Float_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Long64(Array):
"""
Abstract class that represents Parent class of Array Long64 mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(BIGINT)
class Array_Long64_RO(Array_Long64):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devlong64_ro'
"""
__tablename__ = 'att_array_devlong64_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Long64_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Long64_RW(Array_Long64):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devlong64_rw'
"""
__tablename__ = 'att_array_devlong64_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(BIGINT)
def __repr__(self):
return "<Array_Long64_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Long(Array):
"""
Abstract class that represents Parent class of Array Long mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(INTEGER)
class Array_Long_RO(Array_Long):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devlong_ro'
"""
__tablename__ = 'att_array_devlong_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Long_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Long_RW(Array_Long):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devlong_rw'
"""
__tablename__ = 'att_array_devlong_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(INTEGER)
def __repr__(self):
return "<Array_Long_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_Short(Array):
"""
Abstract class that represents Parent class of Array Short mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Array_Short_RO(Array_Short):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devshort_ro'
"""
__tablename__ = 'att_array_devshort_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_Short_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_Short_RW(Array_Short):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devshort_rw'
"""
__tablename__ = 'att_array_devshort_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(Integer)
def __repr__(self):
return "<Array_Short_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_State(Array):
"""
Abstract class that represents Parent class of Array State mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(Integer)
class Array_State_RO(Array_State):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devstate_ro'
"""
__tablename__ = 'att_array_devstate_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_State_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_State_RW(Array_State):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devstate_rw'
"""
__tablename__ = 'att_array_devstate_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(Integer)
def __repr__(self):
return "<Array_State_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
class Array_String(Array):
"""
Abstract class that represents Parent class of Array String mapper classes
"""
# In the concrete inheritance use case, it is common that the base class is not represented
# within the database, only the subclasses. In other words, the base class is abstract.
__abstract__ = True
value_r = Column(String)
class Array_String_RO(Array_String):
"""
Class that represents a Tango Array Read-Only Value mapped to table 'att_array_devstring_ro'
"""
__tablename__ = 'att_array_devstring_ro'
__table_args__ = {'extend_existing': True}
def __repr__(self):
return "<Array_String_RO(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.quality,self.att_error_desc_id)
class Array_String_RW(Array_String):
"""
Class that represents a Tango Array Read-Write Value mapped to table 'att_array_devstring_rw'
"""
__tablename__ = 'att_array_devstring_rw'
__table_args__ = {'extend_existing': True}
dim_x_w = Column(Integer)
dim_y_w = Column(Integer)
value_w = Column(String)
def __repr__(self):
return "<Array_String_RW(att_conf_id='%s',data_time='%s',recv_time='%s',insert_time='%s',idx='%s',dim_x_r='%s',dim_y_r='%s',value_r='%s',dim_x_w='%s',dim_y_w='%s',value_w='%s',quality='%s',att_error_desc_id='%s')>" \
% (self.att_conf_id,self.data_time,self.recv_time,self.insert_time,self.idx,self.dim_x_r,self.dim_y_r,self.value_r,self.dim_x_w,self.dim_y_w,self.value_w,self.quality,self.att_error_desc_id)
def get_class_by_tablename(tablename: str):
"""
Returns class reference mapped to a table.
"""
for mapper in Base.registry.mappers:
c = mapper.class_
classname = c.__name__
if not classname.startswith('_'):
if hasattr(c, '__tablename__') and c.__tablename__ == tablename:
return c
return None
def build_array_from_record(rows: List[Array], dim_x: int):
"""
Converts Array database items in Python lists
"""
matrix = np.array([])
for i in range(0,dim_x):
x = np.array([item for item in rows if item.idx==i]) #group records by array index
if i==0:
matrix = np.append(matrix,x) #append first row
else:
matrix = np.vstack([matrix,x]) #stack vertically
result = np.transpose(matrix) #transpose -> each row is a distinct array of value
list_result = result.tolist()
return list_result
def get_values_from_record(data_matrix: List[Array]):
"""
Returns a matrix of values from a matrix of Array records
"""
array_matrix = np.matrix(data_matrix)
value_matrix = np.empty(array_matrix.shape)
for index in range(array_matrix.size): # for each object element
value_matrix.itemset(index,array_matrix.item(index).value_r) # extract the value from object and put in the matrix
return value_matrix
...@@ -4,3 +4,5 @@ opcua >= 0.98.13 ...@@ -4,3 +4,5 @@ opcua >= 0.98.13
astropy astropy
python-logstash-async python-logstash-async
gitpython gitpython
PyMySQL[rsa]
sqlalchemy
...@@ -25,6 +25,9 @@ COPY jupyter-kernels /usr/local/share/jupyter/kernels/ ...@@ -25,6 +25,9 @@ COPY jupyter-kernels /usr/local/share/jupyter/kernels/
RUN sudo pip3 install python-logstash-async RUN sudo pip3 install python-logstash-async
COPY jupyter-notebook /usr/local/bin/jupyter-notebook COPY jupyter-notebook /usr/local/bin/jupyter-notebook
#Install further python modules
RUN sudo pip3 install PyMySQL[rsa] sqlalchemy
# Add Tini. Tini operates as a process subreaper for jupyter. This prevents kernel crashes. # Add Tini. Tini operates as a process subreaper for jupyter. This prevents kernel crashes.
ENV TINI_VERSION v0.6.0 ENV TINI_VERSION v0.6.0
ENV JUPYTER_RUNTIME_DIR=/tmp ENV JUPYTER_RUNTIME_DIR=/tmp
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment