Skip to content
Snippets Groups Projects
Commit c24173a9 authored by Thomas Juerges's avatar Thomas Juerges
Browse files

Merge branch 'master' into 2021-03-22T14.42.30-branched_from_master-Makefile_refactoring

parents 24e9db5b f8d7c664
No related branches found
No related tags found
1 merge request!21Small refactoring of the Makefile
This commit is part of merge request !21. Comments created here will be created in the context of that merge request.
...@@ -19,17 +19,36 @@ ...@@ -19,17 +19,36 @@
"LTS/SDP/1": { "LTS/SDP/1": {
"properties": { "properties": {
"OPC_Server_Name": [ "OPC_Server_Name": [
"DESPi2.astron.nl" "dop36.astron.nl"
] ]
} }
} }
} }
} }
}, },
"example_device": { "APSCTL": {
"1": { "1": {
"example_device": { "APSCTL": {
"LTS/example_device/1": { "LTS/APSCTL/1": {
"properties": {
"OPC_Server_Name": [
"ltspi.astron.nl"
],
"OPC_Server_Port": [
"4844"
],
"OPC_Time_Out": [
"5.0"
]
}
}
}
}
},
"test_device": {
"1": {
"test_device": {
"LTS/test_device/1": {
"attribute_properties": { "attribute_properties": {
"Ant_mask_RW": { "Ant_mask_RW": {
"archive_period": [ "archive_period": [
......
...@@ -26,10 +26,62 @@ ...@@ -26,10 +26,62 @@
} }
} }
}, },
"example_device": { "ini_device": {
"1": { "1": {
"example_device": { "ini_device": {
"LTS/example_device/1": { "LTS/ini_device/1": {
"attribute_properties": {
"Ant_mask_RW": {
"archive_period": [
"600000"
]
}
},
"properties": {
"SNMP_community": [
"public"
],
"SNMP_host": [
"172.22.176.1"
],
"SNMP_timeout": [
"5.0"
]
}
}
}
}
},
"SNMP": {
"1": {
"SNMP": {
"LTS/SNMP/1": {
"attribute_properties": {
"Ant_mask_RW": {
"archive_period": [
"600000"
]
}
},
"properties": {
"SNMP_community": [
"public"
],
"SNMP_host": [
"172.22.176.1"
],
"SNMP_timeout": [
"5.0"
]
}
}
}
}
},
"test_device": {
"1": {
"test_device": {
"LTS/test_device/1": {
"attribute_properties": { "attribute_properties": {
"Ant_mask_RW": { "Ant_mask_RW": {
"archive_period": [ "archive_period": [
......
devices/APSCTL.py 0 → 100644
+ 187
0
View file @ c24173a9
# -*- coding: utf-8 -*-
#
# This file is part of the SDP project
#
#
#
# Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info.
""" SDP Device Server for LOFAR2.0
"""
# PyTango imports
from tango.server import run
from tango.server import device_property
from tango import AttrWriteType
#attribute extention and hardware device imports
from src.attribute_wrapper import attribute_wrapper
from src.hardware_device import hardware_device
import numpy
# Additional import
from clients.opcua_connection import OPCUAConnection
__all__ = ["APSCTL", "main"]
class APSCTL(hardware_device):
"""
**Properties:**
- Device Property
OPC_Server_Name
- Type:'DevString'
OPC_Server_Port
- Type:'DevULong'
OPC_Time_Out
- Type:'DevDouble'
"""
# -----------------
# Device Properties
# -----------------
OPC_Server_Name = device_property(
dtype='DevString',
mandatory=True
)
OPC_Server_Port = device_property(
dtype='DevULong',
mandatory=True
)
OPC_Time_Out = device_property(
dtype='DevDouble',
mandatory=True
)
# ----------
# Attributes
# ----------
N_unb = 2
N_fpga = 4
N_ddr = 2
N_qsfp = 6
# Central CP per Uniboard
UNB2_Power_ON_OFF_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_Power_ON_OFF_RW"], datatype=numpy.bool_, dims=(N_unb,), access=AttrWriteType.READ_WRITE)
UNB2_Front_Panel_LED_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_Front_Panel_LED_RW"], datatype=numpy.uint8, dims=(N_unb,), access=AttrWriteType.READ_WRITE)
UNB2_Mask_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_Mask_RW"], datatype=numpy.bool_, dims=(N_unb,), access=AttrWriteType.READ_WRITE)
# Central MP per Uniboard
UNB2_I2C_bus_OK_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_I2C_bus_OK_R"], datatype=numpy.bool_, dims=(N_unb,))
UNB2_Front_Panel_LED_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_Front_Panel_LED_R"], datatype=numpy.uint8, dims=(N_unb,))
UNB2_EEPROM_Serial_Number_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_EEPROM_Serial_Number_R"], datatype=numpy.str, dims=(N_unb,))
UNB2_EEPROM_Unique_ID_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_EEPROM_Unique_ID_R"], datatype=numpy.uint32, dims=(N_unb,))
UNB2_DC_DC_48V_12V_VIN_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_DC_DC_48V_12V_VIN_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_DC_DC_48V_12V_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_DC_DC_48V_12V_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_DC_DC_48V_12V_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_DC_DC_48V_12V_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_DC_DC_48V_12V_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_DC_DC_48V_12V_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N01_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N01_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N01_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N01_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N01_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N01_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N23_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N23_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N23_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N23_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_QSFP_N23_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_QSFP_N23_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_1V2_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_1V2_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_1V2_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_1V2_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_1V2_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_1V2_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_PHY_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_PHY_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_PHY_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_PHY_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_SWITCH_PHY_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_SWITCH_PHY_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_CLOCK_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_CLOCK_VOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_CLOCK_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_CLOCK_IOUT_R"], datatype=numpy.double, dims=(N_unb,))
UNB2_POL_CLOCK_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_POL_CLOCK_TEMP_R"], datatype=numpy.double, dims=(N_unb,))
# monitor points per FPGA
UNB2_FPGA_DDR4_SLOT_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_DDR4_SLOT_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_DDR4_SLOT_PART_NUMBER_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_DDR4_SLOT_PART_NUMBER_R"], datatype=numpy.str, dims=(N_unb * N_qsfp,N_fpga))
UNB2_FPGA_QSFP_CAGE_0_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_0_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_1_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_1_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_2_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_2_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_3_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_3_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_4_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_4_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_5_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_5_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_0_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_0_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_1_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_1_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_2_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_2_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_3_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_3_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_4_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_4_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_QSFP_CAGE_5_LOS_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_QSFP_CAGE_5_LOS_R"], datatype=numpy.uint8, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_CORE_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_CORE_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_CORE_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_CORE_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_CORE_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_CORE_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_ERAM_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_ERAM_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_ERAM_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_ERAM_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_ERAM_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_ERAM_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_RXGXB_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_RXGXB_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_RXGXB_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_RXGXB_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_RXGXB_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_RXGXB_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_TXGXB_VOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_TXGXB_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_TXGXB_IOUT_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_TXGXB_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_TXGXB_TEMP_R = attribute_wrapper(comms_annotation=["2:PCC", "2:UNB2_FPGA_POL_TXGXB_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_HGXB_VOUT_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_HGXB_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_HGXB_IOUT_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_HGXB_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_HGXB_TEMP_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_HGXB_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_PGM_VOUT_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_PGM_VOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_PGM_IOUT_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_PGM_IOUT_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
UNB2_FPGA_POL_PGM_TEMP_R = attribute_wrapper(comms_annotation=["2:UNB2_FPGA_POL_PGM_TEMP_R"], datatype=numpy.double, dims=(N_unb,N_fpga))
def delete_device(self):
"""Hook to delete resources allocated in init_device.
This method allows for any memory or other resources allocated in the
init_device method to be released. This method is called by the device
destructor and by the device Init command (a Tango built-in).
"""
self.debug_stream("Shutting down...")
self.Off()
self.debug_stream("Shut down. Good bye.")
# --------
# overloaded functions
# --------
def off(self):
""" user code here. is called when the state is set to OFF """
# Stop keep-alive
self.opcua_connection.stop()
def initialise(self):
""" user code here. is called when the sate is set to INIT """
"""Initialises the attributes and properties of the PCC."""
# set up the OPC ua client
self.OPCua_client = OPCUAConnection("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), "http://lofar.eu", self.OPC_Time_Out, self.Fault, self)
# map an access helper class
for i in self.attr_list():
try:
i.set_comm_client(self.OPCua_client)
except:
self.debug_stream("error in getting APSCTL attribute: {} from client".format(i))
self.OPCua_client.start()
# --------
# Commands
# --------
# ----------
# Run server
# ----------
def main(args=None, **kwargs):
"""Main function of the SDP module."""
return run((APSCTL,), args=args, **kwargs)
if __name__ == '__main__':
main()
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# This file is part of the PCC project # This file wraps around a tango device class and provides a number of abstractions useful for hardware devices. It works together
#
#
# #
# Distributed under the terms of the APACHE license. # Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info. # See LICENSE.txt for more info.
""" Hardware Device Server for LOFAR2.0 """
""" """
# PyTango imports # PyTango imports
from tango.server import run from tango.server import run
from tango import AttrWriteType
# Additional import # Additional import
from src.hardware_device import * from src.attribute_wrapper import attribute_wrapper
from src.hardware_device import hardware_device
__all__ = ["HW_dev"] __all__ = ["HW_dev"]
class HW_dev(hardware_device): class HW_dev(hardware_device):
""" """
This class is the minimal (read empty) implementation of a class using 'hardware_device' This class is the minimal (read empty) implementation of a class using 'hardware_device'
...@@ -29,7 +29,7 @@ class HW_dev(hardware_device): ...@@ -29,7 +29,7 @@ class HW_dev(hardware_device):
# Attributes # Attributes
# ---------- # ----------
""" """
attribute wrapper objects can be declared here. All attribute wrapper objects will get automatically put in a ist (attr_list) for easy access attribute wrapper objects can be declared here. All attribute wrapper objects will get automatically put in a list (attr_list) for easy access
example = attribute_wrapper(comms_annotation="this is an example", datatype=numpy.double, dims=(8, 2), access=AttrWriteType.READ_WRITE) example = attribute_wrapper(comms_annotation="this is an example", datatype=numpy.double, dims=(8, 2), access=AttrWriteType.READ_WRITE)
... ...
...@@ -76,6 +76,7 @@ class HW_dev(hardware_device): ...@@ -76,6 +76,7 @@ class HW_dev(hardware_device):
""" user code here. is called when the sate is set to INIT """ """ user code here. is called when the sate is set to INIT """
pass pass
# ---------- # ----------
# Run server # Run server
# ---------- # ----------
...@@ -86,4 +87,3 @@ def main(args=None, **kwargs): ...@@ -86,4 +87,3 @@ def main(args=None, **kwargs):
if __name__ == '__main__': if __name__ == '__main__':
main() main()
...@@ -15,21 +15,38 @@ ...@@ -15,21 +15,38 @@
from tango import DebugIt from tango import DebugIt
from tango.server import run, command from tango.server import run, command
from tango.server import device_property from tango.server import device_property
from tango import AttrWriteType
import numpy
# Additional import # Additional import
from src.wrappers import *
from clients.opcua_connection import OPCUAConnection from clients.opcua_connection import OPCUAConnection
from src.attribute_wrapper import * from src.attribute_wrapper import attribute_wrapper
from src.hardware_device import * from src.hardware_device import hardware_device
from src.lofar_logging import device_logging_to_python from src.lofar_logging import device_logging_to_python
__all__ = ["PCC", "main"] __all__ = ["PCC", "main"]
@device_logging_to_python({"device": "PCC"}) @device_logging_to_python({"device": "PCC"})
class PCC(hardware_device): class PCC(hardware_device):
"""
**Properties:**
- Device Property
OPC_Server_Name
- Type:'DevString'
OPC_Server_Port
- Type:'DevULong'
OPC_Time_Out
- Type:'DevDouble'
"""
# ----------------- # -----------------
# Device Properties # Device Properties
# ----------------- # -----------------
OPC_Server_Name = device_property( OPC_Server_Name = device_property(
dtype='DevString', dtype='DevString',
mandatory=True mandatory=True
...@@ -44,8 +61,7 @@ class PCC(hardware_device): ...@@ -44,8 +61,7 @@ class PCC(hardware_device):
dtype='DevDouble', dtype='DevDouble',
mandatory=True mandatory=True
) )
OPC_namespace = device_property(
OPC_Namespace = device_property(
dtype='DevString', dtype='DevString',
mandatory=False mandatory=False
) )
...@@ -53,56 +69,36 @@ class PCC(hardware_device): ...@@ -53,56 +69,36 @@ class PCC(hardware_device):
# ---------- # ----------
# Attributes # Attributes
# ---------- # ----------
RCU_state_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_state_R"], datatype=numpy.str_, access=AttrWriteType.READ_WRITE)
RCU_mask_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_mask_RW"], datatype=numpy.bool_, dims=(32,), access=AttrWriteType.READ_WRITE) RCU_mask_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_mask_RW"], datatype=numpy.bool_, dims=(32,), access=AttrWriteType.READ_WRITE)
Ant_mask_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:Ant_mask_RW"], datatype=numpy.bool_, dims=(3, 32), access=AttrWriteType.READ_WRITE) Ant_mask_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:Ant_mask_RW"], datatype=numpy.bool_, dims=(3, 32), access=AttrWriteType.READ_WRITE)
RCU_attenuator_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_attenuator_R"], datatype=numpy.int64, dims=(3, 32)) RCU_attenuator_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_attenuator_R"], datatype=numpy.int64, dims=(3, 32))
RCU_attenuator_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_attenuator_RW"], datatype=numpy.int64, dims=(3, 32),
RCU_attenuator_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_attenuator_RW"], datatype=numpy.int64, dims=(3, 32), access=AttrWriteType.READ_WRITE) access=AttrWriteType.READ_WRITE)
RCU_band_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_band_R"], datatype=numpy.int64, dims=(3, 32)) RCU_band_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_band_R"], datatype=numpy.int64, dims=(3, 32))
RCU_band_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_band_RW"], datatype=numpy.int64, dims=(3, 32), access=AttrWriteType.READ_WRITE) RCU_band_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_band_RW"], datatype=numpy.int64, dims=(3, 32), access=AttrWriteType.READ_WRITE)
RCU_temperature_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_temperature_R"], datatype=numpy.float64, dims=(32,)) RCU_temperature_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_temperature_R"], datatype=numpy.float64, dims=(32,))
RCU_Pwr_dig_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_Pwr_dig_R"], datatype=numpy.int64, dims=(32,)) RCU_Pwr_dig_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_Pwr_dig_R"], datatype=numpy.int64, dims=(32,))
RCU_LED0_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_LED0_R"], datatype=numpy.int64, dims=(32,)) RCU_LED0_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_LED0_R"], datatype=numpy.int64, dims=(32,))
RCU_LED0_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_LED0_RW"], datatype=numpy.int64, dims=(32,), access=AttrWriteType.READ_WRITE) RCU_LED0_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_LED0_RW"], datatype=numpy.int64, dims=(32,), access=AttrWriteType.READ_WRITE)
RCU_ADC_lock_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_lock_R"], datatype=numpy.int64, dims=(3, 32)) RCU_ADC_lock_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_lock_R"], datatype=numpy.int64, dims=(3, 32))
RCU_ADC_SYNC_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_SYNC_R"], datatype=numpy.int64, dims=(3, 32)) RCU_ADC_SYNC_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_SYNC_R"], datatype=numpy.int64, dims=(3, 32))
RCU_ADC_JESD_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_JESD_R"], datatype=numpy.int64, dims=(3, 32)) RCU_ADC_JESD_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_JESD_R"], datatype=numpy.int64, dims=(3, 32))
RCU_ADC_CML_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_CML_R"], datatype=numpy.int64, dims=(3, 32)) RCU_ADC_CML_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ADC_CML_R"], datatype=numpy.int64, dims=(3, 32))
RCU_OUT1_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_OUT1_R"], datatype=numpy.int64, dims=(3, 32)) RCU_OUT1_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_OUT1_R"], datatype=numpy.int64, dims=(3, 32))
RCU_OUT2_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_OUT2_R"], datatype=numpy.int64, dims=(3, 32)) RCU_OUT2_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_OUT2_R"], datatype=numpy.int64, dims=(3, 32))
RCU_ID_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ID_R"], datatype=numpy.int64, dims=(32,)) RCU_ID_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_ID_R"], datatype=numpy.int64, dims=(32,))
RCU_version_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_version_R"], datatype=numpy.str_, dims=(32,)) RCU_version_R = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_version_R"], datatype=numpy.str_, dims=(32,))
HBA_element_beamformer_delays_R = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_beamformer_delays_R"], datatype=numpy.int64, dims=(32, 96)) HBA_element_beamformer_delays_R = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_beamformer_delays_R"], datatype=numpy.int64,
dims=(32, 96))
HBA_element_beamformer_delays_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_beamformer_delays_RW"], datatype=numpy.int64, dims=(32, 96), access=AttrWriteType.READ_WRITE) HBA_element_beamformer_delays_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_beamformer_delays_RW"], datatype=numpy.int64,
dims=(32, 96), access=AttrWriteType.READ_WRITE)
HBA_element_pwr_R = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_pwr_R"], datatype=numpy.int64, dims=(32, 96)) HBA_element_pwr_R = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_pwr_R"], datatype=numpy.int64, dims=(32, 96))
HBA_element_pwr_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_pwr_RW"], datatype=numpy.int64, dims=(32, 96),
access=AttrWriteType.READ_WRITE)
HBA_element_pwr_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:HBA_element_pwr_RW"], datatype=numpy.int64, dims=(32, 96), access=AttrWriteType.READ_WRITE) RCU_monitor_rate_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_monitor_rate_RW"], datatype=numpy.float64,
access=AttrWriteType.READ_WRITE)
uC_ID_R = attribute_wrapper(comms_annotation=["2:PCC", "2:uC_ID_R"], datatype=numpy.int64, dims=(32,))
RCU_monitor_rate_RW = attribute_wrapper(comms_annotation=["2:PCC", "2:RCU_monitor_rate_RW"], datatype=numpy.float64, access=AttrWriteType.READ_WRITE)
def delete_device(self): def delete_device(self):
"""Hook to delete resources allocated in init_device. """Hook to delete resources allocated in init_device.
...@@ -112,6 +108,7 @@ class PCC(hardware_device): ...@@ -112,6 +108,7 @@ class PCC(hardware_device):
destructor and by the device Init command (a Tango built-in). destructor and by the device Init command (a Tango built-in).
""" """
self.debug_stream("Shutting down...") self.debug_stream("Shutting down...")
self.Off() self.Off()
self.debug_stream("Shut down. Good bye.") self.debug_stream("Shut down. Good bye.")
...@@ -120,19 +117,25 @@ class PCC(hardware_device): ...@@ -120,19 +117,25 @@ class PCC(hardware_device):
# -------- # --------
def off(self): def off(self):
""" user code here. is called when the state is set to OFF """ """ user code here. is called when the state is set to OFF """
# Stop keep-alive # Stop keep-alive
self.OPCua_client.disconnect() self.OPCua_client.stop()
def initialise(self): def initialise(self):
""" user code here. is called when the state is set to INIT """ """ user code here. is called when the state is set to INIT """
#set up the OPC ua client # Init the dict that contains function to OPC-UA function mappings.
namespace = "http://lofar.eu" self.function_mapping = {}
if self.OPC_Namespace is not None: self.function_mapping["RCU_on"] = {}
namespace = self.OPC_Namespace self.function_mapping["RCU_off"] = {}
self.function_mapping["ADC_on"] = {}
self.function_mapping["RCU_update"] = {}
self.function_mapping["CLK_on"] = {}
self.function_mapping["CLK_off"] = {}
self.function_mapping["CLK_PLL_setup"] = {}
self.OPCua_client = OPCUAConnection("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), namespace, self.OPC_Time_Out, self.Standby, self.Fault, self) # set up the OPC ua client
self.OPCua_client = OPCUAConnection("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), "http://lofar.eu",
self.OPC_Time_Out, self.Fault, self)
# map the attributes to the OPC ua comm client # map the attributes to the OPC ua comm client
for i in self.attr_list(): for i in self.attr_list():
...@@ -141,16 +144,6 @@ class PCC(hardware_device): ...@@ -141,16 +144,6 @@ class PCC(hardware_device):
except: except:
pass pass
# Init the dict that contains function to OPC-UA function mappings.
self.function_mapping = {}
self.function_mapping["RCU_off"] = self.OPCua_client._setup_annotation(["2:PCC", "2:RCU_off"])
self.function_mapping["RCU_on"] = self.OPCua_client._setup_annotation(["2:PCC", "2:RCU_on"])
self.function_mapping["ADC_on"] = self.OPCua_client._setup_annotation(["2:PCC", "2:ADC_on"])
self.function_mapping["RCU_update"] = self.OPCua_client._setup_annotation(["2:PCC", "2:RCU_update"])
self.function_mapping["CLK_off"] = self.OPCua_client._setup_annotation(["2:PCC", "2:CLK_off"])
self.function_mapping["CLK_on"] = self.OPCua_client._setup_annotation(["2:PCC", "2:CLK_on"])
self.function_mapping["CLK_PLL_setup"] = self.OPCua_client._setup_annotation(["2:PCC", "2:CLK_PLL_setup"])
self.OPCua_client.start() self.OPCua_client.start()
# -------- # --------
...@@ -244,4 +237,3 @@ def main(args=None, **kwargs): ...@@ -244,4 +237,3 @@ def main(args=None, **kwargs):
if __name__ == '__main__': if __name__ == '__main__':
main() main()
...@@ -14,13 +14,16 @@ ...@@ -14,13 +14,16 @@
# PyTango imports # PyTango imports
from tango.server import run from tango.server import run
from tango.server import device_property from tango.server import device_property
from tango import AttrWriteType
# Additional import # Additional import
from clients.opcua_connection import OPCUAConnection from clients.opcua_connection import OPCUAConnection
from src.attribute_wrapper import * from src.attribute_wrapper import attribute_wrapper
from src.hardware_device import * from src.hardware_device import hardware_device
from src.lofar_logging import device_logging_to_python from src.lofar_logging import device_logging_to_python
import numpy
__all__ = ["SDP", "main"] __all__ = ["SDP", "main"]
...@@ -105,10 +108,7 @@ class SDP(hardware_device): ...@@ -105,10 +108,7 @@ class SDP(hardware_device):
"""Initialises the attributes and properties of the PCC.""" """Initialises the attributes and properties of the PCC."""
# set up the OPC ua client # set up the OPC ua client
self.OPCua_client = OPCUAConnection("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), "http://lofar.eu", self.OPC_Time_Out, self.Standby, self.Fault, self) self.OPCua_client = OPCUAConnection("opc.tcp://{}:{}/".format(self.OPC_Server_Name, self.OPC_Server_Port), "http://lofar.eu", self.OPC_Time_Out, self.Fault, self)
# will contain all the values for this object
self.setup_value_dict()
# map an access helper class # map an access helper class
for i in self.attr_list(): for i in self.attr_list():
......
from src.comms_client import * from threading import Thread
import socket
from src.comms_client import CommClient
import numpy
import opcua import opcua
from opcua import Client
__all__ = ["OPCUAConnection"] __all__ = ["OPCUAConnection"]
...@@ -33,13 +37,13 @@ class OPCUAConnection(CommClient): ...@@ -33,13 +37,13 @@ class OPCUAConnection(CommClient):
def start(self): def start(self):
super().start() super().start()
def __init__(self, address, namespace, timeout, on_func, fault_func, streams, try_interval=2): def __init__(self, address, namespace, timeout, fault_func, streams, try_interval=2):
""" """
Create the OPC ua client and connect() to it and get the object node Create the OPC ua client and connect() to it and get the object node
""" """
super().__init__(on_func, fault_func, streams, try_interval) super().__init__(fault_func, streams, try_interval)
self.client = opcua.Client(address, timeout) self.client = Client(address, timeout)
# Explicitly connect # Explicitly connect
if not self.connect(): if not self.connect():
...@@ -77,7 +81,7 @@ class OPCUAConnection(CommClient): ...@@ -77,7 +81,7 @@ class OPCUAConnection(CommClient):
return True return True
except socket.error as e: except socket.error as e:
self.streams.error_stream("Could not connect to server %s: %s", self._servername(), e) self.streams.error_stream("Could not connect to server %s: %s", self._servername(), e)
raise Exception("") from e raise Exception("Could not connect to server %s", self._servername()) from e
def disconnect(self): def disconnect(self):
...@@ -89,19 +93,16 @@ class OPCUAConnection(CommClient): ...@@ -89,19 +93,16 @@ class OPCUAConnection(CommClient):
try: try:
self.client.disconnect() self.client.disconnect()
except Exception as e: except Exception as e:
self.streams.error_stream("Disconnect from OPC-UA server {} failed: {}".format(self._servername(), e)) self.streams.error_stream("Disconnect from OPC-UA server %s failed: %s", self._servername(), e)
def ping(self): def ping(self):
""" """
ping the client to make sure the connection with the client is still functional. ping the client to make sure the connection with the client is still functional.
""" """
try: try:
if self.connected is True:
self.client.send_hello() self.client.send_hello()
else:
self.streams.debug_stream("Will not ping OPC-UA server {} because the connection is inactive.".format(self._servername()))
except Exception as e: except Exception as e:
raise Exception("Lost connection to server {}.".format(self._servername())) from e raise Exception("Lost connection to server %s: %s", self._servername(), e)
def _setup_annotation(self, annotation): def _setup_annotation(self, annotation):
""" """
...@@ -117,12 +118,13 @@ class OPCUAConnection(CommClient): ...@@ -117,12 +118,13 @@ class OPCUAConnection(CommClient):
elif isinstance(annotation, list): elif isinstance(annotation, list):
path = annotation path = annotation
else: else:
raise Exception("OPC-ua mapping requires either a list of the path or dict with the path. Was given {} type containing: {}".format(type(annotation), annotation)) raise Exception("OPC-ua mapping requires either a list of the path or dict with the path. Was given %s type containing: %s", type(annotation), annotation)
try: try:
node = self.obj.get_child(path) node = self.obj.get_child(path)
except Exception as e: except Exception as e:
raise Exception("Could not get node: {} on server {}".format(path, self._servername())) from e self.streams.error_stream("Could not get node: %s on server %s: %s", path, self._servername(), e)
raise Exception("Could not get node: %s on server %s", path, self._servername()) from e
return node return node
......
from src.comms_client import * from src.comms_client import CommClient
import numpy
import os
# <class 'numpy.bool_'> # <class 'numpy.bool_'>
class example_client(CommClient): class test_client(CommClient):
""" """
this class provides an example implementation of a comms_client. this class provides an example implementation of a comms_client.
Durirng initialisation it creates a correctly shaped zero filled value. on read that value is returned and on write its modified. Durirng initialisation it creates a correctly shaped zero filled value. on read that value is returned and on write its modified.
...@@ -11,11 +14,11 @@ class example_client(CommClient): ...@@ -11,11 +14,11 @@ class example_client(CommClient):
def start(self): def start(self):
super().start() super().start()
def __init__(self, standby_func, fault_func, streams, try_interval=2): def __init__(self, fault_func, streams, try_interval=2):
""" """
initialises the class and tries to connect to the client. initialises the class and tries to connect to the client.
""" """
super().__init__(standby_func, fault_func, streams, try_interval) super().__init__(fault_func, streams, try_interval)
# Explicitly connect # Explicitly connect
if not self.connect(): if not self.connect():
...@@ -27,7 +30,6 @@ class example_client(CommClient): ...@@ -27,7 +30,6 @@ class example_client(CommClient):
""" """
this function provides a location for the code neccecary to connect to the client this function provides a location for the code neccecary to connect to the client
""" """
self.streams.debug_stream("the example client doesn't actually connect to anything silly") self.streams.debug_stream("the example client doesn't actually connect to anything silly")
self.connected = True # set connected to true self.connected = True # set connected to true
...@@ -45,7 +47,9 @@ class example_client(CommClient): ...@@ -45,7 +47,9 @@ class example_client(CommClient):
the annotation can be in whatever format may be required. it is up to the user to handle its content the annotation can be in whatever format may be required. it is up to the user to handle its content
example annotation may include: example annotation may include:
- a file path and file line/location - a file path and file line/location
- COM object path - server address
- IDs
- data structures
""" """
# as this is an example, just print the annotation # as this is an example, just print the annotation
...@@ -66,7 +70,6 @@ class example_client(CommClient): ...@@ -66,7 +70,6 @@ class example_client(CommClient):
return dims, dtype return dims, dtype
def _setup_mapping(self, dims, dtype): def _setup_mapping(self, dims, dtype):
""" """
takes all gathered data to configure and return the correct read and write functions takes all gathered data to configure and return the correct read and write functions
...@@ -85,7 +88,6 @@ class example_client(CommClient): ...@@ -85,7 +88,6 @@ class example_client(CommClient):
self.streams.debug_stream("created and bound example_client read/write functions to attribute_wrapper object") self.streams.debug_stream("created and bound example_client read/write functions to attribute_wrapper object")
return read_function, write_function return read_function, write_function
def setup_attribute(self, annotation=None, attribute=None): def setup_attribute(self, annotation=None, attribute=None):
""" """
MANDATORY function: is used by the attribute wrapper to get read/write functions. MANDATORY function: is used by the attribute wrapper to get read/write functions.
...@@ -103,4 +105,3 @@ class example_client(CommClient): ...@@ -103,4 +105,3 @@ class example_client(CommClient):
# return the read/write functions # return the read/write functions
return read_function, write_function return read_function, write_function
...@@ -5,6 +5,7 @@ import numpy ...@@ -5,6 +5,7 @@ import numpy
from src.wrappers import only_when_on, fault_on_error from src.wrappers import only_when_on, fault_on_error
import logging import logging
logger = logging.getLogger() logger = logging.getLogger()
...@@ -17,14 +18,17 @@ class attribute_wrapper(attribute): ...@@ -17,14 +18,17 @@ class attribute_wrapper(attribute):
""" """
wraps around the tango Attribute class. Provides an easier interface for 1d or 2d arrays. Also provides a way to abstract wraps around the tango Attribute class. Provides an easier interface for 1d or 2d arrays. Also provides a way to abstract
managing the communications interface. managing the communications interface.
comms_annotation: data passed along to the attribute. can be given any form of data. handling is up to client implementation
datatype: any numpy datatype
dims: dimensions of the
init_value: value
""" """
# ensure the type is a numpy array # ensure the type is a numpy array
if "numpy" not in str(datatype) and type(datatype) != str: if "numpy" not in str(datatype) and datatype != str:
raise TypeError("Attribute needs to be a Tango-supported numpy or str type, but has type \"%s\"" % (datatype,)) raise TypeError("Attribute needs to be a Tango-supported numpy or str type, but has type \"%s\"" % (datatype,))
self.comms_annotation = comms_annotation # store data that can be used by the comms interface. not used by the wrapper itself self.comms_annotation = comms_annotation # store data that can be used by the comms interface. not used by the wrapper itself
self.numpy_type = datatype # tango changes our attribute to their representation (E.g numpy.int64 becomes "DevLong64") self.numpy_type = datatype # tango changes our attribute to their representation (E.g numpy.int64 becomes "DevLong64")
...@@ -54,7 +58,6 @@ class attribute_wrapper(attribute): ...@@ -54,7 +58,6 @@ class attribute_wrapper(attribute):
# scalar, just set the single dimension # scalar, just set the single dimension
max_dim_x = 1 max_dim_x = 1
if access == AttrWriteType.READ_WRITE: if access == AttrWriteType.READ_WRITE:
""" if the attribute is of READ_WRITE type, assign the RW and write function to it""" """ if the attribute is of READ_WRITE type, assign the RW and write function to it"""
...@@ -68,8 +71,8 @@ class attribute_wrapper(attribute): ...@@ -68,8 +71,8 @@ class attribute_wrapper(attribute):
try: try:
return device.value_dict[self] return device.value_dict[self]
except Exception as e: except Exception as e:
raise Exception("Attribute read_RW function error, attempted to read value_dict with key: `%s`, are you sure this exists?", self) from e raise Exception("Attribute read_RW function error, attempted to read value_dict with key: `%s`, are you sure this exists?",
self) from e
@only_when_on @only_when_on
@fault_on_error @fault_on_error
...@@ -77,6 +80,7 @@ class attribute_wrapper(attribute): ...@@ -77,6 +80,7 @@ class attribute_wrapper(attribute):
""" """
_write_RW writes a value to this attribute _write_RW writes a value to this attribute
""" """
self.write_function(value) self.write_function(value)
device.value_dict[self] = value device.value_dict[self] = value
...@@ -133,7 +137,8 @@ class attribute_wrapper(attribute): ...@@ -133,7 +137,8 @@ class attribute_wrapper(attribute):
except Exception as e: except Exception as e:
def pass_func(value=None): def pass_func(value=None):
pass pass
logger.error("setting comm_client failed. using pass function instead")
logger.error("Exception while setting %s attribute with annotation: '%s' read/write functions. using pass function instead to to keep running", client.__class__.__name__, self.comms_annotation)
self.read_function = pass_func self.read_function = pass_func
self.write_function = pass_func self.write_function = pass_func
......
from threading import Thread from threading import Thread
import socket
import time import time
import numpy
from tango import DevState
class CommClient(Thread): class CommClient(Thread):
""" """
The ProtocolHandler class is the generic interface class between the tango attribute_wrapper and the outside world The ProtocolHandler class is the generic interface class between the tango attribute_wrapper and the outside world
""" """
def __init__(self, standby_func, fault_func, streams, try_interval=2): def __init__(self, fault_func, streams, try_interval=2):
""" """
""" """
self.standby_func = standby_func
self.fault_func = fault_func self.fault_func = fault_func
self.try_interval = try_interval self.try_interval = try_interval
self.streams = streams self.streams = streams
...@@ -45,14 +39,12 @@ class CommClient(Thread): ...@@ -45,14 +39,12 @@ class CommClient(Thread):
self.fault_func() self.fault_func()
return return
self.standby_func()
self.stopping = False self.stopping = False
while not self.stopping: while not self.stopping:
# keep trying to connect # keep trying to connect
if not self.connected: if not self.connected:
if self.connect(): if self.connect():
self.standby_func() pass
else: else:
# we retry only once, to catch exotic network issues. if the infra or hardware is down, # we retry only once, to catch exotic network issues. if the infra or hardware is down,
# our device cannot help, and must be reinitialised after the infra or hardware is fixed. # our device cannot help, and must be reinitialised after the infra or hardware is fixed.
...@@ -74,7 +66,7 @@ class CommClient(Thread): ...@@ -74,7 +66,7 @@ class CommClient(Thread):
self.fault_func() self.fault_func()
def ping(self): def ping(self):
pass return
def stop(self): def stop(self):
""" """
......
...@@ -16,15 +16,14 @@ from tango.server import Device, command ...@@ -16,15 +16,14 @@ from tango.server import Device, command
from tango import DevState, DebugIt from tango import DevState, DebugIt
# Additional import # Additional import
from src.attribute_wrapper import * from src.attribute_wrapper import attribute_wrapper
from src.lofar_logging import log_exceptions from src.lofar_logging import log_exceptions
__all__ = ["hardware_device"] __all__ = ["hardware_device"]
from src.wrappers import only_in_states from src.wrappers import only_in_states
#@log_exceptions()
class hardware_device(Device): class hardware_device(Device):
""" """
...@@ -60,7 +59,6 @@ class hardware_device(Device): ...@@ -60,7 +59,6 @@ class hardware_device(Device):
self.value_dict = {i: i.initial_value() for i in self.attr_list()} self.value_dict = {i: i.initial_value() for i in self.attr_list()}
@log_exceptions()
def init_device(self): def init_device(self):
""" Instantiates the device in the OFF state. """ """ Instantiates the device in the OFF state. """
...@@ -84,19 +82,9 @@ class hardware_device(Device): ...@@ -84,19 +82,9 @@ class hardware_device(Device):
""" """
self.set_state(DevState.INIT) self.set_state(DevState.INIT)
self.setup_value_dict() self.setup_value_dict()
self.initialise()
self.standby()
self.set_state(DevState.STANDBY)
@only_in_states([DevState.INIT]) self.initialise()
def Standby(self):
"""
Command to ask for initialisation of this device. Can only be called in FAULT or OFF state.
:return:None
"""
self.standby()
self.set_state(DevState.STANDBY) self.set_state(DevState.STANDBY)
@command() @command()
...@@ -155,8 +143,6 @@ class hardware_device(Device): ...@@ -155,8 +143,6 @@ class hardware_device(Device):
pass pass
def on(self): def on(self):
pass pass
def standby(self):
pass
def initialise(self): def initialise(self):
pass pass
...@@ -164,7 +150,6 @@ class hardware_device(Device): ...@@ -164,7 +150,6 @@ class hardware_device(Device):
"""Method always executed before any TANGO command is executed.""" """Method always executed before any TANGO command is executed."""
pass pass
@log_exceptions()
def delete_device(self): def delete_device(self):
"""Hook to delete resources allocated in init_device. """Hook to delete resources allocated in init_device.
......
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
# Distributed under the terms of the APACHE license. # Distributed under the terms of the APACHE license.
# See LICENSE.txt for more info. # See LICENSE.txt for more info.
""" PCC Device Server for LOFAR2.0 """ test Device Server
""" """
# PyTango imports # PyTango imports
...@@ -17,7 +16,7 @@ from tango.server import device_property ...@@ -17,7 +16,7 @@ from tango.server import device_property
from tango import DevState from tango import DevState
# Additional import # Additional import
from clients.test_client import example_client from clients.test_client import test_client
from src.attribute_wrapper import * from src.attribute_wrapper import *
from src.hardware_device import * from src.hardware_device import *
...@@ -25,7 +24,6 @@ __all__ = ["test_device", "main"] ...@@ -25,7 +24,6 @@ __all__ = ["test_device", "main"]
class test_device(hardware_device): class test_device(hardware_device):
# ----------------- # -----------------
# Device Properties # Device Properties
# ----------------- # -----------------
...@@ -48,16 +46,20 @@ class test_device(hardware_device): ...@@ -48,16 +46,20 @@ class test_device(hardware_device):
bool_scalar_R = attribute_wrapper(comms_annotation="numpy.bool_ type read scalar", datatype=numpy.bool_) bool_scalar_R = attribute_wrapper(comms_annotation="numpy.bool_ type read scalar", datatype=numpy.bool_)
bool_scalar_RW = attribute_wrapper(comms_annotation="numpy.bool_ type read/write scalar", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE) bool_scalar_RW = attribute_wrapper(comms_annotation="numpy.bool_ type read/write scalar", datatype=numpy.bool_, access=AttrWriteType.READ_WRITE)
int64_spectrum_R = attribute_wrapper(comms_annotation="numpy.int64 type read spectrum (len = 8)", datatype=numpy.int64, dims=(8,)) int32_spectrum_R = attribute_wrapper(comms_annotation="numpy.int32 type read spectrum (len = 8)", datatype=numpy.int32, dims=(8,))
str_spectrum_RW = attribute_wrapper(comms_annotation="numpy.str type read/write spectrum (len = 8)", datatype=numpy.str_, dims=(8,), access=AttrWriteType.READ_WRITE) int32_spectrum_RW = attribute_wrapper(comms_annotation="numpy.int32 type read spectrum (len = 8)", datatype=numpy.int32, dims=(8,),
access=AttrWriteType.READ_WRITE)
double_image_R = attribute_wrapper(comms_annotation="numpy.double type read image (dims = 2x8)", datatype=numpy.double, dims=(2, 8)) double_image_R = attribute_wrapper(comms_annotation="numpy.double type read image (dims = 2x8)", datatype=numpy.double, dims=(2, 8))
double_image_RW = attribute_wrapper(comms_annotation="numpy.double type read/write image (dims = 8x2)", datatype=numpy.double, dims=(8, 2), access=AttrWriteType.READ_WRITE) double_image_RW = attribute_wrapper(comms_annotation="numpy.double type read/write image (dims = 8x2)", datatype=numpy.double, dims=(8, 2),
access=AttrWriteType.READ_WRITE)
int32_scalar_R = attribute_wrapper(comms_annotation="numpy.int32 type read scalar", datatype=numpy.int32) int32_scalar_R = attribute_wrapper(comms_annotation="numpy.int32 type read scalar", datatype=numpy.int32)
uint16_spectrum_RW = attribute_wrapper(comms_annotation="numpy.uint16 type read/write spectrum (len = 8)", datatype=numpy.uint16, dims=(8,), access=AttrWriteType.READ_WRITE) uint16_spectrum_RW = attribute_wrapper(comms_annotation="numpy.uint16 type read/write spectrum (len = 8)", datatype=numpy.uint16, dims=(8,),
access=AttrWriteType.READ_WRITE)
float32_image_R = attribute_wrapper(comms_annotation="numpy.float32 type read image (dims = 8x2)", datatype=numpy.float32, dims=(8, 2)) float32_image_R = attribute_wrapper(comms_annotation="numpy.float32 type read image (dims = 8x2)", datatype=numpy.float32, dims=(8, 2))
uint8_image_RW = attribute_wrapper(comms_annotation="numpy.uint8 type read/write image (dims = 2x8)", datatype=numpy.uint8, dims=(2, 8), access=AttrWriteType.READ_WRITE) uint8_image_RW = attribute_wrapper(comms_annotation="numpy.uint8 type read/write image (dims = 2x8)", datatype=numpy.uint8, dims=(2, 8),
access=AttrWriteType.READ_WRITE)
# -------- # --------
# overloaded functions # overloaded functions
...@@ -68,16 +70,15 @@ class test_device(hardware_device): ...@@ -68,16 +70,15 @@ class test_device(hardware_device):
self.set_state(DevState.INIT) self.set_state(DevState.INIT)
# set up the test client
#set up the OPC ua client self.test_client = test_client(self.Fault, self)
self.example_client = example_client(self.Standby, self.Fault, self)
# map an access helper class # map an access helper class
for i in self.attr_list(): for i in self.attr_list():
i.set_comm_client(self.example_client) i.set_comm_client(self.test_client)
self.test_client.start()
self.example_client.start()
# ---------- # ----------
# Run server # Run server
......
...@@ -25,3 +25,7 @@ ENV TINI_VERSION v0.6.0 ...@@ -25,3 +25,7 @@ ENV TINI_VERSION v0.6.0
ENV JUPYTER_RUNTIME_DIR=/tmp ENV JUPYTER_RUNTIME_DIR=/tmp
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/bin/tini
RUN sudo chmod +x /usr/bin/tini RUN sudo chmod +x /usr/bin/tini
# Make sure Jupyter can write to the home directory
ENV HOME=/home/tango
RUN chmod a+rwx /home/tango
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment