diff --git a/.gitignore b/.gitignore index 1c9f0180be9d92c8ee002b05a09340a5dbc595b7..1868c635d7f144854c503dde0975c01c5195283e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ *.out *.app bin/ +build/ .nse_depinfo diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..70e01f2106d94b8eefdae2989f22323acb2db993 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,78 @@ +image: + name: nexus.engageska-portugal.pt/ska-docker/tango-dsconfig + +# The following variables are automatically passed down to the tangodb container +# as well as the tangodatabaseds container and available within each. +variables: + MYSQL_ROOT_PASSWORD: "secret" + MYSQL_DATABASE: "tango" + MYSQL_USER: "tango" + MYSQL_PASSWORD: "tango" + MYSQL_HOST: "tangodb" + TANGO_HOST: "localhost:10000" + +stages: + - build + - test + +#services: +# - name: nexus.engageska-portugal.pt/ska-docker/tango-db +# alias: tangodb +# - name: nexus.engageska-portugal.pt/ska-docker/tango-cpp +# alias: tangodatabaseds +# entrypoint: ["/usr/local/bin/DataBaseds"] +# command: ["2","-ORBendPoint giop:tcp::10000"] + +build_job: + stage: build + before_script: + #TODO: remove procps use for ps + - sudo apt update && sudo apt -y --no-install-recommends install build-essential cmake pkg-config libboost-thread-dev procps + script: + #- make + - mkdir build && cd build + - cmake -DBUILD_TESTS=ON .. + - make + artifacts: + paths: + - build/alarm-handler-srv + - build/bin/testdevice-srv + expire_in: 1 week + # # depending on your build setup it's most likely a good idea to cache outputs to reduce the build time + # cache: + # paths: + # - build/CMakeFiles/ + +test_load_job: + stage: test + before_script: + #TODO: remove procps use for ps + - sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev procps + script: + - sleep 10 + - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 & + - sleep 10 + - exit_code=2 + - json2tango -w -a -u ./test/ah_config.json || exit_code=$? + # json2tango returns 2 if values written to DB + - if [ ${exit_code} -ne 2 ]; then echo "Tango DB configuration failed!" ; else echo "Tango DB configuration succedeed!"; fi + - sleep 5 + - ./build/alarm-handler-srv 01 & + - ./build/bin/testdevice-srv 01 & + - sleep 10 + - ps -ef | grep alarm-handler-srv | grep -v grep + - ps -ef | grep testdevice-srv | grep -v grep + - sleep 5 + - python ./test/load-alarm-conf.py --device=alarm/handler/01 --load="tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1" + - sleep 1 + - python ./test/check-alarm-conf.py --device=alarm/handler/01 --alarm="tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1" + #artifacts: + # paths: + # - build/alarm-handler-srv + # expire_in: 1 week + needs: ["build_job"] + services: + - name: nexus.engageska-portugal.pt/ska-docker/tango-db + alias: tangodb + + diff --git a/.gitlab-ci.yml_multi_stage b/.gitlab-ci.yml_multi_stage new file mode 100644 index 0000000000000000000000000000000000000000..4dd6b6959776effde12158f81535f0ce9cb12dcf --- /dev/null +++ b/.gitlab-ci.yml_multi_stage @@ -0,0 +1,79 @@ +image: + name: nexus.engageska-portugal.pt/ska-docker/tango-dsconfig + +# The following variables are automatically passed down to the tangodb container +# as well as the tangodatabaseds container and available within each. +variables: + MYSQL_ROOT_PASSWORD: "secret" + MYSQL_DATABASE: "tango" + MYSQL_USER: "tango" + MYSQL_PASSWORD: "tango" + MYSQL_HOST: "tangodb" + TANGO_HOST: "localhost:10000" + +stages: + - build + - conf + - test + +services: + - name: nexus.engageska-portugal.pt/ska-docker/tango-db + alias: tangodb +# - name: nexus.engageska-portugal.pt/ska-docker/tango-cpp +# alias: tangodatabaseds +# entrypoint: ["/usr/local/bin/DataBaseds"] +# command: ["2","-ORBendPoint giop:tcp::10000"] + +build_job: + stage: build + before_script: + #TODO: remove procps use for ps + - sudo apt update && sudo apt -y --no-install-recommends install build-essential cmake pkg-config libboost-thread-dev procps + script: + #- make + - mkdir build && cd build + - cmake .. + - make + artifacts: + paths: + - build/alarm-handler-srv + expire_in: 1 week + # # depending on your build setup it's most likely a good idea to cache outputs to reduce the build time + # cache: + # paths: + # - build/CMakeFiles/ + +configure_and_run_job: + stage: conf + script: + - sleep 10 + - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 & + - sleep 10 + - exit_code=2 + - json2tango -w -a -u ./test/ah_config.json || exit_code=$? + # json2tango returns 2 if values written to DB + - if [ ${exit_code} -ne 2 ]; then echo "Tango DB configuration failed!" ; else echo "Tango DB configuration succedeed!"; fi + - sleep 5 + artifacts: + paths: + - build/alarm-handler-srv + expire_in: 1 week + needs: ["build_job"] + #services: + # - name: nexus.engageska-portugal.pt/ska-docker/tango-db + # alias: tangodb + +test_job: + stage: test + before_script: + #TODO: remove procps use for ps + - sudo apt update && sudo apt -y --no-install-recommends install libboost-thread-dev procps + script: + - /usr/local/bin/DataBaseds 2 -ORBendPoint giop:tcp::10000 & + - sleep 10 + - ./build/alarm-handler-srv 01 & + - sleep 10 + - ps -ef | grep alarm-handler-srv | grep -v grep + - sleep 5 + needs: ["configure_and_run_job"] + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f106d8e2b0b549219533525581bcd75b35f697ed --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,135 @@ +# Functions and Pre-build ----------------------------------- + +# Stop messy in source builds +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) +set(CMAKE_DISABLE_SOURCE_CHANGES OFF) + +if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) + message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." ) +endif() + +# Start Build Config ----------------------------------- +cmake_minimum_required(VERSION 3.8) +set(CMAKE_SKIP_RPATH true) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Output name for the final binary +set(AH_NAME "alarm-handler-srv") + +# Versioning +set(VERSION_MAJOR "1") +set(VERSION_MINOR "0") +set(VERSION_PATCH "0") +set(VERSION_METADATA "") +set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +# Add any include paths from the command line +list(APPEND INCLUDE_PATHS ${CMAKE_INCLUDE_PATH}) +list(APPEND INCLUDE_PATHS ${CMAKE_SOURCE_DIR}) +list(APPEND LIBRARY_PATHS ${CMAKE_LIBRARY_PATH}) + +# Start the project +project(alarm_handler VERSION ${VERSION_STRING} LANGUAGES CXX) + + +# Build options +option(ENABLE_CLANG "Enable clang code and layout analysis" OFF) +option(BUILD_TESTS "Build tests" OFF) + +# arch install definitions +include(GNUInstallDirs) + +message(STATUS "Searching for libraries...") + +# Variable to contain a list of all the libs we depend on +set(AH_LIBRARIES) + +# allow pkg-config to search the CMAKE_PREFIX_PATH +set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON) +list(APPEND CMAKE_PREFIX_PATH "/usr") + +# Find Dependencies ----------------------------------- + +# Find tango if it has not already been found. Returns an interface library +# called TangoInterfaceLibrary +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake") +find_package(Tango) + +set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) +find_package(Boost 1.65.0 COMPONENTS thread) + +# Code Analysis ----------------------------------- +if(ENABLE_CLANG) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + + # To find clang, find_program will search your PATH environment variable. + # Ensure if you have a non-standard clang install, that it has been added + # to your path. + find_program(CLANG_TIDY_EXE + NAMES "clang-tidy" + DOC "Path to clang-tidy executable") + + if(NOT CLANG_TIDY_EXE) + message(STATUS "clang-tidy not found.") + else(NOT CLANG_TIDY_EXE) + message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") + set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}") + endif(NOT CLANG_TIDY_EXE) +endif(ENABLE_CLANG) + +# Source ----------------------------------- + +add_subdirectory(src) + +# Build Targets ----------------------------------- + +# Executable -------- +add_executable(alarm_handler ${SRC_FILES}) + +target_link_libraries(alarm_handler + PRIVATE + TangoInterfaceLibrary + ${Boost_LIBRARIES} + ) + +target_include_directories(alarm_handler + PRIVATE + $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src> + ${INCLUDE_PATHS} + "${PROJECT_BINARY_DIR}" + ${Boost_INCLUDE_DIRS}) + +set_target_properties(alarm_handler + PROPERTIES + OUTPUT_NAME ${AH_NAME} + LINK_FLAGS "-Wl,--no-undefined" + CXX_STANDARD 11) + +if(DO_CLANG_TIDY) + set_target_properties(alarm_handler + PROPERTIES + CXX_CLANG_TIDY ${DO_CLANG_TIDY}) +endif(DO_CLANG_TIDY) + +target_compile_options(alarm_handler + PRIVATE "$<$<CONFIG:DEBUG>:-g>") + +# Install Config ----------------------------------- +install( + TARGETS alarm_handler + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +message(STATUS "Configured alarm-handler project") + + +# Tests ----------------------------------- +if(BUILD_TESTS) + add_subdirectory(test) +endif(BUILD_TESTS) + diff --git a/cmake/FindLibraries.cmake b/cmake/FindLibraries.cmake new file mode 100644 index 0000000000000000000000000000000000000000..4db63a57cbba49278997b1283a674d2361babfb8 --- /dev/null +++ b/cmake/FindLibraries.cmake @@ -0,0 +1,32 @@ +include(CMakeParseArguments) + +function(find_libraries) + + # Parse the parameters + set(MULTIVALUEARGS LIBRARIES SEARCH_PATHS) + cmake_parse_arguments(FIND_LIBRARIES "" "" "${MULTIVALUEARGS}" ${ARGN}) + + # Clear the found libraries + unset(FOUND_LIBRARIES PARENT_SCOPE) + + foreach(LIB ${FIND_LIBRARIES_LIBRARIES}) + + # try the user provided paths first + find_library(FOUND_LIB_${LIB} ${LIB} PATHS ${FIND_LIBRARIES_SEARCH_PATHS} NO_DEFAULT_PATH) + + # if we could not find it, drop to the system paths + if(NOT FOUND_LIB_${LIB}) + find_library(FOUND_LIB_${LIB} ${LIB}) + endif(NOT FOUND_LIB_${LIB}) + + if(FOUND_LIB_${LIB}) + message(STATUS "Found " ${LIB} " at: " ${FOUND_LIB_${LIB}}) + list(APPEND FOUND_LIBRARIES ${FOUND_LIB_${LIB}}) + else() + message(FATAL "Could not find " ${LIB}) + endif(FOUND_LIB_${LIB}) + + endforeach(LIB ${LIBRARIES}) + + set(FOUND_LIBRARIES ${FOUND_LIBRARIES} PARENT_SCOPE) +endfunction(find_libraries) \ No newline at end of file diff --git a/cmake/FindTango.cmake b/cmake/FindTango.cmake new file mode 100644 index 0000000000000000000000000000000000000000..241b1529c0452eba1a783f4ac33b9609a28bdf9a --- /dev/null +++ b/cmake/FindTango.cmake @@ -0,0 +1,24 @@ +if(NOT TARGET TangoInterfaceLibrary) + + # Ensure pkg-config is installed + find_package(PkgConfig REQUIRED) + + # Now search for the tango.pc file, this is a required dependency + message(STATUS "Search for TANGO package config...") + pkg_search_module(TANGO REQUIRED tango>=9.2.5) + message(STATUS "Found tango version ${TANGO_VERSION} at ${TANGO_PREFIX}") + + include(FindLibraries) + find_libraries(LIBRARIES ${TANGO_LIBRARIES} SEARCH_PATHS ${TANGO_LIBRARY_DIRS}) + + # Create an interface library to represent the tango linkage + add_library(TangoInterfaceLibrary INTERFACE) + + set_target_properties(TangoInterfaceLibrary + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${TANGO_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FOUND_LIBRARIES}" + INTERFACE_COMPILE_OPTIONS "${TANGO_CFLAGS}") + + message(STATUS "Configured Tango Interface for TANGO version ${TANGO_VERSION}") +endif(NOT TARGET TangoInterfaceLibrary) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..03dba93c7557c6fafd91c2f3c29f540b85b23180 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.2) + +# source files +set(SRC_FILES ${SRC_FILES} + ${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerClass.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerDynAttrUtils.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/AlarmHandlerStateMachine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/alarm_table.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/alarm-thread.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ClassFactory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/cmd_thread.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/event_table.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/SubscribeThread.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/update-thread.cpp + PARENT_SCOPE) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e51ae0e9683c06f531b70c63fea8c5967a46f18f --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,29 @@ +cmake_minimum_required(VERSION 3.2) + +project(test NONE) +include(ExternalProject) + +ExternalProject_Add(testdevice + SOURCE_DIR ${CMAKE_SOURCE_DIR}/test/testdevice +# PREFIX ${CMAKE_BINARY_DIR} + CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}" +# INSTALL_DIR ${CMAKE_BINARY_DIR} +# BINARY_DIR ${CMAKE_BINARY_DIR} +# STEP_TARGETS build +# EXCLUDE_FROM_ALL TRUE + ) + +ExternalProject_Get_property(testdevice SOURCE_DIR) +message("Source dir of testdevice = ${SOURCE_DIR}") + +ExternalProject_Get_property(testdevice INSTALL_DIR) +message("Install dir of testdevice = ${INSTALL_DIR}") + +ExternalProject_Get_property(testdevice BINARY_DIR) +message("Binary dir of testdevice = ${BINARY_DIR}") + +ExternalProject_Get_property(testdevice CMAKE_ARGS) +message("CMqke args for testdevice = ${CMAKE_ARGS}") + +#ExternalProject_Get_property(testdevice PREFIX) +#message("Prefix dir of testdevice = ${PREFIX}") diff --git a/test/ah_config.json b/test/ah_config.json new file mode 100644 index 0000000000000000000000000000000000000000..20998cf9cbe19fe2ee0c30226e24fcd152881af4 --- /dev/null +++ b/test/ah_config.json @@ -0,0 +1,45 @@ +{ + "_version": 1, + "_source": "ConfigInjectorDiag.xls", + "_title": "hdbpp mysql innodb test", + "_date": "2020-07-07 14:45:04", + + "servers": { + "alarm-handler-srv/01": { + "AlarmHandler": { + "alarm/handler/01": { + "properties": { + }, + "attribute_properties": { + } + } + } + }, + "testdevice-srv/01": { + "TestDevice": { + "alarm/test/01": { + "properties": { + "Attr_config": [ + "condition:bool:0:0.0" + ] + }, + "attribute_properties": { + } + } + } + } + }, + "classes": { + "AlarmHandler": { + "properties": { + "GroupNames": ["gr_none","gr_test"], + "StatisticsTimeWindow": ["60"], + "SubscribeRetryPeriod": ["30"] + } + }, + "TestDevice": { + "properties": { + } + } + } +} diff --git a/test/check-alarm-conf.py b/test/check-alarm-conf.py new file mode 100755 index 0000000000000000000000000000000000000000..4cf65b5978d79bf823cd493bf23d9985d844a5b1 --- /dev/null +++ b/test/check-alarm-conf.py @@ -0,0 +1,103 @@ +#!/usr/bin/python +# + +import sys,re +#import PyTango +from PyTango import * +import time +import string + +if __name__ == "__main__": + + Device = False + Conf = False + File = False + conflist = [] + #PrepareState = False + for arg in sys.argv: + word = '([a-z0-9._\-\*]*)' + wordpath = '([a-z0-9._\-\*/]*)' + m = re.compile("--device=" + word + "/{0,1}" + word + "/{0,1}" + word).match(arg.lower()) + if m is not None: + #print m.groups() + domain = m.groups()[0] + family = m.groups()[1] + member = m.groups()[2] + if domain == '': + domain = '*' + if family == '': + family = '*' + if member == '': + member = '*' + Device = True + #formula = '([a-z0-9._,\*,\-,\|,\/,\",\s,\t]*)' + formula = '(.*)' + m = re.compile("--conf=" + formula).match(arg) + if m is not None: + #print m.groups() + alarm_rule = m.groups()[0] + Conf = True + #m = re.compile("--prepare_state").match(arg.lower()) + #if m is not None: + # PrepareState = True + m = re.compile("--file=" + wordpath).match(arg) + if m is not None: + #print m.groups() + file_name = m.groups()[0] + File = True + + tagchars = '([a-zA-Z0-9._-]*)' + tag='' + if Device: + if Conf or File: + dev_name = domain + '/' + family + '/' + member + try: + dev = DeviceProxy(dev_name) + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print ('ERROR connecting proxy(',dev_name,'): ',e[0].desc) + sys.exit(-1) + if Conf: + m = re.compile("tag=" + tagchars + ";(.*)").match(alarm_rule) + if m is not None: + try: + tag = m.groups()[0] + conflist = dev.command_inout('SearchAlarm',tag) + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print (' ---> ERROR: ', e[0].desc) + sys.exit(1) + for co in conflist: + if co == alarm_rule: + print ('Found matching alarm: ', co) + sys.exit(0) + print ('Not found conf for alarm ', tag) + sys.exit(1) + elif File: + for line in open(file_name): + line = line[0:-1] + m = re.compile("tag=" + tagchars + ";(.*)").match(line) + conf_found = False + if m is not None: + try: + tag = m.groups()[0] + conflist = dev.command_inout('SearchAlarm',tag) + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print (' ---> ERROR: ', e[0].desc) + sys.exit(1) + for co in conflist: + if co == alarm_rule: + conf_found = True + if not conf_found: + print ('Not found conf for alarm ', tag) + sys.exit(1) + + sys.exit(0) + + if len(sys.argv) < 3: + print ('Usage:', sys.argv[0], ' --device=alarm_device --conf=alarm_rule | --file=filename') + print () + print ('Examples:') + print ('\tcheck one alarm_rule in alarm/handler/01:', sys.argv[0], '--device=alarm/handler/01 --conf=\"tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1\"') + print ('\tcheck alarm rules from filename in alarm/handler/01:', sys.argv[0], '--device=alarm/handler/01 --file=alarms.txt') + sys.exit(-1) + +# EOF diff --git a/test/load-alarm-conf.py b/test/load-alarm-conf.py new file mode 100755 index 0000000000000000000000000000000000000000..d584350396cdcce2e1f3b5ddd0ea5be7125e8de1 --- /dev/null +++ b/test/load-alarm-conf.py @@ -0,0 +1,85 @@ +#!/usr/bin/python +# + +import sys,re +#import PyTango +from PyTango import * +import time +import string + +if __name__ == "__main__": + + Device = False + Conf = False + File = False + #PrepareState = False + for arg in sys.argv: + word = '([a-z0-9._\-\*]*)' + wordpath = '([a-z0-9._\-\*/]*)' + m = re.compile("--device=" + word + "/{0,1}" + word + "/{0,1}" + word).match(arg.lower()) + if m is not None: + domain = m.groups()[0] + family = m.groups()[1] + member = m.groups()[2] + if domain == '': + domain = '*' + if family == '': + family = '*' + if member == '': + member = '*' + Device = True + #formula = '([a-z0-9._,\*,\-,\|,\/,\",\s,\t]*)' + formula = '(.*)' + m = re.compile("--conf=" + formula).match(arg) + if m is not None: + alarm_rule = m.groups()[0] + Conf = True + #m = re.compile("--prepare_state").match(arg.lower()) + #if m is not None: + # PrepareState = True + m = re.compile("--file=" + wordpath).match(arg) + if m is not None: + file_name = m.groups()[0] + File = True + + if Device: + if Conf or File: + dev_name = domain + '/' + family + '/' + member + try: + dev = DeviceProxy(dev_name) + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print ('ERROR connecting proxy(',dev_name,'): ',e[0].desc) + sys.exit(-1) + if Conf: + print ('Loading: ', alarm_rule) + try: + dev.command_inout('Load',alarm_rule) + print ('.............OK!') + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print ('...........ERROR!') + print (' ---> ERROR: ', e[0].desc) + continue + sys.exit(0) + elif File: + for line in open(file_name): + line = line[0:-1] + try: + dev.command_inout('Load',line) + time.sleep(0.1) + except (DevFailed,ConnectionFailed,EventSystemFailed) as e: + print (' ---> ERROR: ', e[0].desc) + time.sleep(2) + sys.exit(1) + sys.exit(0) + #dev = DeviceProxy("alarm/alarm/1") + #dev.command_inout('Load', sys.argv[1]) + + if len(sys.argv) < 3: + print ('Usage:', sys.argv[0], ' --device=alarm_device --conf=alarm_rule | --file=filename') + print () + print ('Examples:') + print ('\tload one alarm_rule in alarm/handler/01:', sys.argv[0], '--device=alarm/handler/01 --conf=\"tag=test0;formula=(alarm/test/01/condition == 1);on_delay=0;off_delay=0;priority=high;shlvd_time=0;group=gr_test;message=Test alarm;url=;on_command=;off_command=;enabled=1\"') + print ('\tload alarm rules from filename in alarm/handler/01:', sys.argv[0], '--device=alarm/handler/01 --file=alarms.txt') + sys.exit(-1) + +# EOF diff --git a/test/testdevice/CMakeLists.txt b/test/testdevice/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..47e5ffd4c460fe7a55dda2e4881dea2d285f99e3 --- /dev/null +++ b/test/testdevice/CMakeLists.txt @@ -0,0 +1,96 @@ +# Functions and Pre-build ----------------------------------- + +# Stop messy in source builds +set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) +set(CMAKE_DISABLE_SOURCE_CHANGES OFF) + +if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) + message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." ) +endif() + +# Start Build Config ----------------------------------- +cmake_minimum_required(VERSION 3.8) +set(CMAKE_SKIP_RPATH true) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Output name for the final binary +set(DEV_NAME "testdevice-srv") + +# Versioning +set(VERSION_MAJOR "1") +set(VERSION_MINOR "0") +set(VERSION_PATCH "0") +set(VERSION_METADATA "") +set(VERSION_STRING ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +# Add any include paths from the command line +list(APPEND INCLUDE_PATHS ${CMAKE_INCLUDE_PATH}) +list(APPEND INCLUDE_PATHS ${CMAKE_SOURCE_DIR}) +list(APPEND LIBRARY_PATHS ${CMAKE_LIBRARY_PATH}) + +# Start the project +project(testdevice VERSION ${VERSION_STRING} LANGUAGES CXX) + + +# Build options + +# arch install definitions +include(GNUInstallDirs) + +message(STATUS "Searching for libraries...") + +# Variable to contain a list of all the libs we depend on +set(AH_LIBRARIES) + +# allow pkg-config to search the CMAKE_PREFIX_PATH +set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH ON) +list(APPEND CMAKE_PREFIX_PATH "/usr") + +# Find Dependencies ----------------------------------- + +# Find tango if it has not already been found. Returns an interface library +# called TangoInterfaceLibrary +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake") +find_package(Tango) + +# Source ----------------------------------- + +add_subdirectory(src) + +# Build Targets ----------------------------------- + +# Executable -------- +add_executable(testdevice ${SRC_FILES}) + +target_link_libraries(testdevice + PRIVATE + TangoInterfaceLibrary + ) + +target_include_directories(testdevice + PRIVATE + $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src> + ${INCLUDE_PATHS} + "${PROJECT_BINARY_DIR}" + ) + +set_target_properties(testdevice + PROPERTIES + OUTPUT_NAME ${DEV_NAME} + LINK_FLAGS "-Wl,--no-undefined" + CXX_STANDARD 11) + +target_compile_options(testdevice + PRIVATE "$<$<CONFIG:DEBUG>:-g>") + +# Install Config ----------------------------------- +install( + TARGETS testdevice + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +message(STATUS "Configured testdevice project") + diff --git a/test/testdevice/LICENSE b/test/testdevice/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..65c5ca88a67c30becee01c5a8816d964b03862f9 --- /dev/null +++ b/test/testdevice/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/test/testdevice/Make-9.3.4.in b/test/testdevice/Make-9.3.4.in new file mode 100644 index 0000000000000000000000000000000000000000..6e9b70ea3338aea1f61279f736c60f7c47ed2ef1 --- /dev/null +++ b/test/testdevice/Make-9.3.4.in @@ -0,0 +1,93 @@ +GCCMAJOR := $(shell ${CXX} -dumpversion | cut -d"." -f1) +GCCMINOR := $(shell ${CXX} -dumpversion | cut -d"." -f2) +MACHINE := $(shell ${CXX} -dumpmachine) + +TANGO_DIR := /usr/local/tango-9.3.4 +OMNIORB_DIR := /usr/local/omniorb-4.2.3 +ZMQ_DIR := /usr/local/zeromq-4.0.8 +RUNTIME_DIR := /runtime + +TANGO_INC := ${TANGO_DIR}/include/tango +LOG4TANGO_INC := ${TANGO_DIR}/include +OMNIORB_INC := ${OMNIORB_DIR}/include +ZMQ_INC := ${ZMQ_DIR}/include +RUNTIME_INC := ${RUNTIME_DIR}/include + +TANGO_LIB = ${TANGO_DIR}/lib +OMNIORB_LIB = ${OMNIORB_DIR}/lib +ZMQ_LIB = ${ZMQ_DIR}/lib +RUNTIME_LIB = ${RUNTIME_DIR}/lib + +ifeq ($(SDKTARGETSYSROOT),) + ifeq ($(GCCMAJOR),4) + ifeq ($(shell test $(GCCMINOR) -lt 4; echo $$?),0) + CXXFLAGS += -std=gnu++98 + else + CXXFLAGS += -std=c++0x + endif + else + CXXFLAGS += -std=c++11 + endif + INC_DIR = -I${TANGO_INC} -I${LOG4TANGO_INC} -I${OMNIORB_INC} -I${ZMQ_INC} -I${RUNTIME_INC} + LIB_DIR = -L${TANGO_LIB} -L${OMNIORB_LIB} -L${ZMQ_LIB} -L${RUNTIME_LIB} -L/usr/local/lib +else + CXXFLAGS += -std=gnu++11 + INC_DIR = -I${SDKTARGETSYSROOT}/usr/include/tango +endif + +#----------------------------------------- +# Default make entry +#----------------------------------------- +default: release +release debug: bin/$(NAME_SRV) +all: default +#----------------------------------------- +# Set CXXFLAGS and LDFLAGS +#----------------------------------------- + +CXXFLAGS += -D__linux__ -D__OSVERSION__=2 -Wall -pedantic \ + -Wno-non-virtual-dtor -Wno-long-long -DOMNI_UNLOADABLE_STUBS \ + $(INC_DIR) -Isrc + +ifeq ($(GCCMAJOR),4) + CXXFLAGS += -Wextra +endif +ifeq ($(GCCMAJOR),5) + CXXFLAGS += -Wextra +endif +LDFLAGS += $(LIB_DIR) -ltango -lomniORB4 -lomniDynamic4 \ + -lCOS4 -lomnithread -lzmq + +#----------------------------------------- +# Set dependencies +#----------------------------------------- +SRC_FILES += $(wildcard src/*.cpp) +OBJ_FILES += $(addprefix obj/,$(notdir $(SRC_FILES:.cpp=.o))) + +obj/%.o: $(SRC_FILES:%.cpp) + $(CXX) $(CXXFLAGS) -c -o $@ $< + +.nse_depinfo: $(SRC_FILES) + @$(CXX) $(CXXFLAGS) -M -MM $^ | sed 's/\(.*\)\.o/obj\/\1.o/g' > $@ +-include .nse_depinfo + +#----------------------------------------- +# Main make entries +#----------------------------------------- +bin/$(NAME_SRV): bin obj $(OBJ_FILES) + $(CXX) $(CXXFLAGS) $(OBJ_FILES) -o bin/$(NAME_SRV) $(LDFLAGS) + +clean: + @rm -fr obj/ bin/ core* .nse_depinfo src/*~ + +bin obj: + @ test -d $@ || mkdir $@ + +#----------------------------------------- +# Target specific options +#----------------------------------------- +release: CXXFLAGS += -O2 -DNDEBUG +release: LDFLAGS += -s +debug: CXXFLAGS += -ggdb3 + +.PHONY: clean diff --git a/test/testdevice/Makefile b/test/testdevice/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..78898556014f21155eadf1341765289d7e89d7f8 --- /dev/null +++ b/test/testdevice/Makefile @@ -0,0 +1,6 @@ +NAME_SRV = testdevice-srv + +CXXFLAGS = +LDFLAGS = + +include ./Make-9.3.4.in diff --git a/test/testdevice/README.md b/test/testdevice/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b85ef5b2a19404342193e1675143b9baa8c8638f --- /dev/null +++ b/test/testdevice/README.md @@ -0,0 +1,30 @@ +# Project Name + +testdevice + +## Description + +Tango device server for storing and distributing a number of variables as device attributes. + +## Installation + +See your institue guidelines for deploying and configuring a Tango device server. + +## Usage + +The server is dynamically configured by means of dedicated Methods. The configuration and values are stored in the Tango Database and restored at server restart. +A typical usage is to store and distribute the results of measurments or simulations to a number of differet clients. + +## History + + +## Credits + + +Elettra-Sincrotrone Trieste S.C.p.A. di interesse nazionale +Strada Statale 14 - km 163,5 in AREA Science Park +34149 Basovizza, Trieste ITALY + +## License + +GPL 3 diff --git a/test/testdevice/cmake/FindLibraries.cmake b/test/testdevice/cmake/FindLibraries.cmake new file mode 100644 index 0000000000000000000000000000000000000000..4db63a57cbba49278997b1283a674d2361babfb8 --- /dev/null +++ b/test/testdevice/cmake/FindLibraries.cmake @@ -0,0 +1,32 @@ +include(CMakeParseArguments) + +function(find_libraries) + + # Parse the parameters + set(MULTIVALUEARGS LIBRARIES SEARCH_PATHS) + cmake_parse_arguments(FIND_LIBRARIES "" "" "${MULTIVALUEARGS}" ${ARGN}) + + # Clear the found libraries + unset(FOUND_LIBRARIES PARENT_SCOPE) + + foreach(LIB ${FIND_LIBRARIES_LIBRARIES}) + + # try the user provided paths first + find_library(FOUND_LIB_${LIB} ${LIB} PATHS ${FIND_LIBRARIES_SEARCH_PATHS} NO_DEFAULT_PATH) + + # if we could not find it, drop to the system paths + if(NOT FOUND_LIB_${LIB}) + find_library(FOUND_LIB_${LIB} ${LIB}) + endif(NOT FOUND_LIB_${LIB}) + + if(FOUND_LIB_${LIB}) + message(STATUS "Found " ${LIB} " at: " ${FOUND_LIB_${LIB}}) + list(APPEND FOUND_LIBRARIES ${FOUND_LIB_${LIB}}) + else() + message(FATAL "Could not find " ${LIB}) + endif(FOUND_LIB_${LIB}) + + endforeach(LIB ${LIBRARIES}) + + set(FOUND_LIBRARIES ${FOUND_LIBRARIES} PARENT_SCOPE) +endfunction(find_libraries) \ No newline at end of file diff --git a/test/testdevice/cmake/FindTango.cmake b/test/testdevice/cmake/FindTango.cmake new file mode 100644 index 0000000000000000000000000000000000000000..241b1529c0452eba1a783f4ac33b9609a28bdf9a --- /dev/null +++ b/test/testdevice/cmake/FindTango.cmake @@ -0,0 +1,24 @@ +if(NOT TARGET TangoInterfaceLibrary) + + # Ensure pkg-config is installed + find_package(PkgConfig REQUIRED) + + # Now search for the tango.pc file, this is a required dependency + message(STATUS "Search for TANGO package config...") + pkg_search_module(TANGO REQUIRED tango>=9.2.5) + message(STATUS "Found tango version ${TANGO_VERSION} at ${TANGO_PREFIX}") + + include(FindLibraries) + find_libraries(LIBRARIES ${TANGO_LIBRARIES} SEARCH_PATHS ${TANGO_LIBRARY_DIRS}) + + # Create an interface library to represent the tango linkage + add_library(TangoInterfaceLibrary INTERFACE) + + set_target_properties(TangoInterfaceLibrary + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${TANGO_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FOUND_LIBRARIES}" + INTERFACE_COMPILE_OPTIONS "${TANGO_CFLAGS}") + + message(STATUS "Configured Tango Interface for TANGO version ${TANGO_VERSION}") +endif(NOT TARGET TangoInterfaceLibrary) \ No newline at end of file diff --git a/test/testdevice/src/CMakeLists.txt b/test/testdevice/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ae7908bcf66a743c0e90582e0b8c6e87873534b9 --- /dev/null +++ b/test/testdevice/src/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.2) + +# source files +set(SRC_FILES ${SRC_FILES} + ${CMAKE_CURRENT_SOURCE_DIR}/TestDevice.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestDeviceClass.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/TestDeviceStateMachine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ClassFactory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp + PARENT_SCOPE) diff --git a/test/testdevice/src/ClassFactory.cpp b/test/testdevice/src/ClassFactory.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1b2363345f0d92536c352396be57afb84f8a387d --- /dev/null +++ b/test/testdevice/src/ClassFactory.cpp @@ -0,0 +1,38 @@ +/*----- PROTECTED REGION ID(TestDevice::ClassFactory.cpp) ENABLED START -----*/ + +//============================================================================= +// +// file : ClassFactory.cpp +// +// description : C++ source for the class_factory method of the DServer +// device class. This method is responsible for the creation of +// all class singleton for a device server. It is called +// at device server startup. +// +// $Author: graziano $ +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <tango.h> +#include <TestDeviceClass.h> + +// Add class header files if needed + + +/** + * Create TestDevice Class singleton and store it in DServer object. + */ + +void Tango::DServer::class_factory() +{ + // Add method class init if needed + + add_class(TestDevice_ns::TestDeviceClass::init("TestDevice")); +} + +/*----- PROTECTED REGION END -----*/ diff --git a/test/testdevice/src/TestDevice.cpp b/test/testdevice/src/TestDevice.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab7a8fc151749b0bd127ea1bfa509b98f4ce3b23 --- /dev/null +++ b/test/testdevice/src/TestDevice.cpp @@ -0,0 +1,1630 @@ +/*----- PROTECTED REGION ID(TestDevice.cpp) ENABLED START -----*/ + +//============================================================================= +// +// file : TestDevice.cpp +// +// description : C++ source for the TestDevice and its commands. +// The class is derived from Device. It represents the +// CORBA servant object which will be accessed from the +// network. All commands which can be executed on the +// TestDevice are implemented in this file. +// +// $Author: graziano $ +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <TestDevice.h> +#include <TestDeviceClass.h> +#include <math.h> +#include <iomanip> +#include <limits> + +/*----- PROTECTED REGION END -----*/ + + +/** + * TestDevice class description: + * + */ + +//================================================================ +// +// The following table gives the correspondence +// between command and method names. +// +// Command name | Method name +//---------------------------------------------------------------- +// State | Inherited (no method) +// Status | Inherited (no method) +//================================================================ + +namespace TestDevice_ns +{ + /*----- PROTECTED REGION ID(TestDevice::namespace_starting) ENABLED START -----*/ + + // static initializations + + /*----- PROTECTED REGION END -----*/ // TestDevice::namespace_starting + + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDevice() + * Description : Constructors for a Tango device + * implementing the class TestDevice + */ +//-------------------------------------------------------- +TestDevice::TestDevice(Tango::DeviceClass *cl, string &s) + : TANGO_BASE_CLASS(cl, s.c_str()) +{ + /*----- PROTECTED REGION ID(TestDevice::constructor_1) ENABLED START -----*/ + + init_device(); + + /*----- PROTECTED REGION END -----*/ // TestDevice::constructor_1 +} +//-------------------------------------------------------- +TestDevice::TestDevice(Tango::DeviceClass *cl, const char *s) + : TANGO_BASE_CLASS(cl, s) +{ + /*----- PROTECTED REGION ID(TestDevice::constructor_2) ENABLED START -----*/ + + init_device(); + + /*----- PROTECTED REGION END -----*/ // TestDevice::constructor_2 +} +//-------------------------------------------------------- +TestDevice::TestDevice(Tango::DeviceClass *cl, const char *s, const char *d) + : TANGO_BASE_CLASS(cl, s, d) +{ + /*----- PROTECTED REGION ID(TestDevice::constructor_3) ENABLED START -----*/ + + init_device(); + + /*----- PROTECTED REGION END -----*/ // TestDevice::constructor_3 +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::delete_device()() + * Description : will be called at device destruction or at init command + */ +//-------------------------------------------------------- +void TestDevice::delete_device() +{ + /*----- PROTECTED REGION ID(TestDevice::delete_device) ENABLED START -----*/ + + // Delete device allocated objects + + save_configuration(); + + map<std::string,map_data_t>::iterator it; + for(it = attr_data_map.begin(); it != attr_data_map.end(); it++) + { + if(it->second.type == Tango::DEV_DOUBLE) + delete [] (Tango::DevDouble *) it->second.value; + else if(it->second.type == Tango::DEV_LONG) + delete [] (Tango::DevLong *) it->second.value; + else if(it->second.type == Tango::DEV_BOOLEAN) + delete [] (Tango::DevBoolean *) it->second.value; + else if(it->second.type == Tango::DEV_STRING) + delete [] (char *) it->second.value; //TODO: !!! + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::delete_device + delete[] attr_ScalarDyn_read; + delete[] attr_Ref_read; + delete[] attr_Values_read; + +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::init_device() + * Description : // will be called at device initialization. + */ +//-------------------------------------------------------- +void TestDevice::init_device() +{ + DEBUG_STREAM << "TestDevice::init_device() create device " << device_name << endl; + + /*----- PROTECTED REGION ID(TestDevice::init_device_before) ENABLED START -----*/ + + // Initialization before get_device_property() call + dlastDB = 0.0; + waitingDB = false; + + /*----- PROTECTED REGION END -----*/ // TestDevice::init_device_before + + // Get the device properties (if any) from database + get_device_property(); + + attr_ScalarDyn_read = new Tango::DevString[1]; + attr_Ref_read = new Tango::DevDouble[1024]; + attr_Values_read = new Tango::DevString[1024]; + + /*----- PROTECTED REGION ID(TestDevice::init_device) ENABLED START -----*/ + for (int i = 0; i < 1024; i++) + { + //ref_ptr[i] = ref_array[i]; + attr_Values_read[i] = ref_array[i]; + } + + // Initialize device + gettimeofday(&last_read, NULL); + set_state(Tango::ON); + + /*----- PROTECTED REGION END -----*/ // TestDevice::init_device +} + + + +//-------------------------------------------------------- +/** + * Method : TestDevice::get_device_property() + * Description : // Add your own code to initialize + */ +//-------------------------------------------------------- +void TestDevice::get_device_property() +{ + /*----- PROTECTED REGION ID(TestDevice::get_device_property_before) ENABLED START -----*/ + + // Initialize property data members + + /*----- PROTECTED REGION END -----*/ // TestDevice::get_device_property_before + + + // Read device properties from database. + Tango::DbData dev_prop; + dev_prop.push_back(Tango::DbDatum("Attr_config")); + dev_prop.push_back(Tango::DbDatum("MinSaveDBPeriod")); + + // is there at least one property to be read ? + if (dev_prop.size()>0) + { + // Call database and extract values + if (Tango::Util::instance()->_UseDb==true) + get_db_device()->get_property(dev_prop); + + // get instance on TestDeviceClass to get class property + Tango::DbDatum def_prop, cl_prop; + TestDeviceClass *ds_class = + (static_cast<TestDeviceClass *>(get_device_class())); + int i = -1; + + // Try to initialize Attr_config from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> attr_config; + else { + // Try to initialize Attr_config from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> attr_config; + } + // And try to extract Attr_config value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> attr_config; + + // Try to initialize MinSaveDBPeriod from class property + cl_prop = ds_class->get_class_property(dev_prop[++i].name); + if (cl_prop.is_empty()==false) cl_prop >> minSaveDBPeriod; + else { + // Try to initialize MinSaveDBPeriod from default device value + def_prop = ds_class->get_default_device_property(dev_prop[i].name); + if (def_prop.is_empty()==false) def_prop >> minSaveDBPeriod; + } + // And try to extract MinSaveDBPeriod value from database + if (dev_prop[i].is_empty()==false) dev_prop[i] >> minSaveDBPeriod; + + + } + /*----- PROTECTED REGION ID(TestDevice::get_device_property_after) ENABLED START -----*/ + + // Check device property data members init + + /*----- PROTECTED REGION END -----*/ // TestDevice::get_device_property_after + +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::always_executed_hook() + * Description : method always executed before any command is executed + */ +//-------------------------------------------------------- +void TestDevice::always_executed_hook() +{ + //INFO_STREAM << "TestDevice::always_executed_hook() " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::always_executed_hook) ENABLED START -----*/ + + // code always executed before all requests + + /*----- PROTECTED REGION END -----*/ // TestDevice::always_executed_hook +} + + + +//-------------------------------------------------------- +/** + * Method : TestDevice::read_attr_hardware() + * Description : Hardware acquisition for attributes. + */ +//-------------------------------------------------------- +void TestDevice::read_attr_hardware(vector<long> &attr_list) +{ + //DEBUG_STREAM << "TestDevice::read_attr_hardware(vector<long> &attr_list) entering... " << endl; + /*----- PROTECTED REGION ID(TestDevice::read_attr_hardware) ENABLED START -----*/ + + // Add your own code + if(waitingDB) + { + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::read_attr_hardware + +} + + +//-------------------------------------------------------- +/** + * Read ScalarDyn attribute + * Description: + * + * Data type: Tango::DevDouble + * Attr type: Scalar + */ +//-------------------------------------------------------- +void TestDevice::read_ScalarDyn(Tango::Attribute &attr) +{ + //DEBUG_STREAM << "TestDevice::read_ScalarDyn(Tango::Attribute &attr) entering... " << endl; + /*----- PROTECTED REGION ID(TestDevice::read_ScalarDyn) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it = attr_data_map.find(attr.get_name()); + if(it == attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception reading attribute", + (const char*) "Attribute Not Found", __FUNCTION__, Tango::ERR); + + if(it->second.type == Tango::DEV_DOUBLE) + { + attr.set_value_date_quality((Tango::DevDouble *) it->second.value,it->second.ts,Tango::ATTR_VALID, 1, 0, false); + } + else if(it->second.type == Tango::DEV_LONG) + { + attr.set_value_date_quality((Tango::DevLong *) it->second.value,it->second.ts,Tango::ATTR_VALID, 1, 0, false); + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + attr.set_value_date_quality((Tango::DevBoolean *) it->second.value,it->second.ts,Tango::ATTR_VALID, 1, 0, false); + } + else if(it->second.type == Tango::DEV_STRING) + { + *attr_ScalarDyn_read = (char *) it->second.value; + attr.set_value_date_quality(attr_ScalarDyn_read,it->second.ts,Tango::ATTR_VALID, 1, 0, false); + //attr.set_value_date_quality((Tango::DevString *) it->second.value,it->second.ts,Tango::ATTR_VALID, 1, 0, false); + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::read_ScalarDyn +} +//+---------------------------------------------------------------------------- +// +// method : TestDevice::write_ScalarDyn +// +// description : Write ScalarDyn attribute values to hardware. +// +//----------------------------------------------------------------------------- +void TestDevice::write_ScalarDyn(Tango::WAttribute &attr) +{ + DEBUG_STREAM << "TestDevice::write_ScalarDyn(Tango::WAttribute &attr) entering... "<< endl; + /*----- PROTECTED REGION ID(TestDevice::write_ScalarDyn) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it = attr_data_map.find(attr.get_name()); + if(it == attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception reading attribute", + (const char*) "Attribute Not Found", __FUNCTION__, Tango::ERR); + + gettimeofday(&(it->second.ts), NULL); + if(it->second.type == Tango::DEV_DOUBLE) + { + Tango::DevDouble w_val; + attr.get_write_value(w_val); + *(Tango::DevDouble *) it->second.value = w_val; + try{ + push_change_event(attr.get_name(),(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(attr.get_name(),(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_LONG) + { + Tango::DevLong w_val; + attr.get_write_value(w_val); + *(Tango::DevLong *) it->second.value = w_val; + try{ + push_change_event(attr.get_name(),(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(attr.get_name(),(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + Tango::DevBoolean w_val; + attr.get_write_value(w_val); + *(Tango::DevBoolean *) it->second.value = w_val; + try{ + push_change_event(attr.get_name(),(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(attr.get_name(),(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_STRING) + { + Tango::DevString w_val; + attr.get_write_value(w_val); + memset((char *) it->second.value, 0, 1024); + strncpy((char *) it->second.value,w_val, 1023); + //try{ + // push_change_event(attr.get_name(),(Tango::DevString *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + // push_archive_event(attr.get_name(),(Tango::DevString *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + //}catch(...){} + } + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + else + { + waitingDB = true; + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::write_ScalarDyn +} + +//-------------------------------------------------------- +/** + * Read SpectrumDyn attribute + * Description: + * + * Data type: Tango::DevDouble + * Attr type: Spectrum + */ +//-------------------------------------------------------- +void TestDevice::read_SpectrumDyn(Tango::Attribute &attr) +{ + //DEBUG_STREAM << "TestDevice::read_SpectrumDyn(Tango::Attribute &attr) entering... " << endl; + /*----- PROTECTED REGION ID(TestDevice::read_SpectrumDyn) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it = attr_data_map.find(attr.get_name()); + if(it == attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception reading attribute", + (const char*) "Attribute Not Found", __FUNCTION__, Tango::ERR); + + if(it->second.type == Tango::DEV_DOUBLE) + { + attr.set_value_date_quality((Tango::DevDouble *) it->second.value,it->second.ts,Tango::ATTR_VALID, it->second.size1, 0, false); + } + else if(it->second.type == Tango::DEV_LONG) + { + attr.set_value_date_quality((Tango::DevLong *) it->second.value,it->second.ts,Tango::ATTR_VALID, it->second.size1, 0, false); + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + attr.set_value_date_quality((Tango::DevBoolean *) it->second.value,it->second.ts,Tango::ATTR_VALID, it->second.size1, 0, false); + } + else if(it->second.type == Tango::DEV_STRING) + { + //NOT SUPPORTED + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::read_SpectrumDyn +} +//+---------------------------------------------------------------------------- +// +// method : TestDevice::write_SpectrumDyn +// +// description : Write SpectrumDyn attribute values to hardware. +// +//----------------------------------------------------------------------------- +void TestDevice::write_SpectrumDyn(Tango::WAttribute &attr) +{ + DEBUG_STREAM << "TestDevice::write_SpectrumDyn(Tango::WAttribute &attr) entering... "<< endl; + /*----- PROTECTED REGION ID(TestDevice::write_SpectrumDyn) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it = attr_data_map.find(attr.get_name()); + if(it == attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception reading attribute", + (const char*) "Attribute Not Found", __FUNCTION__, Tango::ERR); + + gettimeofday(&(it->second.ts), NULL); + size_t value_size = attr.get_write_value_length(); + it->second.size1 = value_size > MAX_SPECTRUM_SIZE ? MAX_SPECTRUM_SIZE : value_size; + if(it->second.type == Tango::DEV_DOUBLE) + { + const Tango::DevDouble * w_val; + attr.get_write_value(w_val); + for(size_t ind=0; ind < it->second.size1; ind++) + { + ((Tango::DevDouble *) it->second.value)[ind] = w_val[ind]; + } + try{ + push_change_event(attr.get_name(),(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + push_archive_event(attr.get_name(),(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_LONG) + { + const Tango::DevLong * w_val; + attr.get_write_value(w_val); + for(size_t ind=0; ind < it->second.size1; ind++) + { + ((Tango::DevLong *) it->second.value)[ind] = w_val[ind]; + } + try{ + push_change_event(attr.get_name(),(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + push_archive_event(attr.get_name(),(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + const Tango::DevBoolean * w_val; + attr.get_write_value(w_val); + for(size_t ind=0; ind<it->second.size1; ind++) + { + ((Tango::DevBoolean *) it->second.value)[ind] = w_val[ind]; + } + try{ + push_change_event(attr.get_name(),(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + push_archive_event(attr.get_name(),(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_STRING) + { + //NOT SUPPORTED + } + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + else + { + waitingDB = true; + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::write_SpectrumDyn +} + +//-------------------------------------------------------- +/** + * Read Ref attribute + * Description: + * + * Data type: Tango::DevString + * Attr type: Scalar + */ +//-------------------------------------------------------- +void TestDevice::read_Ref(Tango::Attribute &attr) +{ + //DEBUG_STREAM << "TestDevice::read_Ref(Tango::Attribute &attr) entering... " << endl; + /*----- PROTECTED REGION ID(TestDevice::read_Ref) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it; + int i=0; + for(it = attr_data_map.begin(), i=0; it != attr_data_map.end() && i<1024; it++) + { + if(it->second.type == Tango::DEV_DOUBLE) + attr_Ref_read[i++] = *((Tango::DevDouble *) it->second.value); + } + attr.set_value(attr_Ref_read, i); + /*----- PROTECTED REGION END -----*/ // TestDevice::read_Ref +} +//+---------------------------------------------------------------------------- +// +// method : TestDevice::write_Ref +// +// description : Write Ref attribute values to hardware. +// +//----------------------------------------------------------------------------- +void TestDevice::write_Ref(Tango::WAttribute &attr) +{ + DEBUG_STREAM << "TestDevice::write_Ref(Tango::Attribute &attr) entering... " << endl; + + // Retrieve write value + const Tango::DevDouble *w_val; + attr.get_write_value(w_val); + + /*----- PROTECTED REGION ID(TestDevice::write_Ref) ENABLED START -----*/ + int size_ref = attr.get_write_value_length(); + size_ref = size_ref<1024 ? size_ref : 1024; + double tmp; + int i=0; + attr.get_write_value(tmp); + + for(map<std::string,map_data_t>::iterator it=attr_data_map.begin(); it != attr_data_map.end() && i<size_ref; it++) + { + if(it->second.type == Tango::DEV_DOUBLE) + { + gettimeofday(&(it->second.ts), NULL); + *(Tango::DevDouble *) it->second.value = w_val[i++]; + try { + push_change_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + } + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + else + { + waitingDB = true; + } + + /*----- PROTECTED REGION END -----*/// TestDevice::write_Ref +} + +//-------------------------------------------------------- +/** + * Read Values attribute + * Description: + * + * Data type: Tango::DevString + * Attr type: Scalar + */ +//-------------------------------------------------------- +void TestDevice::read_Values(Tango::Attribute &attr) +{ + //DEBUG_STREAM << "TestDevice::read_Values(Tango::Attribute &attr) entering... " << endl; + /*----- PROTECTED REGION ID(TestDevice::read_Values) ENABLED START -----*/ + + map<std::string,map_data_t>::iterator it; + int i; + for(it = attr_data_map.begin(), i=0; it != attr_data_map.end() && i<1024; it++, i++) + { + stringstream val; + if(it->second.type == Tango::DEV_DOUBLE) + { + for(size_t ind=0; ind<it->second.size1; ind++) + { + val << std::setprecision(std::numeric_limits<Tango::DevDouble>::digits10+2) << ((Tango::DevDouble *) it->second.value)[ind]; + if(ind < it->second.size1-1) + val << ","; + } + sprintf(ref_array[i], "%s=%s", it->first.c_str(), val.str().c_str()); + } + else if(it->second.type == Tango::DEV_LONG) + { + for(size_t ind=0; ind<it->second.size1; ind++) + { + val << std::setprecision(std::numeric_limits<Tango::DevLong>::digits10+2) << ((Tango::DevLong *) it->second.value)[ind]; + if(ind < it->second.size1-1) + val << ","; + } + sprintf(ref_array[i], "%s=%s", it->first.c_str(), val.str().c_str()); + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + for(size_t ind=0; ind<it->second.size1; ind++) + { + val << (((Tango::DevBoolean *) it->second.value)[ind] ? "true" : "false"); + if(ind < it->second.size1-1) + val << ","; + } + sprintf(ref_array[i], "%s=%s", it->first.c_str(), val.str().c_str()); + } + else if(it->second.type == Tango::DEV_STRING) + { + sprintf(ref_array[i], "%s=%s", it->first.c_str(), ((char *) it->second.value)); + } + + } + attr.set_value(attr_Values_read, i); + /*----- PROTECTED REGION END -----*/ // TestDevice::read_Values +} +//+---------------------------------------------------------------------------- +// +// method : TestDevice::write_Ref +// +// description : Write Ref attribute values to hardware. +// +//----------------------------------------------------------------------------- +void TestDevice::write_Values(Tango::WAttribute &attr) +{ + DEBUG_STREAM << "TestDevice::write_Values(Tango::Attribute &attr) entering... " << endl; + + // Retrieve write value + const Tango::ConstDevString *w_val; + attr.get_write_value(w_val); + + /*----- PROTECTED REGION ID(TestDevice::write_Values) ENABLED START -----*/ + int size_ref = attr.get_write_value_length(); + size_ref = size_ref<1024 ? size_ref : 1024; + double tmp; + int i=0; + attr.get_write_value(tmp); + + for(i=0; i<size_ref; i++) + { + vector<string> results; + string_explode(w_val[i], "=", &results); + if(results.size() == 2) + { + map<std::string,map_data_t>::iterator it = attr_data_map.find(results[0]); + + if(it == attr_data_map.end()) + continue; + /*Tango::Except::throw_exception((const char*) "Exception writing attribute", + string("Attribute '") + string(results[0]) + string("' not found"), __FUNCTION__, Tango::ERR);*/ + gettimeofday(&(it->second.ts), NULL); + vector<string> values; + string_explode(results[1], ",", &values); + if(it->second.type == Tango::DEV_BOOLEAN) + { + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind<it->second.size1; val++) + { + if(*val == "true") + ((Tango::DevBoolean *) it->second.value)[ind++] = true; + else if(*val == "false") + ((Tango::DevBoolean *) it->second.value)[ind++] = false; + else + ((Tango::DevBoolean *) it->second.value)[ind++] = atoi(val->c_str()); + } + try { + set_write_value((Tango::DevBoolean *) it->second.value, results[0], it->second.size1); + push_change_event(it->first,(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1/*size*/, 0, false); + push_archive_event(it->first,(Tango::DevBoolean *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ it->second.size1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_LONG) + { + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind<it->second.size1; val++) + { + ((Tango::DevLong *) it->second.value)[ind++] = atoi(results[1].c_str()); + } + try { + set_write_value((Tango::DevLong *) it->second.value, results[0], it->second.size1); + push_change_event(it->first,(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(it->first,(Tango::DevLong *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_DOUBLE) + { + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind<it->second.size1; val++) + { + ((Tango::DevDouble *) it->second.value)[ind++] = atof(results[1].c_str()); + } + try { + set_write_value((Tango::DevDouble *) it->second.value, results[0], it->second.size1); + push_change_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + } + else if(it->second.type == Tango::DEV_STRING) + { + memset((char *) it->second.value, 0, 1024); + strncpy((char *) it->second.value,results[1].c_str(), 1023); + Tango::DevString str_ptr = (char *) it->second.value; + set_write_value((Tango::DevString ) str_ptr, results[0]); + } + } + } + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + else + { + waitingDB = true; + } + //and now push events + + /*----- PROTECTED REGION END -----*/// TestDevice::write_Ref +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::add_dynamic_attributes() + * Description : Create the dynamic attributes if any + * for specified device. + */ +//-------------------------------------------------------- +void TestDevice::add_dynamic_attributes() +{ + /*----- PROTECTED REGION ID(TestDevice::Class::add_dynamic_attributes) ENABLED START -----*/ + + // Add your own code to create and add dynamic attributes if any + DEBUG_STREAM << __FUNCTION__ << " entering..."; + if (attr_config.empty() == false) + { + for(vector<string>::iterator it = attr_config.begin();it != attr_config.end(); it++) + { + vector<string> results; + string_explode(*it, ":", &results); + try + { + create_dynamic_attribute(results); + } catch(Tango::DevFailed &e) + { + INFO_STREAM << __FUNCTION__ << " Error reading creating attribute='" << e.errors[0].desc << "'"; + } + } + } + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::add_dynamic_attributes + +} + + + +//======================================================== +// Command execution methods +//======================================================== + +//-------------------------------------------------------- +/** + * Execute the WriteAttrname command: + * Description: Delete all Double attributes and create new ones. + * + * @param argin List of double attributes to write. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::write_attrname(const Tango::DevVarDoubleStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::write_attrname() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::write_attrname) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + + double tmp; + int lens, lend, lenmin; + string name; + int i=0; + lens = argin->svalue.length(); + lend = argin->dvalue.length(); + lenmin = (lens <= lend) ? lens : lend; + + for(i=0; i<lenmin; i++) + { + name = string(argin->svalue[i]); + tmp = argin->dvalue[i]; + + map<std::string,map_data_t>::iterator it = attr_data_map.find(name); + if(it == attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception writing attribute", string("Attribute '") + name + + string("' not found"), __FUNCTION__, Tango::ERR); + + if(it->second.type != Tango::DEV_DOUBLE) + { + Tango::Except::throw_exception((const char*) "Exception writing attribute", string("Attribute '") + name + + string("' is not of type double"), __FUNCTION__, Tango::ERR); + } + else + { + gettimeofday(&(it->second.ts), NULL); + *(Tango::DevDouble *) it->second.value = tmp; + try { + push_change_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + push_archive_event(it->first,(Tango::DevDouble *)(it->second.value),/*NULL,Tango::ATTR_VALID,*/ 1/*size*/, 0, false); + }catch(...){} + timeval now; + gettimeofday(&now, NULL); + double dnow=now.tv_sec + (double)now.tv_usec/1000000.0; + if(dnow - dlastDB > minSaveDBPeriod) + { + save_configuration(); + dlastDB = dnow; + waitingDB = false; + } + else + { + waitingDB = true; + } + } + } + + /*----- PROTECTED REGION END -----*/// TestDevice::write_attrname + + return; +} + +//-------------------------------------------------------- +/** + * Execute the ReadAttrname command: + * Description: Delete all Double attributes and create new ones. + * + * @param argin List of new double attributes. + * @returns + */ +//-------------------------------------------------------- +Tango::DevVarDoubleArray * TestDevice::read_attrname(const Tango::DevVarStringArray *argin) +{ + Tango::DevVarDoubleArray *argout; + DEBUG_STREAM << "TestDevice::read_attrname() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::read_attrname) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + argout = new Tango::DevVarDoubleArray(); + vector<string> attributes; + attributes << (*argin); + double *tmp = new double[attributes.size()]; + string name; + + unsigned int index = 0; + + for(vector<string>::iterator its = attributes.begin(); its != attributes.end(); its++) + { + name = *its; + map<std::string, map_data_t>::iterator it = attr_data_map.find(name); + if(it == attr_data_map.end()) + { + delete [] tmp; + Tango::Except::throw_exception((const char*) "Exception reading attribute", string("Attribute '") + name + + string("' not found"), __FUNCTION__, Tango::ERR); + } + if(it->second.type == Tango::DEV_DOUBLE) + { + tmp[index++] = *((Tango::DevDouble *) it->second.value); + } + else + { + delete [] tmp; + Tango::Except::throw_exception((const char*) "Exception reading attribute", string("Attribute '") + name + + string("' is not of type double"), __FUNCTION__, Tango::ERR); + } + } + //if found all names + if(index == attributes.size()) + { + argout->length(index); + for(unsigned int i=0; i<index; i++) + (*argout)[i] = tmp[i]; + } + delete [] tmp; + /*----- PROTECTED REGION END -----*/// TestDevice::read_attrname + + return argout; +} + +//-------------------------------------------------------- +/** + * Execute the Config command: + * Description: Delete all Double attributes and create new ones. + * + * @param argin List of new double attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::config(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::config() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::config) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + +#if 1 + //TODO: verify memory leak + for(unsigned int i = 0; i < this->get_device_attr()->get_attr_nb(); i++) + { + string attr_name = get_device_attr()->get_attr_by_ind(i).get_name(); + if((attr_name != "State") && (attr_name != "Status") && (attr_name != "Ref") && (attr_name != "Values")) + { + DEBUG_STREAM << "TestDevice::config: i=" << i << " removing attribute: " + << attr_name << endl; + //TODO: update_idx=Flag set to true if the attributes object index + // used to retrieve the corresponding Attr object has to be + // updated (because one Attr object has been removed) + this->get_device_attr()->remove_attribute(attr_name, /*update_idx*/true); + i--; + } + } +#else + erase_dynamic_attributes() //TODO +#endif + + map<std::string,map_data_t>::iterator it; + for(it = attr_data_map.begin(); it != attr_data_map.end(); it++) + { + if(it->second.type == Tango::DEV_DOUBLE) + delete [] (Tango::DevDouble *) it->second.value; + else if(it->second.type == Tango::DEV_LONG) + delete [] (Tango::DevLong *) it->second.value; + else if(it->second.type == Tango::DEV_BOOLEAN) + delete [] (Tango::DevBoolean *) it->second.value; + else if(it->second.type == Tango::DEV_STRING) + delete [] (char *) it->second.value; + } + + try + { + attr_data_map.clear(); + DEBUG_STREAM << "TestDevice::config: attr_data_map cleared !" << endl; + } catch(...) + { + WARN_STREAM << "TestDevice::delete_device: Could not clear attr_data_map !" << endl; + } + + numAttr = attributes.size(); + for(int j = 0; j < numAttr; j++) + { + Tango::Attr *cspec; + char attrname[256]; + Tango::UserDefaultAttrProp attrprop; + + sprintf(attrname, "%s", attributes[j].c_str()); + cspec = new ScalarDynAttrib(attrname, Tango::DEV_DOUBLE); + /*sprintf(strtmp,"Dynamic Attribute %s reading channel %d ",attrname,num_ch); + if(unit != "") + { + attrprop.set_unit(unit.c_str()); + attrprop.set_standard_unit("1.0"); + attrprop.set_display_unit(unit.c_str()); + } + attrprop.set_format("%.9g"); + attrprop.set_description(strtmp);*/ + cspec->set_default_properties(attrprop); + add_attribute(cspec); + struct timeval curr_time; + //gettimeofday(&curr_time,NULL); + curr_time.tv_sec = 0; + + double *value = new double(); + map_data_t tmp; + tmp.value = value; + tmp.size1 = 1; + tmp.size2 = 0; + tmp.max1 = 1; + tmp.max2 = 1; + tmp.type = Tango::DEV_DOUBLE; + tmp.ts = curr_time; + attr_data_map.insert(make_pair(attrname, tmp)); + } + save_configuration(); + /*----- PROTECTED REGION END -----*/// TestDevice::config + return; +} + +//-------------------------------------------------------- +/** + * Execute the Add command: + * Description: Create new attributes. + * + * @param argin List of new attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::add(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::add() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::add) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + for(vector<string>::iterator it = attributes.begin();it != attributes.end(); it++) + { + DEBUG_STREAM << __func__ << ": adding '" << *it << "'"; + vector<string> results; + string_explode(*it, ":", &results); + create_dynamic_attribute(results); + } + save_configuration(); + + /*----- PROTECTED REGION END -----*/// TestDevice::add + return; +} + +//-------------------------------------------------------- +/** + * Execute the AddDouble command: + * Description: Create new attributes. + * + * @param argin List of new attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::add_double(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::add_double() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::add_double) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + for(vector<string>::iterator it = attributes.begin();it != attributes.end(); it++) + { + vector<string> results; + results.push_back(*it); + results.push_back("double"); + results.push_back("0"); + results.push_back("0"); + create_dynamic_attribute(results); + } + save_configuration(); + + /*----- PROTECTED REGION END -----*/// TestDevice::add_double + return; +} + +//-------------------------------------------------------- +/** + * Execute the AddLong command: + * Description: Create new attributes. + * + * @param argin List of new attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::add_long(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::add_long() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::add_long) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + for(vector<string>::iterator it = attributes.begin();it != attributes.end(); it++) + { + vector<string> results; + results.push_back(*it); + results.push_back("long"); + results.push_back("0"); + results.push_back("0"); + create_dynamic_attribute(results); + } + save_configuration(); + + /*----- PROTECTED REGION END -----*/// TestDevice::add_long + return; +} + +//-------------------------------------------------------- +/** + * Execute the AddBool command: + * Description: Create new attributes. + * + * @param argin List of new attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::add_bool(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::add_bool() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::add_bool) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + for(vector<string>::iterator it = attributes.begin();it != attributes.end(); it++) + { + vector<string> results; + results.push_back(*it); + results.push_back("bool"); + results.push_back("0"); + results.push_back("0"); + create_dynamic_attribute(results); + } + save_configuration(); + + /*----- PROTECTED REGION END -----*/// TestDevice::add_bool + return; +} + +//-------------------------------------------------------- +/** + * Execute the AddString command: + * Description: Create new attributes. + * + * @param argin List of new attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::add_string(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::add_string() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::add_string) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + for(vector<string>::iterator it = attributes.begin();it != attributes.end(); it++) + { + vector<string> results; + results.push_back(*it); + results.push_back("string"); + results.push_back("0"); + results.push_back("0"); + create_dynamic_attribute(results); + } + save_configuration(); + + /*----- PROTECTED REGION END -----*/// TestDevice::add_string + return; +} + +//-------------------------------------------------------- +/** + * Execute the Remove command: + * Description: Remove attributes. + * + * @param argin List of attributes. + * @returns + */ +//-------------------------------------------------------- +void TestDevice::remove(const Tango::DevVarStringArray *argin) +{ + DEBUG_STREAM << "TestDevice::remove() - " << device_name << endl; + /*----- PROTECTED REGION ID(TestDevice::remove) ENABLED START -----*/ + + // Add your own code + // POGO has generated a method core with argout allocation. + // If you would like to use a static reference without copying, + // See "TANGO Device Server Programmer's Manual" + // (chapter : Writing a TANGO DS / Exchanging data) + //------------------------------------------------------------ + + // Add your own code to control device here + vector<string> attributes; + attributes << (*argin); + + //TODO: verify memory leak + for(vector<string>::iterator it = attributes.begin(); it != attributes.end(); it++) + { + + if((*it != "State") && (*it != "Status") && (*it != "Ref")) + { + map<std::string,map_data_t>::iterator it_attr = attr_data_map.find(*it); + if(it_attr == attr_data_map.end()) + { + Tango::Except::throw_exception((const char*) "Exception removing attribute", string("Attribute '") + + string(*it) + string("' not found"), __FUNCTION__, Tango::ERR); + } + DEBUG_STREAM << __FUNCTION__ << ": removing attribute: " << *it; + //TODO: update_idx=Flag set to true if the attributes object index + // used to retrieve the corresponding Attr object has to be + // updated (because one Attr object has been removed) + this->get_device_attr()->remove_attribute(*it, /*update_idx*/true); + + try + { + if(it_attr->second.type == Tango::DEV_DOUBLE) + delete [] (Tango::DevDouble *) it_attr->second.value; + else if(it_attr->second.type == Tango::DEV_LONG) + delete [] (Tango::DevLong *) it_attr->second.value; + else if(it_attr->second.type == Tango::DEV_BOOLEAN) + delete [] (Tango::DevBoolean *) it_attr->second.value; + else if(it_attr->second.type == Tango::DEV_STRING) + delete [] (char *) it_attr->second.value; + attr_data_map.erase(/**it*/it_attr); + DEBUG_STREAM << __FUNCTION__ << ": " << *it << " removed from attr_data_map"; + } catch(...) + { + WARN_STREAM << __FUNCTION__ << ": ERROR removing " << *it << " from attr_data_map"; + } + save_configuration(); + } + } + + + /*----- PROTECTED REGION END -----*/// TestDevice::remove + return; +} + + /*----- PROTECTED REGION ID(TestDevice::namespace_ending) ENABLED START -----*/ + + + // Additional Methods +//+------------------------------------------------------------------ +/* + * method: TestDevice::create_dynamic_attribute + * Create and configure an attribute + */ +//+------------------------------------------------------------------ +void TestDevice::create_dynamic_attribute(vector<string> config) +{ + if(config.size() == 3 || config.size() == 4) + { + Tango::Attr *attr; + char attrname[256]; + Tango::UserDefaultAttrProp attrprop; + + struct timeval attr_time; + if(config.size() == 4) + { + vector<string> timestamp; + string_explode(config[3], ".", ×tamp); + + if(timestamp.size() == 2) + { + attr_time.tv_sec = atoi(timestamp[0].c_str()); + attr_time.tv_usec = atoi(timestamp[1].c_str()); + if(attr_time.tv_sec == 0) + gettimeofday(&attr_time,NULL); + } + else + { + gettimeofday(&attr_time,NULL); + } + } + else + { + gettimeofday(&attr_time,NULL); + } + + strcpy(attrname, config[0].c_str()); + if(attr_data_map.find(attrname) != attr_data_map.end()) + Tango::Except::throw_exception((const char*) "Exception creating attribute", + string("Attribute '") + string(attrname) + string("' already existing"), __FUNCTION__, Tango::ERR); + + vector<string> values; + string_explode(config[2], ",", &values); + + map_data_t tmp; + tmp.size1 = (values.size() > MAX_SPECTRUM_SIZE) ? MAX_SPECTRUM_SIZE : values.size(); + tmp.size2 = 0; + tmp.max1 = 1; + tmp.max2 = 1; + tmp.ts = attr_time; + size_t value_size = (tmp.size1 > 1) ? MAX_SPECTRUM_SIZE : 1; + if(config[1] == "bool") + { + tmp.type = Tango::DEV_BOOLEAN; + Tango::DevBoolean *value = new Tango::DevBoolean[value_size]; + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind < tmp.size1; val++) + { + if(*val == "true") + value[ind++] = true; + else if(*val == "false") + value[ind++] = false; + else + value[ind++] = atoi(val->c_str()); + } + tmp.value = value; + } + else if(config[1] == "long") + { + tmp.type = Tango::DEV_LONG; + Tango::DevLong *value = new Tango::DevLong[value_size]; + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind < tmp.size1; val++) + { + value[ind++] = atoi(val->c_str()); + } + tmp.value = value; + } + else if(config[1] == "double") + { + tmp.type = Tango::DEV_DOUBLE; + Tango::DevDouble *value = new Tango::DevDouble[value_size]; + size_t ind=0; + for(vector<string>::iterator val=values.begin(); val != values.end() && ind < tmp.size1; val++) + { + value[ind++] = atof(val->c_str()); + } + tmp.value = value; + } + else if(config[1] == "string") + { + tmp.size1 = 1; + tmp.type = Tango::DEV_STRING; + char *value = new char[1024]; + memset(value, 0, 1024); + strncpy(value, config[2].c_str(), 1023); + tmp.value = value; + } + + if(tmp.size1 == 1) + attr = new ScalarDynAttrib(attrname, tmp.type); + else + attr = new SpectrumDynAttrib(attrname, tmp.type, MAX_SPECTRUM_SIZE); + /*sprintf(strtmp,"Dynamic Attribute %s reading channel %d ",attrname,num_ch); + if(unit != "") + { + attrprop.set_unit(unit.c_str()); + attrprop.set_standard_unit("1.0"); + attrprop.set_display_unit(unit.c_str()); + } + attrprop.set_format("%.9g"); + attrprop.set_description(strtmp);*/ + attr->set_default_properties(attrprop); + add_attribute(attr); + set_change_event(attrname, true, false); + set_archive_event(attrname, true, false); + attr_data_map.insert(make_pair(attrname, tmp)); + + try + { + if(config[1] == "bool") + { + set_write_value(((Tango::DevBoolean *)tmp.value), attrname, tmp.size1); + } + else if(config[1] == "long") + { + set_write_value(((Tango::DevLong *)tmp.value), attrname, tmp.size1); + } + else if(config[1] == "double") + { + set_write_value(((Tango::DevDouble *)tmp.value), attrname, tmp.size1); + } + else if(config[1] == "string") + { + Tango::DevString str_ptr = (char *)tmp.value; + set_write_value((Tango::DevString)str_ptr, attrname); + } + } catch(Tango::DevFailed &e) + { + INFO_STREAM << __FUNCTION__ << " error seting write value=" << e.errors[0].desc; + } + } +} + + +//+------------------------------------------------------------------ +/* + * method: TestDevice::string_explode + * Explode a string + */ +//+------------------------------------------------------------------ +void TestDevice::string_explode(string str, string separator, vector<string>* results) +{ + size_t found; + + found = str.find_first_of(separator); + while(found != string::npos) { + if(found > 0) { + results->push_back(str.substr(0,found)); + } + str = str.substr(found+1); + found = str.find_first_of(separator); + } + if(str.length() > 0) { + results->push_back(str); + } + +} + +//+------------------------------------------------------------------ +/* + * method: TestDevice::save_configuration + * Save configuration on DB + */ +//+------------------------------------------------------------------ +void TestDevice::save_configuration() +{ + Tango::Database *db = new Tango::Database(); + try + { + db->set_timeout_millis(10000); //10 s timeout + vector<string> configuration; + char conf_str[256]; + + map<std::string,map_data_t>::iterator it; + for(it = attr_data_map.begin(); it != attr_data_map.end(); it++) + { + double ts = (double)(it->second.ts.tv_sec) + ((double)it->second.ts.tv_usec)/1000000.0; + if(it->second.size1 == 1) + { + if(it->second.type == Tango::DEV_DOUBLE) + sprintf(conf_str, "%s:double:%.16e:%f", it->first.c_str(), *((Tango::DevDouble *) it->second.value), ts); + else if(it->second.type == Tango::DEV_LONG) + sprintf(conf_str, "%s:long:%d:%f", it->first.c_str(), *((Tango::DevLong *) it->second.value), ts); + else if(it->second.type == Tango::DEV_BOOLEAN) + sprintf(conf_str, "%s:bool:%d:%f", it->first.c_str(), *((Tango::DevBoolean *) it->second.value), ts); + else if(it->second.type == Tango::DEV_STRING) + sprintf(conf_str, "%s:string:%s:%f", it->first.c_str(), ((char *) it->second.value), ts); + } + else if(it->second.size1 > 1) + { + stringstream val; + if(it->second.type == Tango::DEV_DOUBLE) + { + for(size_t i=0; i<it->second.size1; i++) + { + val << std::setprecision(std::numeric_limits<double>::digits10+2) << ((Tango::DevDouble *) it->second.value)[i]; + if(i < it->second.size1-1) + val << ","; + } + sprintf(conf_str, "%s:double:%s:%f", it->first.c_str(), val.str().c_str(), ts); + } + else if(it->second.type == Tango::DEV_LONG) + { + for(size_t i=0; i<it->second.size1; i++) + { + val << std::setprecision(std::numeric_limits<Tango::DevLong>::digits10+2) << ((Tango::DevLong *) it->second.value)[i]; + if(i < it->second.size1-1) + val << ","; + } + sprintf(conf_str, "%s:long:%s:%f", it->first.c_str(), val.str().c_str(), ts); + } + else if(it->second.type == Tango::DEV_BOOLEAN) + { + for(size_t i=0; i<it->second.size1; i++) + { + val << std::setprecision(std::numeric_limits<Tango::DevBoolean>::digits10+2) << ((Tango::DevBoolean *) it->second.value)[i]; + if(i < it->second.size1-1) + val << ","; + } + sprintf(conf_str, "%s:bool:%s:%f", it->first.c_str(), val.str().c_str(), ts); + } + else if(it->second.type == Tango::DEV_STRING) + { + //NOT SUPPORTED + } + } + + configuration.push_back(conf_str); + DEBUG_STREAM << __FUNCTION__ << " saving " << conf_str; + } + Tango::DbDatum config("Attr_config"); + Tango::DbData db_data_put; + config << configuration; + db_data_put.push_back(config); + db->put_device_property(get_name(), db_data_put); + //get_db_device()->put_property(db_data_put); + if(get_state()!=Tango::ON) + set_state(Tango::ON); + } catch(Tango::DevFailed &e) + { + INFO_STREAM << __FUNCTION__ << " error saving properties=" << e.errors[0].desc; + set_state(Tango::FAULT); + } + delete db; +} + + +long TestDevice::create_dynamic_command(const char* cmd_name, Tango::CmdArgType type_in, Tango::CmdArgType type_out, long size_in, long size_out) +{ + + std::vector< Tango::Command* >& command_list = get_device_class()->get_command_list(); + command_list.push_back(new CmdClass(cmd_name, + type_in, type_out, + "LV argin", + "LV argout", + Tango::OPERATOR, + size_in, + this)); + + return 0; +} + +template <typename Attr_type> void TestDevice::set_write_value(Attr_type *value, string attrname, long x) +{ + Tango::WAttribute& wattr = get_device_attr()->get_w_attr_by_name(attrname.c_str()); + if(x == 1) + wattr.set_write_value(*value); + else + wattr.set_write_value(value, x); +} + +void TestDevice::set_write_value(Tango::DevString value, string attrname) +{ + Tango::WAttribute& wattr = get_device_attr()->get_w_attr_by_name(attrname.c_str()); + wattr.set_write_value(value); +} + +/*************************************************************************** + + CmdClass class + +***************************************************************************/ +CORBA::Any *CmdClass::execute(Tango::DeviceImpl *device,const CORBA::Any &in_any) +{ + + cout << "CmdClass::" << get_name() << ": entering..." << endl; + + //const Tango::DevVarLongArray *argin; + //extract(in_any, argin); + + return new CORBA::Any(); + +} + +/*bool TestDevice::is_LVCmd_allowed(const CORBA::Any &any) +{ + // End of Generated Code + + // Re-Start of Generated Code +return true; +}*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::namespace_ending +} // namespace diff --git a/test/testdevice/src/TestDevice.h b/test/testdevice/src/TestDevice.h new file mode 100644 index 0000000000000000000000000000000000000000..d8b28e58ecb617e355ddae8a9fadd39aff563892 --- /dev/null +++ b/test/testdevice/src/TestDevice.h @@ -0,0 +1,320 @@ +/*----- PROTECTED REGION ID(TestDevice.h) ENABLED START -----*/ +//============================================================================= +// +// file : TestDevice.h +// +// description : Include for the TestDevice class. +// +// $Author: graziano $ +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef TestDevice_H +#define TestDevice_H + + +#include <tango.h> + +#define MAX_ATTR_SIZE 3000 +#define MAX_SPECTRUM_SIZE 100 + +/*----- PROTECTED REGION END -----*/ + + +/** + * TestDevice class Description: + * + */ + +namespace TestDevice_ns +{ + /*----- PROTECTED REGION ID(TestDevice::Additional Class Declarations) ENABLED START -----*/ + + // Additional Class Declarations +typedef struct { + void *value; //pointer to values + unsigned int size1; //actual size of dimension 1 + unsigned int size2; //actual size of dimension 2 + unsigned int max1; //max size of dimension 1 + unsigned int max2; //max size of dimension 2 + long type; //data type + unsigned char cmd_attr_type; //if data for attribute or for command + struct timeval ts; +} map_data_t; + +enum { typeDouble, typeLong, typeBool, typeString, typeUchar}; + /*----- PROTECTED REGION END -----*/ // TestDevice::Additional Class Declarations + + +class TestDevice : public TANGO_BASE_CLASS +{ + + friend class CmdClass; + /*----- PROTECTED REGION ID(TestDevice::Data Members) ENABLED START -----*/ + + // Add your own data members +protected: + + map<std::string,map_data_t> attr_data_map; + + void string_explode(string, string, vector<string>*); + void save_configuration(); + void create_dynamic_attribute(vector<string> config); + long create_dynamic_command(const char* cmd_name, Tango::CmdArgType type_in, Tango::CmdArgType type_out, long size_in, long size_out); + + template <typename Attr_type> void set_write_value(Attr_type *value, string attrname, long x = 1); + void set_write_value(Tango::DevString value, string attrname); + + timeval last_read; + int numAttr; + char ref_array[1024][256]; + double dlastDB; + bool waitingDB; + //Tango::DevString ref_ptr[1024]; + + /*----- PROTECTED REGION END -----*/ // TestDevice::Data Members + + +// Device property data members +public: + // Attr_config: + vector<string> attr_config; + // MinSaveDBPeriod: + Tango::DevLong minSaveDBPeriod; + + +// Attribute data members +public: + Tango::DevString *attr_ScalarDyn_read; + Tango::DevString attr_ScalarDyn_write; + Tango::DevDouble *attr_Ref_read; + Tango::DevString *attr_Values_read; + + +// Constructors and destructors +public: + /** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device Name + */ + TestDevice(Tango::DeviceClass *cl,string &s); + /** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device Name + */ + TestDevice(Tango::DeviceClass *cl,const char *s); + /** + * Constructs a newly allocated Command object. + * + * @param cl Class. + * @param s Device name + * @param d Device description. + */ + TestDevice(Tango::DeviceClass *cl,const char *s,const char *d); + /** + * The object destructor. + */ + ~TestDevice() {delete_device();}; + + + +// Miscellaneous methods +public: + /** + * will be called at device destruction or at init command. + */ + void delete_device(); + /** + * Initialize the device + */ + virtual void init_device(); + /** + * Read the device properties from database + */ + void get_device_property(); + /** + * Always executed method before execution command method. + */ + virtual void always_executed_hook(); + + +// Attribute methods +public: + /** + * Method : TestDevice::read_attr_hardware() + * Description : Hardware acquisition for attributes. + */ + virtual void read_attr_hardware(vector<long> &attr_list); + + + + /** + * ScalarDyn attribute related methods. + * Description: + * + * Data type: Tango::DevString + * Attr type: Scalar + */ + virtual void read_ScalarDyn(Tango::Attribute &attr); + virtual void write_ScalarDyn(Tango::WAttribute &attr); + virtual bool is_ScalarDyn_allowed(Tango::AttReqType type); + + + /** + * SpectrumDyn attribute related methods. + * Description: + * + * Data type: Tango::DevString + * Attr type: Spectrum + */ + virtual void read_SpectrumDyn(Tango::Attribute &attr); + virtual void write_SpectrumDyn(Tango::WAttribute &attr); + virtual bool is_SpectrumDyn_allowed(Tango::AttReqType type); + + + /** + * Ref attribute related methods. + * Description: + * + * Data type: Tango::DevDouble + * Attr type: Spectrum + */ + virtual void read_Ref(Tango::Attribute &attr); + virtual void write_Ref(Tango::WAttribute &attr); + virtual bool is_Ref_allowed(Tango::AttReqType type); + + + + /** + * Values attribute related methods. + * Description: + * + * Data type: Tango::DevString + * Attr type: Spectrum + */ + virtual void read_Values(Tango::Attribute &attr); + virtual void write_Values(Tango::WAttribute &attr); + virtual bool is_Values_allowed(Tango::AttReqType type); + + + + /** + * Method : TestDevice::add_dynamic_attributes() + * Description : Add dynamic attributes if any. + */ + void add_dynamic_attributes(); + +// Command related methods +public: + + + /** + * Command WriteAttrname related methods. + */ + void write_attrname(const Tango::DevVarDoubleStringArray *); + virtual bool is_WriteAttrname_allowed(const CORBA::Any &any); + + /** + * Command ReadAttrname related methods. + */ + Tango::DevVarDoubleArray *read_attrname(const Tango::DevVarStringArray *); + virtual bool is_ReadAttrname_allowed(const CORBA::Any &any); + + /** + * Command Config related methods. + */ + void config(const Tango::DevVarStringArray *); + virtual bool is_Config_allowed(const CORBA::Any &any); + + /** + * Command Add related methods. + */ + void add(const Tango::DevVarStringArray *); + virtual bool is_Add_allowed(const CORBA::Any &any); + + /** + * Command AddDouble related methods. + */ + void add_double(const Tango::DevVarStringArray *); + virtual bool is_AddDouble_allowed(const CORBA::Any &any); + + /** + * Command AddLong related methods. + */ + void add_long(const Tango::DevVarStringArray *); + virtual bool is_AddLong_allowed(const CORBA::Any &any); + + /** + * Command AddBool related methods. + */ + void add_bool(const Tango::DevVarStringArray *); + virtual bool is_AddBool_allowed(const CORBA::Any &any); + + /** + * Command AddString related methods. + */ + void add_string(const Tango::DevVarStringArray *); + virtual bool is_AddString_allowed(const CORBA::Any &any); + + /** + * Command Remove related methods. + */ + void remove(const Tango::DevVarStringArray *); + virtual bool is_Remove_allowed(const CORBA::Any &any); + + + + /*----- PROTECTED REGION ID(TestDevice::Additional Method prototypes) ENABLED START -----*/ + + // Additional Method prototypes + + /*----- PROTECTED REGION END -----*/ // TestDevice::Additional Method prototypes + +}; + + /*----- PROTECTED REGION ID(TestDevice::Additional Classes Definitions) ENABLED START -----*/ + + // Additional Classes definitions +class CmdClass : public Tango::Command +{ +public: + CmdClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level, + int size_in, + Tango::DeviceImpl *dev) + :Command(name,in,out,in_desc,out_desc, level) {_max_in=size_in; mydevice=(TestDevice *)dev;}; + + CmdClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + int size_in, + Tango::DeviceImpl *dev) + :Command(name,in,out) {_max_in=size_in; mydevice=(TestDevice *)dev;}; + ~CmdClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return true/*(static_cast<TangoLib *>(dev))->is_Cmd_allowed(any)*/;} + + int _max_in; + TestDevice *mydevice; +}; + + /*----- PROTECTED REGION END -----*/ // TestDevice::Additional Classes Definitions + +} // namespace + +#endif // TestDevice_H diff --git a/test/testdevice/src/TestDeviceClass.cpp b/test/testdevice/src/TestDeviceClass.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c9390d9fe775908aaae8557402424ecbb980c1a2 --- /dev/null +++ b/test/testdevice/src/TestDeviceClass.cpp @@ -0,0 +1,755 @@ +/*----- PROTECTED REGION ID(TestDeviceClass.cpp) ENABLED START -----*/ +//============================================================================= +// +// file : TestDeviceClass.cpp +// +// description : C++ source for the TestDeviceClass. A singleton +// class derived from DeviceClass. It implements the +// command list and all properties and methods required +// by the �name� once per process. +// +// $Author: graziano $ +// +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#include <TestDeviceClass.h> + +/*----- PROTECTED REGION END -----*/ + +//------------------------------------------------------------------- +/** + * Create TestDeviceClass singleton and + * return it in a C function for Python usage + */ +//------------------------------------------------------------------- +extern "C" { +#ifdef _TG_WINDOWS_ + +__declspec(dllexport) + +#endif + + Tango::DeviceClass *_create_TestDevice_class(const char *name) { + return TestDevice_ns::TestDeviceClass::init(name); + } +} + + +namespace TestDevice_ns +{ + + +//=================================================================== +// Initialize pointer for singleton pattern +//=================================================================== +TestDeviceClass *TestDeviceClass::_instance = NULL; + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::TestDeviceClass(string &s) + * description : constructor for the TestDeviceClass + * + * @param s The class name + */ +//-------------------------------------------------------- +TestDeviceClass::TestDeviceClass(string &s):DeviceClass(s) +{ + cout2 << "Entering TestDeviceClass constructor" << endl; + set_default_property(); + get_class_property(); + write_class_property(); + + /*----- PROTECTED REGION ID(TestDevice::Class::constructor) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::constructor + + cout2 << "Leaving TestDeviceClass constructor" << endl; +} + + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::~TestDeviceClass() + * description : destructor for the TestDeviceClass + */ +//-------------------------------------------------------- +TestDeviceClass::~TestDeviceClass() +{ + /*----- PROTECTED REGION ID(TestDevice::Class::destructor) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::destructor + + _instance = NULL; +} + + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::init + * description : Create the object if not already done. + * Otherwise, just return a pointer to the object + * + * @param name The class name + */ +//-------------------------------------------------------- +TestDeviceClass *TestDeviceClass::init(const char *name) +{ + if (_instance == NULL) + { + try + { + string s(name); + _instance = new TestDeviceClass(s); + } + catch (bad_alloc) + { + throw; + } + } + return _instance; +} + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::instance + * description : Check if object already created, + * and return a pointer to the object + */ +//-------------------------------------------------------- +TestDeviceClass *TestDeviceClass::instance() +{ + if (_instance == NULL) + { + cerr << "Class is not initialised !!" << endl; + exit(-1); + } + return _instance; +} + + + + +//=================================================================== +// Command execution method calls +//=================================================================== +//-------------------------------------------------------- +/** + * method : WriteAttrnameClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *WriteAttrnameClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "WriteAttrnameClass::execute(): arrived" << endl; + + const Tango::DevVarDoubleStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->write_attrname(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : ReadAttrnameClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *ReadAttrnameClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "ReadAttrnameClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + return insert((static_cast<TestDevice *>(device))->read_attrname(argin)); +} +//-------------------------------------------------------- +/** + * method : ConfigClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *ConfigClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "ConfigClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->config(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : AddClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *AddClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "AddClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->add(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : AddDoubleClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *AddDoubleClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "AddDoubleClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->add_double(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : AddLongClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *AddLongClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "AddLongClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->add_long(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : AddBoolClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *AddBoolClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "AddBoolClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->add_bool(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : AddStringClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *AddStringClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "AddStringClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->add_string(argin)); + return new CORBA::Any(); +} +//-------------------------------------------------------- +/** + * method : RemoveClass::execute() + * description : method to trigger the execution of the command. + * + * @param device The device on which the command must be executed + * @param in_any The command input data + * + * returns The command output data (packed in the Any object) + */ +//-------------------------------------------------------- +CORBA::Any *RemoveClass::execute(Tango::DeviceImpl *device, const CORBA::Any &in_any) +{ + cout2 << "RemoveClass::execute(): arrived" << endl; + + const Tango::DevVarStringArray *argin; + extract(in_any, argin); + + ((static_cast<TestDevice *>(device))->remove(argin)); + return new CORBA::Any(); +} + + + +//=================================================================== +// Properties management +//=================================================================== + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::get_class_property + * description : Get the class property for specified name. + * + * @param name The property name + */ +//-------------------------------------------------------- +Tango::DbDatum TestDeviceClass::get_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_prop.size() ; i++) + if (cl_prop[i].name == prop_name) + return cl_prop[i]; + // if not found, returns an empty DbDatum + return Tango::DbDatum(prop_name); +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::get_default_device_property()() + * Description : Return the default value for device property. + */ +//-------------------------------------------------------- +Tango::DbDatum TestDeviceClass::get_default_device_property(string &prop_name) +{ + for (unsigned int i=0 ; i<dev_def_prop.size() ; i++) + if (dev_def_prop[i].name == prop_name) + return dev_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::get_default_class_property()() + * Description : Return the default value for class property. + */ +//-------------------------------------------------------- +Tango::DbDatum TestDeviceClass::get_default_class_property(string &prop_name) +{ + for (unsigned int i=0 ; i<cl_def_prop.size() ; i++) + if (cl_def_prop[i].name == prop_name) + return cl_def_prop[i]; + // if not found, return an empty DbDatum + return Tango::DbDatum(prop_name); +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::get_class_property() + * Description : // Add your own code to initialize + */ +//-------------------------------------------------------- +void TestDeviceClass::get_class_property() +{ +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::set_default_property() + * Description : Set default property (class and device) for wizard. + * For each property, add to wizard property name and description. + * If default value has been set, add it to wizard property and. + * store it in a DbDatum. + */ +//-------------------------------------------------------- +void TestDeviceClass::set_default_property() +{ + string prop_name; + string prop_desc; + string prop_def; + vector<string> vect_data; + + // Set Default Class Properties + + // Set Default Device Properties + + prop_name = "Attr_config"; + prop_desc = ""; + prop_def = ""; + vect_data.clear(); + if (prop_def.length()>0) + { + Tango::DbDatum data(prop_name); + data << vect_data ; + dev_def_prop.push_back(data); + add_wiz_dev_prop(prop_name, prop_desc, prop_def); + } + else + add_wiz_dev_prop(prop_name, prop_desc); + + prop_name = "MinSaveDBPeriod"; + prop_desc = ""; + prop_def = "10"; + vect_data.clear(); + if (prop_def.length()>0) + { + Tango::DbDatum data(prop_name); + data << vect_data ; + dev_def_prop.push_back(data); + add_wiz_dev_prop(prop_name, prop_desc, prop_def); + } + else + add_wiz_dev_prop(prop_name, prop_desc); +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::write_class_property() + * Description : Set class description fields as property in database + */ +//-------------------------------------------------------- +void TestDeviceClass::write_class_property() +{ + // First time, check if database used + if (Tango::Util::_UseDb == false) + return; + + Tango::DbData data; + string classname = get_name(); + string header; + string::size_type start, end; + + // Put title + Tango::DbDatum title("ProjectTitle"); + string str_title("Storage Ring Access"); + title << str_title; + data.push_back(title); + + // Put Description + Tango::DbDatum description("Description"); + vector<string> str_desc; + str_desc.push_back(""); + description << str_desc; + data.push_back(description); + + // Put inheritance + Tango::DbDatum inher_datum("InheritedFrom"); + vector<string> inheritance; + inheritance.push_back("Device_Impl"); + inher_datum << inheritance; + data.push_back(inher_datum); + + // Call database and and values + get_db_class()->put_property(data); +} + + + + +//=================================================================== +// Factory methods +//=================================================================== + + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::device_factory + * description : Create the device object(s) + * and store them in the device list + * + * @param *devlist_ptr The device name list + */ +//-------------------------------------------------------- +void TestDeviceClass::device_factory(const Tango::DevVarStringArray *devlist_ptr) +{ + + /*----- PROTECTED REGION ID(TestDevice::Class::device_factory_before) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::device_factory_before + + // Create devices and add it into the device list + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + cout4 << "Device name : " << (*devlist_ptr)[i].in() << endl; + device_list.push_back(new TestDevice(this, (*devlist_ptr)[i])); + } + + // Manage dynamic attributes if any + erase_dynamic_attributes(devlist_ptr, get_class_attr()->get_attr_list()); + + // Export devices to the outside world + for (unsigned long i=1 ; i<=devlist_ptr->length() ; i++) + { + // Add dynamic attributes if any + TestDevice *dev = static_cast<TestDevice *>(device_list[device_list.size()-i]); + dev->add_dynamic_attributes(); + + // Check before if database used. + if ((Tango::Util::_UseDb == true) && (Tango::Util::_FileDb == false)) + export_device(dev); + else + export_device(dev, dev->get_name().c_str()); + } + + /*----- PROTECTED REGION ID(TestDevice::Class::device_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::device_factory_after + + +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::attribute_factory() + * Description : Create the attribute object(s) + * and store them in the attribute list + */ +//-------------------------------------------------------- +void TestDeviceClass::attribute_factory(vector<Tango::Attr *> &att_list) +{ + /*----- PROTECTED REGION ID(TestDevice::Class::attribute_factory_before) ENABLED START -----*/ + + // Add your own code + // Attribute : Ref + RefAttrib *ref = new RefAttrib(); + att_list.push_back(ref); + + // Attribute : Values + ValuesAttrib *values = new ValuesAttrib(); + att_list.push_back(values); + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::attribute_factory_before + + + // Create a list of static attributes + create_static_attribute_list(get_class_attr()->get_attr_list()); + + /*----- PROTECTED REGION ID(TestDevice::Class::attribute_factory_after) ENABLED START -----*/ + + // Add your own code + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::attribute_factory_after + +} + + +//-------------------------------------------------------- +/** + * Method : TestDevice::TestDeviceClass::command_factory() + * Description : Create the command object(s) + * and store them in the command list + */ +//-------------------------------------------------------- +void TestDeviceClass::command_factory() +{ + /*----- PROTECTED REGION ID(TestDevice::Class::command_factory_before) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::command_factory_before + + ConfigClass *pConfigCmd = + new ConfigClass("Config", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of attribute names (double) to be created removing everything else", + "", + Tango::OPERATOR); + command_list.push_back(pConfigCmd); + + AddClass *pAddCmd = + new AddClass("Add", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of attribute to be added.\nSyntax= name:type:value:timestamp.\ntype=double, long, bool, string.\ntimestamp=0 means now.", + "", + Tango::OPERATOR); + command_list.push_back(pAddCmd); + + AddDoubleClass *pAddDoubleCmd = + new AddDoubleClass("AddDouble", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of double attribute to be added.", + "", + Tango::OPERATOR); + command_list.push_back(pAddDoubleCmd); + + AddLongClass *pAddLongCmd = + new AddLongClass("AddLong", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of long attribute to be added.", + "", + Tango::OPERATOR); + command_list.push_back(pAddLongCmd); + + AddBoolClass *pAddBoolCmd = + new AddBoolClass("AddBool", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of boolean attribute to be added.", + "", + Tango::OPERATOR); + command_list.push_back(pAddBoolCmd); + + AddStringClass *pAddStringCmd = + new AddStringClass("AddString", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of string attribute to be added.", + "", + Tango::OPERATOR); + command_list.push_back(pAddStringCmd); + + RemoveClass *pRemoveCmd = + new RemoveClass("Remove", + Tango::DEVVAR_STRINGARRAY, Tango::DEV_VOID, + "Array of attribute names to be removed", + "", + Tango::OPERATOR); + command_list.push_back(pRemoveCmd); + + WriteAttrnameClass *pWriteAttrnameCmd = + new WriteAttrnameClass("WriteAttrname", + Tango::DEVVAR_DOUBLESTRINGARRAY, Tango::DEV_VOID, + "", + "", + Tango::OPERATOR); + command_list.push_back(pWriteAttrnameCmd); + + ReadAttrnameClass *pReadAttrnameCmd = + new ReadAttrnameClass("ReadAttrname", + Tango::DEVVAR_STRINGARRAY, Tango::DEVVAR_DOUBLEARRAY, + "", + "", + Tango::OPERATOR); + command_list.push_back(pReadAttrnameCmd); + + /*----- PROTECTED REGION ID(TestDevice::Class::command_factory_after) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::command_factory_after + +} + + + + +//=================================================================== +// Dynamic attributes related methods +//=================================================================== + + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::create_static_attribute_list + * description : Create the a list of static attributes + * + * @param att_list the ceated attribute list + */ +//-------------------------------------------------------- +void TestDeviceClass::create_static_attribute_list(vector<Tango::Attr *> &att_list) +{ + for (unsigned long i=0 ; i<att_list.size() ; i++) + { + string att_name(att_list[i]->get_name()); + transform(att_name.begin(), att_name.end(), att_name.begin(), ::tolower); + defaultAttList.push_back(att_name); + } + + cout2 << defaultAttList.size() << " attributes in default list" << endl; + + + /*----- PROTECTED REGION ID(TestDevice::Class::create_static_att_list) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::create_static_att_list + +} + + +//-------------------------------------------------------- +/** + * method : TestDeviceClass::erase_dynamic_attributes + * description : delete the dynamic attributes if any. + * + * @param devlist_ptr the device list pointer + * @param list of all attributes + */ +//-------------------------------------------------------- +void TestDeviceClass::erase_dynamic_attributes(const Tango::DevVarStringArray *devlist_ptr, vector<Tango::Attr *> &att_list) +{ + Tango::Util *tg = Tango::Util::instance(); + + for (unsigned long i=0 ; i<devlist_ptr->length() ; i++) + { + Tango::DeviceImpl *dev_impl = tg->get_device_by_name(((string)(*devlist_ptr)[i]).c_str()); + TestDevice *dev = static_cast<TestDevice *> (dev_impl); + + vector<Tango::Attribute *> &dev_att_list = dev->get_device_attr()->get_attribute_list(); + vector<Tango::Attribute *>::iterator ite_att; + for (ite_att=dev_att_list.begin() ; ite_att != dev_att_list.end() ; ++ite_att) + { + string att_name((*ite_att)->get_name_lower()); + if ((att_name == "state") || (att_name == "status") || (att_name == "ref")) + continue; + vector<string>::iterator ite_str = find(defaultAttList.begin(), defaultAttList.end(), att_name); + if (ite_str == defaultAttList.end()) + { + cout2 << att_name << " is a UNWANTED dynamic attribute for device " << (*devlist_ptr)[i] << endl; + Tango::Attribute &att = dev->get_device_attr()->get_attr_by_name(att_name.c_str()); + dev->remove_attribute(att_list[att.get_attr_idx()],true); + --ite_att; + } + } + } + /*----- PROTECTED REGION ID(TestDevice::Class::erase_dynamic_attributes) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::erase_dynamic_attributes + +} + + + + /*----- PROTECTED REGION ID(TestDevice::Class::Additional Methods) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Class::Additional Methods + +} // namespace diff --git a/test/testdevice/src/TestDeviceClass.h b/test/testdevice/src/TestDeviceClass.h new file mode 100644 index 0000000000000000000000000000000000000000..0a58fc92fb68008befb1887296f1d22a494db6b6 --- /dev/null +++ b/test/testdevice/src/TestDeviceClass.h @@ -0,0 +1,358 @@ +/*----- PROTECTED REGION ID(TestDeviceClass.h) ENABLED START -----*/ +//============================================================================= +// +// file : TestDeviceClass.h +// +// description : Include for the TestDeviceClass root class. +// This class is the singleton class for. +// the TestDevice device class.. +// It contains all properties and methods which the . +// TestDevice requires only once e.g. the commands. +// +// $Author: graziano $ +// +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + +#ifndef TestDeviceCLASS_H +#define TestDeviceCLASS_H + +#include <tango.h> +#include <TestDevice.h> + +/*----- PROTECTED REGION END -----*/ + +namespace TestDevice_ns +{ + /*----- PROTECTED REGION ID(TestDevice::classes for dynamic creation) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::classes for dynamic creation + + + +//========================================= +// Define classes for attributes +//========================================= +class SpectrumDynAttrib: public Tango::SpectrumAttr +{ +public: + SpectrumDynAttrib():SpectrumAttr("SpectrumDyn", + Tango::DEV_DOUBLE, Tango::READ_WRITE, MAX_SPECTRUM_SIZE) {}; + ~SpectrumDynAttrib() {}; + + SpectrumDynAttrib(const string &att_name, long data_type, long s_size):SpectrumAttr(att_name.c_str(), + data_type, Tango::READ_WRITE, s_size) {}; + + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<TestDevice *>(dev))->read_SpectrumDyn(att);} + virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) + {(static_cast<TestDevice *>(dev))->write_SpectrumDyn(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<TestDevice *>(dev))->is_SpectrumDyn_allowed(ty);} +}; + +class ScalarDynAttrib: public Tango::Attr +{ +public: + ScalarDynAttrib():Attr("ScalarDyn", + Tango::DEV_STRING, Tango::READ_WRITE) {}; + ~ScalarDynAttrib() {}; + + ScalarDynAttrib(const string &att_name, long data_type):Attr(att_name.c_str(), + data_type, Tango::READ_WRITE) {}; + + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<TestDevice *>(dev))->read_ScalarDyn(att);} + virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) + {(static_cast<TestDevice *>(dev))->write_ScalarDyn(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<TestDevice *>(dev))->is_ScalarDyn_allowed(ty);} +}; + +class RefAttrib: public Tango::SpectrumAttr +{ +public: + RefAttrib():SpectrumAttr("Ref", Tango::DEV_DOUBLE, Tango::READ_WRITE, 1024) {}; + ~RefAttrib() {}; + + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<TestDevice *>(dev))->read_Ref(att);} + virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) + {(static_cast<TestDevice *>(dev))->write_Ref(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<TestDevice *>(dev))->is_Ref_allowed(ty);} +}; + +class ValuesAttrib: public Tango::SpectrumAttr +{ +public: + ValuesAttrib():SpectrumAttr("Values", Tango::DEV_STRING, Tango::READ_WRITE, 1024) {}; + ~ValuesAttrib() {}; + + virtual void read(Tango::DeviceImpl *dev,Tango::Attribute &att) + {(static_cast<TestDevice *>(dev))->read_Values(att);} + virtual void write(Tango::DeviceImpl *dev,Tango::WAttribute &att) + {(static_cast<TestDevice *>(dev))->write_Values(att);} + virtual bool is_allowed(Tango::DeviceImpl *dev,Tango::AttReqType ty) + {return (static_cast<TestDevice *>(dev))->is_Values_allowed(ty);} +}; + + + + + + +//========================================= +// Define classes for commands +//========================================= +class WriteAttrnameClass : public Tango::Command +{ +public: + WriteAttrnameClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + WriteAttrnameClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~WriteAttrnameClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_WriteAttrname_allowed(any);} +}; +class ReadAttrnameClass : public Tango::Command +{ +public: + ReadAttrnameClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + ReadAttrnameClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~ReadAttrnameClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_ReadAttrname_allowed(any);} +}; +class ConfigClass : public Tango::Command +{ +public: + ConfigClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + ConfigClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~ConfigClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_Config_allowed(any);} +}; +class AddClass : public Tango::Command +{ +public: + AddClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + AddClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~AddClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_Add_allowed(any);} +}; +class AddDoubleClass : public Tango::Command +{ +public: + AddDoubleClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + AddDoubleClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~AddDoubleClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_AddDouble_allowed(any);} +}; +class AddLongClass : public Tango::Command +{ +public: + AddLongClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + AddLongClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~AddLongClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_AddLong_allowed(any);} +}; +class AddBoolClass : public Tango::Command +{ +public: + AddBoolClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + AddBoolClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~AddBoolClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_AddBool_allowed(any);} +}; +class AddStringClass : public Tango::Command +{ +public: + AddStringClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + AddStringClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~AddStringClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_AddString_allowed(any);} +}; +class RemoveClass : public Tango::Command +{ +public: + RemoveClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out, + const char *in_desc, + const char *out_desc, + Tango::DispLevel level) + :Command(name,in,out,in_desc,out_desc, level) {}; + + RemoveClass(const char *name, + Tango::CmdArgType in, + Tango::CmdArgType out) + :Command(name,in,out) {}; + ~RemoveClass() {}; + + virtual CORBA::Any *execute (Tango::DeviceImpl *dev, const CORBA::Any &any); + virtual bool is_allowed (Tango::DeviceImpl *dev, const CORBA::Any &any) + {return (static_cast<TestDevice *>(dev))->is_Remove_allowed(any);} +}; + + + +/** + * The TemplateDevServClass singleton definition + */ + +class +#ifdef _TG_WINDOWS_ + __declspec(dllexport) +#endif + TestDeviceClass : public Tango::DeviceClass +{ + /*----- PROTECTED REGION ID(TestDevice::Additionnal DServer data members) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::Additionnal DServer data members + + + +public: +// write class properties data members + Tango::DbData cl_prop; + Tango::DbData cl_def_prop; + Tango::DbData dev_def_prop; + +// Method prototypes + static TestDeviceClass *init(const char *); + static TestDeviceClass *instance(); + ~TestDeviceClass(); + Tango::DbDatum get_class_property(string &); + Tango::DbDatum get_default_device_property(string &); + Tango::DbDatum get_default_class_property(string &); + +protected: + TestDeviceClass(string &); + static TestDeviceClass *_instance; + void command_factory(); + void attribute_factory(vector<Tango::Attr *> &); + void write_class_property(); + void set_default_property(); + void get_class_property(); + string get_cvstag(); + string get_cvsroot(); + +private: + void device_factory(const Tango::DevVarStringArray *); + void create_static_attribute_list(vector<Tango::Attr *> &); + void erase_dynamic_attributes(const Tango::DevVarStringArray *,vector<Tango::Attr *> &); + vector<string> defaultAttList; + + +}; + +} // namespace + +#endif // TestDeviceCLASS_H + diff --git a/test/testdevice/src/TestDeviceStateMachine.cpp b/test/testdevice/src/TestDeviceStateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c2315781a3ea743b2217efbb009ac763373b514 --- /dev/null +++ b/test/testdevice/src/TestDeviceStateMachine.cpp @@ -0,0 +1,273 @@ +/*----- PROTECTED REGION ID(TestDeviceStateMachine.cpp) ENABLED START -----*/ + +//============================================================================= +// +// file : TestDeviceStateMachine.cpp +// +// description : C++ source for the �name� and its alowed +// methods for commands and attributes +// +// $Author: graziano $ +// +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + + + +#include <TestDevice.h> +#include <TestDeviceClass.h> + +/*----- PROTECTED REGION END -----*/ + + +/* + * TestDevice states description: + * + */ + +namespace TestDevice_ns +{ + +//================================================= +// Attributes Allowed Methods +//================================================= + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_ScalarDynState_allowed() + * Description : Execution allowed for ScalarDyn attribute. + */ +//-------------------------------------------------------- + +bool TestDevice::is_ScalarDyn_allowed(Tango::AttReqType type) +{ + // Not any excluded states for ScalarDyn attribute in READ access. + + /*----- PROTECTED REGION ID(TestDevice::is_ScalarDyn_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::is_ScalarDyn_allowed + + return true; +} + +bool TestDevice::is_SpectrumDyn_allowed(Tango::AttReqType type) +{ + // Not any excluded states for SpectrumDyn attribute in READ access. + + /*----- PROTECTED REGION ID(TestDevice::is_SpectrumDyn_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::is_SpectrumDyn_allowed + + return true; +} + +bool TestDevice::is_Ref_allowed(Tango::AttReqType type) +{ + // Not any excluded states for Ref attribute in READ access. + + /*----- PROTECTED REGION ID(TestDevice::is_Ref_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::is_Ref_allowed + + return true; +} + +bool TestDevice::is_Values_allowed(Tango::AttReqType type) +{ + // Not any excluded states for Values attribute in READ access. + + /*----- PROTECTED REGION ID(TestDevice::is_Values_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // TestDevice::is_Values_allowed + + return true; +} + + + /*----- PROTECTED REGION ID(TestDevice::are_dynamic_attributes_allowed) ENABLED START -----*/ + + // Add your code to check if dynamic attributes are alowed + + /*----- PROTECTED REGION END -----*/ // TestDevice::are_dynamic_attributes_allowed + + +//================================================= +// Commands Allowed Methods +//================================================= + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_WriteAttrname_allowed() + * Description : Execution allowed for WriteAttrname command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_WriteAttrname_allowed(const CORBA::Any &any) +{ + // Not any excluded states for WriteAttrname command. + + /*----- PROTECTED REGION ID(XPI::is_WriteAttrname_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_WriteAttrname_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_ReadAttrname_allowed() + * Description : Execution allowed for ReadAttrname command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_ReadAttrname_allowed(const CORBA::Any &any) +{ + // Not any excluded states for ReadAttrname command. + + /*----- PROTECTED REGION ID(XPI::is_ReadAttrname_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_ReadAttrname_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_Config_allowed() + * Description : Execution allowed for Config command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_Config_allowed(const CORBA::Any &any) +{ + // Not any excluded states for Config command. + + /*----- PROTECTED REGION ID(XPI::is_Config_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_Config_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_Add_allowed() + * Description : Execution allowed for Add command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_Add_allowed(const CORBA::Any &any) +{ + // Not any excluded states for Add command. + + /*----- PROTECTED REGION ID(XPI::is_Add_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_Add_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_AddDouble_allowed() + * Description : Execution allowed for AddDouble command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_AddDouble_allowed(const CORBA::Any &any) +{ + // Not any excluded states for AddDouble command. + + /*----- PROTECTED REGION ID(XPI::is_AddDouble_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_AddDouble_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_AddLong_allowed() + * Description : Execution allowed for AddLong command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_AddLong_allowed(const CORBA::Any &any) +{ + // Not any excluded states for AddLong command. + + /*----- PROTECTED REGION ID(XPI::is_AddLong_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_AddLong_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_AddBool_allowed() + * Description : Execution allowed for AddBool command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_AddBool_allowed(const CORBA::Any &any) +{ + // Not any excluded states for AddBool command. + + /*----- PROTECTED REGION ID(XPI::is_AddBool_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_AddBool_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_AddString_allowed() + * Description : Execution allowed for AddString command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_AddString_allowed(const CORBA::Any &any) +{ + // Not any excluded states for AddString command. + + /*----- PROTECTED REGION ID(XPI::is_AddString_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_AddString_allowed + + return true; +} + +//-------------------------------------------------------- +/** + * Method : TestDevice::is_Remove_allowed() + * Description : Execution allowed for Remove command. + */ +//-------------------------------------------------------- + +bool TestDevice::is_Remove_allowed(const CORBA::Any &any) +{ + // Not any excluded states for Remove command. + + /*----- PROTECTED REGION ID(XPI::is_Remove_allowed) ENABLED START -----*/ + + /*----- PROTECTED REGION END -----*/ // XPI::is_Remove_allowed + + return true; +} + + + + + /*----- PROTECTED REGION ID(TestDevice::are_dynamic_commands_allowed) ENABLED START -----*/ + + // Add your code to check if dynamic commands are alowed + + /*----- PROTECTED REGION END -----*/ // TestDevice::are_dynamic_commands_allowed + +} // namespace TestDevice_ns diff --git a/test/testdevice/src/main.cpp b/test/testdevice/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1dfa5f93bad2514a1e59ca645bcd2a4ea4157102 --- /dev/null +++ b/test/testdevice/src/main.cpp @@ -0,0 +1,60 @@ +/*PROTECTED REGION ID(TestDevice::main.cpp) ENABLED START*/ + +//============================================================================= +// +// file : TestDevice.cpp +// +// description : C++ source for the TestDevice device server main. +// The main rule is to initialise (and create) the Tango +// system and to create the DServerClass singleton. +// The main should be the same for every Tango device server. +// +// $Author: graziano $ +// +// +// +//============================================================================= +// This file is generated by POGO +// (Program Obviously used to Generate tango Object) +//============================================================================= + +#include <tango.h> + + +int main(int argc,char *argv[]) +{ + Tango::Util *tg = NULL; + try + { + // Initialise the device server + //---------------------------------------- + tg = Tango::Util::init(argc,argv); + + // Create the device server singleton + // which will create everything + //---------------------------------------- + tg->server_init(false); + + // Run the endless loop + //---------------------------------------- + cout << "Ready to accept request" << endl; + tg->server_run(); + } + catch (bad_alloc) + { + cout << "Can't allocate memory to store device object !!!" << endl; + cout << "Exiting" << endl; + } + catch (CORBA::Exception &e) + { + Tango::Except::print_exception(e); + + cout << "Received a CORBA_Exception" << endl; + cout << "Exiting" << endl; + } + if (tg!=NULL) + tg->server_cleanup(); + return(0); +} +/*PROTECTED REGION END*/ +//========================================================