forked from daneos/lutango
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3535cfc13b | |||
| 9bd078b221 | |||
| 1338eae773 | |||
| 59fb9aa2b3 | |||
| 5d527bc7f7 | |||
| 5c829d936f | |||
| b0be10e25d | |||
| 7d379fd5dd | |||
| 6cf75b0da6 | |||
| 71673c8ede | |||
| 361e3abead | |||
| 152734b329 | |||
| 69143b963b | |||
| a93c8292f1 | |||
| b07072a5a8 | |||
| fe640b0ae0 | |||
| ccf52c63ea | |||
| 619c05fc0d | |||
| 5f138b362b | |||
| 0d667035d3 | |||
| 2459ea8757 | |||
| 7e942585af | |||
| 22ef574220 | |||
| c4c42404eb | |||
| d9a4685c1f |
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
build/*
|
||||
lib/*
|
||||
tmp/*
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Grzegorz Kowalski
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
65
Makefile
Normal file
65
Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# luTango - Lua binding for Tango
|
||||
#
|
||||
# Copyright (C) 2023 Grzegorz Kowalski
|
||||
# See LICENSE for legal information
|
||||
#
|
||||
# file: Makefile
|
||||
#
|
||||
# Build configuration
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
VERSION=$(shell git describe --tags --always --dirty)\:$(shell date +'%Y%m%d')
|
||||
|
||||
SRC_DIR := src
|
||||
BUILD_DIR := build
|
||||
OUT_DIR := lib
|
||||
|
||||
ifeq ($(LUA_VERSION),)
|
||||
LUA_VERSION := 5.1
|
||||
endif
|
||||
|
||||
ifeq ($(PREFIX),)
|
||||
PREFIX := /usr/local/lib/lua/$(LUA_VERSION)/lutango
|
||||
endif
|
||||
|
||||
LUT_INCLUDE := $(SRC_DIR)
|
||||
|
||||
SRCS := $(shell find . -name '*.cpp')
|
||||
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
|
||||
SONAME := core.so.$(VERSION)
|
||||
SOLINK := core.so
|
||||
|
||||
CC = g++
|
||||
CXX = $(CC)
|
||||
|
||||
CFLAGS = -shared -fpic -D_REENTRANT -DVERSION=\"$(VERSION)\" -I$(LUT_INCLUDE) -Wl,--no-undefined
|
||||
CFLAGS += $(shell pkg-config --cflags tango lua$(LUA_VERSION))
|
||||
LDFLAGS = $(shell pkg-config --libs tango lua$(LUA_VERSION))
|
||||
CPPFLAGS += $(CFLAGS)
|
||||
|
||||
dir-guard=@mkdir -p $(@D)
|
||||
|
||||
.PHONY: default clean install
|
||||
|
||||
default: $(OUT_DIR)/$(SONAME)
|
||||
|
||||
$(OUT_DIR)/$(SONAME): $(OBJS)
|
||||
$(dir-guard)
|
||||
$(CXX) $^ $(CPPFLAGS) $(LDFLAGS) -o $@
|
||||
|
||||
$(BUILD_DIR)/%.cpp.o: %.cpp
|
||||
$(dir-guard)
|
||||
$(CXX) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
rm -rf lib
|
||||
|
||||
install:
|
||||
install -d $(PREFIX)
|
||||
install -m 644 $(SRC_DIR)/*.lua $(PREFIX)
|
||||
install -s -m 644 $(OUT_DIR)/$(SONAME) $(PREFIX)
|
||||
ln -sf $(PREFIX)/$(SONAME) $(PREFIX)/$(SOLINK)
|
||||
10
README.md
Normal file
10
README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# luTango - Lua binding for Tango
|
||||
|
||||
luTango is a module providing access to [Tango Control System](https://www.tango-controls.org/) with Lua.
|
||||
In it's current state, a basic subset of client API is available (DeviceProxy, AttributeProxy), although not all Tango types are supported.
|
||||
|
||||
The library has been tested with Lua 5.1, 5.2 and 5.3.
|
||||
|
||||
---
|
||||
|
||||
luTango is distributed under terms of MIT License. Please see LICENSE file for details.
|
||||
19
src/core/global.h
Normal file
19
src/core/global.h
Normal file
@ -0,0 +1,19 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: global.h
|
||||
//
|
||||
// Global values
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __GLOBAL_H__
|
||||
# define __GLOBAL_H__
|
||||
|
||||
#define LUTANGO "lutango"
|
||||
|
||||
#endif /* __GLOBAL_H__ */
|
||||
47
src/core/logging/log.cpp
Normal file
47
src/core/logging/log.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: log.cpp
|
||||
//
|
||||
// Logging facilities for core
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "log.h"
|
||||
|
||||
void _log(LogLevel level, const char* fmt, const char* _file, const char* _func, int _line, ...)
|
||||
{
|
||||
if(level <= current_log_level)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, _line);
|
||||
fprintf(stderr, "[%s]@[CORE:%s:%s:%d]: ", LogLevelLabels[level], _file, _func, _line);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void set_log_level(LogLevel level)
|
||||
{
|
||||
current_log_level = level;
|
||||
}
|
||||
|
||||
void lut_lua_register_log(lua_State* L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
va_lua_register(L, lut_log);
|
||||
lua_setfield(L, -2, "log");
|
||||
LUT_LOG(INFO, "Registered log table");
|
||||
}
|
||||
|
||||
int lut_log_set_log_level(lua_State* L)
|
||||
{
|
||||
int level = luaL_checknumber(L, 1);
|
||||
set_log_level((LogLevel)level);
|
||||
return 1;
|
||||
}
|
||||
52
src/core/logging/log.h
Normal file
52
src/core/logging/log.h
Normal file
@ -0,0 +1,52 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: log.h
|
||||
//
|
||||
// Logging facilities for core
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LOG_H__
|
||||
# define __LOG_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <core/lua.h>
|
||||
#include <core/lua/version_agnostic.h>
|
||||
|
||||
#define LUT_LOG(level, msg, ...) _log(level, msg, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
typedef enum _LogLevel
|
||||
{
|
||||
CRITICAL = 0,
|
||||
ERROR,
|
||||
WARNING,
|
||||
INFO,
|
||||
DEBUG,
|
||||
TRACE
|
||||
} LogLevel;
|
||||
|
||||
static const char* LogLevelLabels[] = {"CRITICAL", "ERROR", "WARNING", "INFO", "DEBUG", "TRACE"};
|
||||
static LogLevel current_log_level = WARNING;
|
||||
|
||||
// C API
|
||||
void _log(LogLevel level, const char* fmt, const char* _file, const char* _func, int _line, ...);
|
||||
void set_log_level(LogLevel level);
|
||||
|
||||
// Lua API
|
||||
void lut_lua_register_log(lua_State* L);
|
||||
int lut_log_set_log_level(lua_State* L);
|
||||
|
||||
static const luaL_Reg lut_log[] =
|
||||
{
|
||||
{ "set_log_level", lut_log_set_log_level },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* __LOG_H__ */
|
||||
29
src/core/lua.h
Normal file
29
src/core/lua.h
Normal file
@ -0,0 +1,29 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lua.h
|
||||
//
|
||||
// Lua includes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUA_INCLUDES_H__
|
||||
# define __LUA_INCLUDES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LUA_INCLUDES_H__ */
|
||||
21
src/core/lua/load.cpp
Normal file
21
src/core/lua/load.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: load.cpp
|
||||
//
|
||||
// Facilities for loading Lua code into core
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "load.h"
|
||||
|
||||
void load_lua_lib(lua_State* L, const char* name)
|
||||
{
|
||||
lua_getglobal(L, "require");
|
||||
lua_pushstring(L, name);
|
||||
lua_call(L, 1, 1);
|
||||
}
|
||||
21
src/core/lua/load.h
Normal file
21
src/core/lua/load.h
Normal file
@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: load.h
|
||||
//
|
||||
// Facilities for loading Lua code into core
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LOAD_H__
|
||||
# define __LOAD_H__
|
||||
|
||||
#include <core/lua.h>
|
||||
|
||||
void load_lua_lib(lua_State* L, const char* name);
|
||||
|
||||
#endif /* __LOAD_H__ */
|
||||
21
src/core/lua/object.cpp
Normal file
21
src/core/lua/object.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: object.cpp
|
||||
//
|
||||
// Lua objects manipulation in C++
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "object.h"
|
||||
|
||||
void *lut_getobj(lua_State *L, int idx)
|
||||
{
|
||||
LUT_LOG(TRACE, "Extracting object from userdata");
|
||||
return *(void**)lua_touserdata(L, idx);
|
||||
}
|
||||
22
src/core/lua/object.h
Normal file
22
src/core/lua/object.h
Normal file
@ -0,0 +1,22 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: object.h
|
||||
//
|
||||
// Lua objects manipulation in C++
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __OBJECT_H__
|
||||
# define __OBJECT_H__
|
||||
|
||||
#include <core/lua.h>
|
||||
#include <core/logging/log.h>
|
||||
|
||||
void *lut_getobj(lua_State *L, int idx);
|
||||
|
||||
#endif /* __OBJECT_H__ */
|
||||
64
src/core/lua/stack.cpp
Normal file
64
src/core/lua/stack.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: stack.cpp
|
||||
//
|
||||
// Lua stack manipulation
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "stack.h"
|
||||
|
||||
void push_bool_table(lua_State* L, std::vector<bool> v)
|
||||
{
|
||||
lua_newtable(L);
|
||||
for(int i = 0; i < v.size(); i++)
|
||||
{
|
||||
lua_pushboolean(L, v[i]);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
void push_string_table(lua_State* L, std::vector<std::string> v)
|
||||
{
|
||||
lua_newtable(L);
|
||||
for(int i = 0; i < v.size(); i++)
|
||||
{
|
||||
lua_pushstring(L, v[i].c_str());
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<bool> pop_bool_table(lua_State* L, int idx)
|
||||
{
|
||||
LUT_LOG(TRACE, "Popping boolean table from stack");
|
||||
std::vector<bool> v;
|
||||
lua_settop(L, idx);
|
||||
for(int i = 1; i <= va_lua_objlen(L, idx); i++)
|
||||
{
|
||||
lua_rawgeti(L, idx, i);
|
||||
bool vi = lua_toboolean(L, idx+1);
|
||||
v.push_back(vi);
|
||||
lua_settop(L, idx);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<std::string> pop_string_table(lua_State* L, int idx)
|
||||
{
|
||||
LUT_LOG(TRACE, "Popping string table from stack");
|
||||
std::vector<std::string> v;
|
||||
lua_settop(L, idx);
|
||||
for(int i = 1; i <= va_lua_objlen(L, idx); i++)
|
||||
{
|
||||
lua_rawgeti(L, idx, i);
|
||||
std::string vi = luaL_checkstring(L, idx+1);
|
||||
v.push_back(vi);
|
||||
lua_settop(L, idx);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
59
src/core/lua/stack.h
Normal file
59
src/core/lua/stack.h
Normal file
@ -0,0 +1,59 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: stack.h
|
||||
//
|
||||
// Lua stack manipulation
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __STACK_H__
|
||||
# define __STACK_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <core/lua.h>
|
||||
#include <core/lua/version_agnostic.h>
|
||||
#include <core/logging/log.h>
|
||||
|
||||
void push_bool_table(lua_State* L, std::vector<bool> value);
|
||||
void push_string_table(lua_State* L, std::vector<std::string> value);
|
||||
|
||||
std::vector<bool> pop_bool_table(lua_State* L, int idx);
|
||||
std::vector<std::string> pop_string_table(lua_State* L, int idx);
|
||||
|
||||
// CPP: non-specialized templates must be implemented in header file
|
||||
template<class T>
|
||||
void push_number_table(lua_State* L, std::vector<T> v)
|
||||
{
|
||||
lua_newtable(L);
|
||||
for(int i = 0; i < v.size(); i++)
|
||||
{
|
||||
lua_pushnumber(L, v[i]);
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::vector<T> pop_number_table(lua_State* L, int idx)
|
||||
{
|
||||
LUT_LOG(TRACE, "Popping number table from stack");
|
||||
std::vector<T> v;
|
||||
lua_settop(L, idx);
|
||||
for(int i = 1; i <= va_lua_objlen(L, idx); i++)
|
||||
{
|
||||
lua_rawgeti(L, idx, i);
|
||||
T vi = luaL_checknumber(L, idx+1);
|
||||
v.push_back(vi);
|
||||
lua_settop(L, idx);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif /* __STACK_H__ */
|
||||
25
src/core/lua/version_agnostic.cpp
Normal file
25
src/core/lua/version_agnostic.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: version_agnostic.cpp
|
||||
//
|
||||
// Facilitate different versions of Lua
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "version_agnostic.h"
|
||||
|
||||
void va_lua_register(lua_State* L, const luaL_Reg* reg)
|
||||
{
|
||||
# if (LUA_VERSION_NUM > 501)
|
||||
// Lua > 5.1
|
||||
luaL_setfuncs(L, reg, 0);
|
||||
# else
|
||||
// Lua 5.1
|
||||
luaL_register(L, NULL, reg);
|
||||
# endif
|
||||
}
|
||||
29
src/core/lua/version_agnostic.h
Normal file
29
src/core/lua/version_agnostic.h
Normal file
@ -0,0 +1,29 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: version_agnostic.h
|
||||
//
|
||||
// Facilitate different versions of Lua
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __VERSION_AGNOSTIC_H__
|
||||
# define __VERSION_AGNOSTIC_H__
|
||||
|
||||
#include <core/lua.h>
|
||||
|
||||
#if (LUA_VERSION_NUM > 501)
|
||||
// Lua > 5.1
|
||||
# define va_lua_objlen lua_rawlen
|
||||
#else
|
||||
// Lua 5.1
|
||||
# define va_lua_objlen lua_objlen
|
||||
#endif
|
||||
|
||||
void va_lua_register(lua_State* L, const luaL_Reg* reg);
|
||||
|
||||
#endif /* __VERSION_AGNOSTIC_H__ */
|
||||
39
src/core/lutango_core.cpp
Normal file
39
src/core/lutango_core.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lutango_core.cpp
|
||||
//
|
||||
// Core module entry point
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lutango_core.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int luaopen_lutango_core(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "luTango core open.");
|
||||
LUT_LOG(INFO, "luTango core v%s", VERSION);
|
||||
|
||||
lua_newtable(L);
|
||||
lut_lua_register_log(L);
|
||||
lut_lua_register_sys(L);
|
||||
lut_lua_register_DeviceProxy(L);
|
||||
lut_lua_register_AttributeProxy(L);
|
||||
|
||||
LUT_LOG(TRACE, "Core module table registered.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
38
src/core/lutango_core.h
Normal file
38
src/core/lutango_core.h
Normal file
@ -0,0 +1,38 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lutango_core.h
|
||||
//
|
||||
// Core module entry point
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUTANGO_H__
|
||||
# define __LUTANGO_H__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <core/lua.h>
|
||||
#include <core/logging/log.h>
|
||||
#include <core/sys/sys.h>
|
||||
|
||||
#include <core/tango/DeviceProxy/lut_DeviceProxy.h>
|
||||
#include <core/tango/AttributeProxy/lut_AttributeProxy.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// core is loaded as "lutango.core"
|
||||
int luaopen_lutango_core(lua_State* L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#endif /* __LUTANGO_H__ */
|
||||
47
src/core/sys/sys.cpp
Normal file
47
src/core/sys/sys.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: sys.cpp
|
||||
//
|
||||
// System utilities
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "sys.h"
|
||||
|
||||
void lut_lua_register_sys(lua_State* L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
va_lua_register(L, lut_sys);
|
||||
lua_setfield(L, -2, "sys");
|
||||
LUT_LOG(INFO, "Registered sys table");
|
||||
}
|
||||
|
||||
int lut_sys_version(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, VERSION);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_sys_tango_version(lua_State* L)
|
||||
{
|
||||
lua_pushstring(L, Tango::TgLibVers);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_sys_cpp_version(lua_State* L)
|
||||
{
|
||||
std::ostringstream cpp_ver;
|
||||
#ifdef __clang__
|
||||
cpp_ver << "clang++ " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__;
|
||||
#else
|
||||
cpp_ver << "GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__;
|
||||
#endif
|
||||
|
||||
lua_pushstring(L, cpp_ver.str().c_str());
|
||||
return 1;
|
||||
}
|
||||
36
src/core/sys/sys.h
Normal file
36
src/core/sys/sys.h
Normal file
@ -0,0 +1,36 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: sys.h
|
||||
//
|
||||
// System utilities
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SYS_H__
|
||||
# define __SYS_H__
|
||||
|
||||
#include <core/lua.h>
|
||||
#include <core/tango.h>
|
||||
#include <core/logging/log.h>
|
||||
#include <core/lua/version_agnostic.h>
|
||||
|
||||
// Lua API
|
||||
void lut_lua_register_sys(lua_State* L);
|
||||
int lut_sys_version(lua_State* L);
|
||||
int lut_sys_tango_version(lua_State* L);
|
||||
int lut_sys_cpp_version(lua_State* L);
|
||||
|
||||
static const luaL_Reg lut_sys[] =
|
||||
{
|
||||
{ "version", lut_sys_version },
|
||||
{ "tango_version", lut_sys_tango_version },
|
||||
{ "cpp_version", lut_sys_cpp_version },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* __SYS_H__ */
|
||||
27
src/core/tango.h
Normal file
27
src/core/tango.h
Normal file
@ -0,0 +1,27 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: tango.h
|
||||
//
|
||||
// Tango includes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __TANGO_INCLUDES_H__
|
||||
# define __TANGO_INCLUDES_H__
|
||||
|
||||
#include <tango/tango.h>
|
||||
|
||||
namespace lut_Tango
|
||||
{
|
||||
static const char* DispLevelNames[] = {"OPERATOR", "EXPERT", "DL_UNKNOWN"};
|
||||
static const char* AttrDataFormatNames[] = {"SCALAR", "SPECTRUM", "IMAGE", "FMT_UNKNOWN"};
|
||||
static const char* AttrMemorizedTypeNames[] = {"NOT_KNOWN", "NONE", "MEMORIZED", "MEMORIZED_WRITE_INIT"};
|
||||
static const char* AttrWriteTypeNames[] = {"READ", "READ_WITH_WRITE", "WRITE", "READ_WRITE", "WT_UNKNOWN"};
|
||||
}
|
||||
|
||||
#endif /* __TANGO_INCLUDES_H__ */
|
||||
282
src/core/tango/AttrCmdInfo/lut_AttrCmdInfo.cpp
Normal file
282
src/core/tango/AttrCmdInfo/lut_AttrCmdInfo.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_AttrCmdInfo.cpp
|
||||
//
|
||||
// Bindings for AttributeInfoEx and CommandInfo classes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lut_AttrCmdInfo.h"
|
||||
|
||||
void lut_AttributeInfo(lua_State* L, Tango::AttributeInfoEx info)
|
||||
{
|
||||
lua_createtable(L, 0, 25);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lut_AttributeAlarmInfo(L, info.alarms);
|
||||
lua_setfield(L, top, "alarms");
|
||||
|
||||
push_string_table(L, info.enum_labels);
|
||||
lua_setfield(L, top, "enum_labels");
|
||||
|
||||
lua_createtable(L, 3, 0);
|
||||
int events_top = lua_gettop(L);
|
||||
lut_ArchiveEventInfo(L, info.events.arch_event);
|
||||
lua_setfield(L, events_top, "archive_event");
|
||||
lut_ChangeEventInfo(L, info.events.ch_event);
|
||||
lua_setfield(L, events_top, "change_event");
|
||||
lut_PeriodicEventInfo(L, info.events.per_event);
|
||||
lua_setfield(L, events_top, "periodic_event");
|
||||
lua_setfield(L, top, "events");
|
||||
|
||||
lua_pushstring(L, lut_Tango::AttrMemorizedTypeNames[info.memorized]);
|
||||
lua_setfield(L, top, "memorized");
|
||||
|
||||
lua_pushstring(L, info.root_attr_name.c_str());
|
||||
lua_setfield(L, top, "root_attr_name");
|
||||
|
||||
lua_pushstring(L, lut_Tango::DispLevelNames[info.disp_level]);
|
||||
lua_setfield(L, top, "disp_level");
|
||||
|
||||
lua_pushstring(L, lut_Tango::AttrDataFormatNames[info.data_format]);
|
||||
lua_setfield(L, top, "data_format");
|
||||
|
||||
lua_pushstring(L, Tango::CmdArgTypeName[info.data_type]);
|
||||
lua_setfield(L, top, "tango_type");
|
||||
|
||||
lua_pushstring(L, to_lua_type_name(info.data_type).c_str());
|
||||
lua_setfield(L, top, "data_type");
|
||||
|
||||
lua_pushstring(L, info.description.c_str());
|
||||
lua_setfield(L, top, "description");
|
||||
|
||||
lua_pushstring(L, info.display_unit.c_str());
|
||||
lua_setfield(L, top, "display_unit");
|
||||
|
||||
lua_pushstring(L, info.format.c_str());
|
||||
lua_setfield(L, top, "format");
|
||||
|
||||
lua_pushstring(L, info.label.c_str());
|
||||
lua_setfield(L, top, "label");
|
||||
|
||||
lua_pushstring(L, info.max_alarm.c_str());
|
||||
lua_setfield(L, top, "max_alarm");
|
||||
|
||||
lua_pushstring(L, info.min_alarm.c_str());
|
||||
lua_setfield(L, top, "min_alarm");
|
||||
|
||||
lua_pushstring(L, info.max_value.c_str());
|
||||
lua_setfield(L, top, "max_value");
|
||||
|
||||
lua_pushstring(L, info.min_value.c_str());
|
||||
lua_setfield(L, top, "min_value");
|
||||
|
||||
lua_pushnumber(L, info.max_dim_x);
|
||||
lua_setfield(L, top, "max_dim_x");
|
||||
|
||||
lua_pushnumber(L, info.max_dim_y);
|
||||
lua_setfield(L, top, "max_dim_y");
|
||||
|
||||
lua_pushstring(L, info.name.c_str());
|
||||
lua_setfield(L, top, "name");
|
||||
|
||||
lua_pushstring(L, info.standard_unit.c_str());
|
||||
lua_setfield(L, top, "standard_unit");
|
||||
|
||||
lua_pushstring(L, info.unit.c_str());
|
||||
lua_setfield(L, top, "unit");
|
||||
|
||||
lua_pushstring(L, lut_Tango::AttrWriteTypeNames[info.writable]);
|
||||
lua_setfield(L, top, "writable");
|
||||
|
||||
lua_pushstring(L, info.writable_attr_name.c_str());
|
||||
lua_setfield(L, top, "writable_attr_name");
|
||||
|
||||
push_string_table(L, info.extensions);
|
||||
lua_setfield(L, top, "extensions");
|
||||
|
||||
push_string_table(L, info.sys_extensions);
|
||||
lua_setfield(L, top, "sys_extensions");
|
||||
}
|
||||
|
||||
void lut_CommandInfo(lua_State* L, Tango::CommandInfo info)
|
||||
{
|
||||
lua_createtable(L, 0, 9);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, lut_Tango::DispLevelNames[info.disp_level]);
|
||||
lua_setfield(L, top, "disp_level");
|
||||
|
||||
lua_pushstring(L, info.cmd_name.c_str());
|
||||
lua_setfield(L, top, "cmd_name");
|
||||
|
||||
lua_pushnumber(L, info.cmd_tag);
|
||||
lua_setfield(L, top, "cmd_tag");
|
||||
|
||||
lua_pushstring(L, to_lua_type_name(info.in_type).c_str());
|
||||
lua_setfield(L, top, "in_type");
|
||||
|
||||
lua_pushstring(L, Tango::CmdArgTypeName[info.in_type]);
|
||||
lua_setfield(L, top, "in_tango_type");
|
||||
|
||||
lua_pushstring(L, info.in_type_desc.c_str());
|
||||
lua_setfield(L, top, "in_type_desc");
|
||||
|
||||
lua_pushstring(L, to_lua_type_name(info.out_type).c_str());
|
||||
lua_setfield(L, top, "out_type");
|
||||
|
||||
lua_pushstring(L, Tango::CmdArgTypeName[info.out_type]);
|
||||
lua_setfield(L, top, "out_tango_type");
|
||||
|
||||
lua_pushstring(L, info.out_type_desc.c_str());
|
||||
lua_setfield(L, top, "out_type_desc");
|
||||
}
|
||||
|
||||
void lut_AttributeAlarmInfo(lua_State* L, Tango::AttributeAlarmInfo info)
|
||||
{
|
||||
lua_createtable(L, 0, 7);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, info.delta_t.c_str());
|
||||
lua_setfield(L, top, "delta_t");
|
||||
|
||||
lua_pushstring(L, info.delta_val.c_str());
|
||||
lua_setfield(L, top, "delta_val");
|
||||
|
||||
lua_pushstring(L, info.max_alarm.c_str());
|
||||
lua_setfield(L, top, "max_alarm");
|
||||
|
||||
lua_pushstring(L, info.max_warning.c_str());
|
||||
lua_setfield(L, top, "max_warning");
|
||||
|
||||
lua_pushstring(L, info.min_alarm.c_str());
|
||||
lua_setfield(L, top, "min_alarm");
|
||||
|
||||
lua_pushstring(L, info.min_warning.c_str());
|
||||
lua_setfield(L, top, "min_warning");
|
||||
|
||||
push_string_table(L, info.extensions);
|
||||
lua_setfield(L, top, "extensions");
|
||||
}
|
||||
|
||||
void lut_ArchiveEventInfo(lua_State* L, Tango::ArchiveEventInfo info)
|
||||
{
|
||||
lua_createtable(L, 0, 4);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, info.archive_abs_change.c_str());
|
||||
lua_setfield(L, top, "archive_abs_change");
|
||||
|
||||
lua_pushstring(L, info.archive_period.c_str());
|
||||
lua_setfield(L, top, "archive_period");
|
||||
|
||||
lua_pushstring(L, info.archive_rel_change.c_str());
|
||||
lua_setfield(L, top, "archive_rel_change");
|
||||
|
||||
push_string_table(L, info.extensions);
|
||||
lua_setfield(L, top, "extensions");
|
||||
}
|
||||
|
||||
void lut_ChangeEventInfo(lua_State* L, Tango::ChangeEventInfo info)
|
||||
{
|
||||
lua_createtable(L, 0, 3);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, info.abs_change.c_str());
|
||||
lua_setfield(L, top, "abs_change");
|
||||
|
||||
lua_pushstring(L, info.rel_change.c_str());
|
||||
lua_setfield(L, top, "rel_change");
|
||||
|
||||
push_string_table(L, info.extensions);
|
||||
lua_setfield(L, top, "extensions");
|
||||
}
|
||||
|
||||
void lut_PeriodicEventInfo(lua_State* L, Tango::PeriodicEventInfo info)
|
||||
{
|
||||
lua_createtable(L, 0, 2);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, info.period.c_str());
|
||||
lua_setfield(L, top, "period");
|
||||
|
||||
push_string_table(L, info.extensions);
|
||||
lua_setfield(L, top, "extensions");
|
||||
}
|
||||
|
||||
std::string to_lua_type_name(int type)
|
||||
{
|
||||
std::string type_name;
|
||||
switch(type)
|
||||
{
|
||||
case Tango::DEV_VOID: // 0 - void
|
||||
type_name = "nil";
|
||||
break;
|
||||
|
||||
case Tango::DEV_BOOLEAN: // 1 - bool
|
||||
type_name = "boolean";
|
||||
break;
|
||||
|
||||
case Tango::DEV_SHORT: // 2 - short
|
||||
case Tango::DEV_LONG: // 3 - long
|
||||
case Tango::DEV_FLOAT: // 4 - float
|
||||
case Tango::DEV_DOUBLE: // 5 - double
|
||||
case Tango::DEV_USHORT: // 6 - ushort
|
||||
case Tango::DEV_ULONG: // 7 - ulong
|
||||
case Tango::DEV_LONG64: // 23 - long64
|
||||
case Tango::DEV_ULONG64: // 24 - ulong64
|
||||
case Tango::DEV_INT: // 27 - int
|
||||
type_name = "number";
|
||||
break;
|
||||
|
||||
case Tango::DEV_STRING: // 8 - string
|
||||
case Tango::DEVVAR_CHARARRAY: // 9 - char[]
|
||||
case Tango::CONST_DEV_STRING: // 20 - const string
|
||||
case Tango::DEV_UCHAR: // 22 - uchar
|
||||
type_name = "string";
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_SHORTARRAY: // 10 - short[]
|
||||
case Tango::DEVVAR_LONGARRAY: // 11 - long[]
|
||||
case Tango::DEVVAR_FLOATARRAY: // 12 - float[]
|
||||
case Tango::DEVVAR_DOUBLEARRAY: // 13 - double[]
|
||||
case Tango::DEVVAR_USHORTARRAY: // 14 - ushort[]
|
||||
case Tango::DEVVAR_ULONGARRAY: // 15 - ulong[]
|
||||
case Tango::DEVVAR_LONG64ARRAY: // 25 - long64[]
|
||||
case Tango::DEVVAR_ULONG64ARRAY: // 26 - ulong64[]
|
||||
type_name = "table(number)";
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_STRINGARRAY: // 16 - string[]
|
||||
type_name = "table(string)";
|
||||
break;
|
||||
|
||||
case Tango::DEV_STATE: // 19 - DevState
|
||||
type_name = "DevState";
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_BOOLEANARRAY: // 21 - bool[]
|
||||
type_name = "table(boolean)";
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_STATEARRAY: // 31 - DevState[]
|
||||
type_name = "table(DevState)";
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_LONGSTRINGARRAY: // 17 - longstring[] ???
|
||||
case Tango::DEVVAR_DOUBLESTRINGARRAY: // 18 - doublestring[] ???
|
||||
case Tango::DEV_ENCODED: // 28 - DevEncoded
|
||||
case Tango::DEV_ENUM: // 29 - DevEnum
|
||||
case Tango::DEV_PIPE_BLOB: // 30 - DevPipeBlob
|
||||
case Tango::DATA_TYPE_UNKNOWN: // 32 - unknown
|
||||
default:
|
||||
type_name = "-not-supported-";
|
||||
break;
|
||||
}
|
||||
return type_name;
|
||||
}
|
||||
31
src/core/tango/AttrCmdInfo/lut_AttrCmdInfo.h
Normal file
31
src/core/tango/AttrCmdInfo/lut_AttrCmdInfo.h
Normal file
@ -0,0 +1,31 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_AttrCmdInfo.h
|
||||
//
|
||||
// Bindings for AttributeInfoEx and CommandInfo classes
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUT_ATTRCMDINFO_H__
|
||||
# define __LUT_ATTRCMDINFO_H__
|
||||
|
||||
#include <core/tango.h>
|
||||
#include <core/lua.h>
|
||||
#include <core/logging/log.h>
|
||||
#include <core/lua/stack.h>
|
||||
|
||||
void lut_AttributeInfo(lua_State* L, Tango::AttributeInfoEx info);
|
||||
void lut_CommandInfo(lua_State* L, Tango::CommandInfo info);
|
||||
void lut_AttributeAlarmInfo(lua_State* L, Tango::AttributeAlarmInfo info);
|
||||
void lut_ArchiveEventInfo(lua_State* L, Tango::ArchiveEventInfo info);
|
||||
void lut_ChangeEventInfo(lua_State* L, Tango::ChangeEventInfo info);
|
||||
void lut_PeriodicEventInfo(lua_State* L, Tango::PeriodicEventInfo info);
|
||||
|
||||
std::string to_lua_type_name(int type);
|
||||
|
||||
#endif /* __LUT_ATTRCMDINFO_H__ */
|
||||
148
src/core/tango/AttributeProxy/lut_AttributeProxy.cpp
Normal file
148
src/core/tango/AttributeProxy/lut_AttributeProxy.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_AttributeProxy.cpp
|
||||
//
|
||||
// Binding for AttributeProxy class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lut_AttributeProxy.h"
|
||||
|
||||
// WRAPPER CLASS --------------------------------------------------------------
|
||||
AttributeProxyWrapper::AttributeProxyWrapper(const char* name)
|
||||
{
|
||||
attr = new Tango::AttributeProxy(name);
|
||||
info = attr->get_config();
|
||||
}
|
||||
|
||||
AttributeProxyWrapper::~AttributeProxyWrapper()
|
||||
{
|
||||
delete attr;
|
||||
}
|
||||
|
||||
// TANGO API ------------------------------------------------------------------
|
||||
int lut_AttributeProxy_state(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API AttributeProxy:state()");
|
||||
AttributeProxyWrapper* udata = (AttributeProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string attr_name = udata->attr->name();
|
||||
|
||||
try
|
||||
{
|
||||
lut_DevState(L, udata->attr->state());
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, attr_name.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_AttributeProxy_status(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API AttributeProxy:status()");
|
||||
AttributeProxyWrapper* udata = (AttributeProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string attr_name = udata->attr->name();
|
||||
|
||||
try
|
||||
{
|
||||
lua_pushstring(L, udata->attr->status().c_str());
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, attr_name.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_AttributeProxy_get_config(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API AttributeProxy:get_config()");
|
||||
AttributeProxyWrapper* udata = (AttributeProxyWrapper*)lut_getobj(L, 1);
|
||||
|
||||
lut_AttributeInfo(L, udata->info);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// LUA API --------------------------------------------------------------------
|
||||
void lut_lua_register_AttributeProxy(lua_State* L)
|
||||
{
|
||||
// create table, register funcs and add it as AttributeProxy to lutango's table
|
||||
lua_newtable(L);
|
||||
va_lua_register(L, lut_AttributeProxy);
|
||||
lua_setfield(L, -2, "AttributeProxy");
|
||||
|
||||
LUT_LOG(INFO, "Registered AttributeProxy table");
|
||||
}
|
||||
|
||||
int lut_AttributeProxy_create(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L, 1);
|
||||
|
||||
LUT_LOG(TRACE, "LUA API AttributeProxy:create(%s)", name);
|
||||
|
||||
// push userdata containing the DeviceProxy
|
||||
AttributeProxyWrapper** udata = (AttributeProxyWrapper**)lua_newuserdata(L, sizeof(AttributeProxyWrapper*));
|
||||
try
|
||||
{
|
||||
*udata = new AttributeProxyWrapper(name);
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, name);
|
||||
}
|
||||
|
||||
// set metatable, that allows userdata proper garbage collection
|
||||
luaL_newmetatable(L, LUT_ATTRIBUTEPROXY);
|
||||
va_lua_register(L, lut_AttributeProxy_userdata);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_AttributeProxy_destroy(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "LUA API AttributeProxy:destroy()");
|
||||
AttributeProxyWrapper* udata = (AttributeProxyWrapper*)lut_getobj(L, 1);
|
||||
delete udata;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// aka read / write
|
||||
int lut_AttributeProxy_call(lua_State* L)
|
||||
{
|
||||
AttributeProxyWrapper* udata = (AttributeProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string attr_name = udata->attr->name();
|
||||
|
||||
LUT_LOG(TRACE, "LUA API AttributeProxy(%s):call(...)", attr_name.c_str());
|
||||
|
||||
try
|
||||
{
|
||||
if(lua_isnoneornil(L, 2))
|
||||
{
|
||||
// called without arguments - read attribute
|
||||
LUT_LOG(TRACE, "Reading attribute %s", attr_name.c_str());
|
||||
lut_fromTangoType(L, udata->attr->read(), udata->info.data_type, udata->info.data_format);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tango::DeviceAttribute v = lut_toTangoType<Tango::DeviceAttribute>(L, 2, udata->info.data_type, udata->info.data_format);
|
||||
v.set_name(attr_name);
|
||||
udata->attr->write(v);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, attr_name.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
78
src/core/tango/AttributeProxy/lut_AttributeProxy.h
Normal file
78
src/core/tango/AttributeProxy/lut_AttributeProxy.h
Normal file
@ -0,0 +1,78 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_AttributeProxy.h
|
||||
//
|
||||
// Binding for AttributeProxy class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUT_ATTRIBUTEPROXY_H__
|
||||
# define __LUT_ATTRIBUTEPROXY_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <core/tango.h>
|
||||
#include <core/lua.h>
|
||||
#include <core/utils.h>
|
||||
|
||||
#include <core/lua/object.h>
|
||||
#include <core/lua/stack.h>
|
||||
#include <core/lua/version_agnostic.h>
|
||||
#include <core/logging/log.h>
|
||||
|
||||
#include <core/tango/types.h>
|
||||
#include <core/tango/AttrCmdInfo/lut_AttrCmdInfo.h>
|
||||
#include <core/tango/DevState/lut_DevState.h>
|
||||
#include <core/tango/DevFailed/lut_DevFailed.h>
|
||||
|
||||
#define LUT_ATTRIBUTEPROXY "lut_AttributeProxy"
|
||||
|
||||
// Wrapper class
|
||||
class AttributeProxyWrapper
|
||||
{
|
||||
public:
|
||||
Tango::AttributeProxy* attr;
|
||||
Tango::AttributeInfoEx info;
|
||||
|
||||
AttributeProxyWrapper(const char* name);
|
||||
~AttributeProxyWrapper();
|
||||
};
|
||||
|
||||
// Tango API
|
||||
int lut_AttributeProxy_state(lua_State* L);
|
||||
int lut_AttributeProxy_status(lua_State* L);
|
||||
int lut_AttributeProxy_get_config(lua_State* L);
|
||||
|
||||
// Lua API
|
||||
void lut_lua_register_AttributeProxy(lua_State* L);
|
||||
int lut_AttributeProxy_create(lua_State* L);
|
||||
int lut_AttributeProxy_destroy(lua_State* L);
|
||||
int lut_AttributeProxy_call(lua_State* L);
|
||||
|
||||
static const luaL_Reg lut_AttributeProxy[] =
|
||||
{
|
||||
// Lua API
|
||||
{ "create", lut_AttributeProxy_create },
|
||||
{ "call", lut_AttributeProxy_call },
|
||||
|
||||
// Tango API
|
||||
{ "state", lut_AttributeProxy_state },
|
||||
{ "status", lut_AttributeProxy_status },
|
||||
{ "get_config", lut_AttributeProxy_get_config},
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg lut_AttributeProxy_userdata[] =
|
||||
{
|
||||
{ "__gc", lut_AttributeProxy_destroy },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* __LUT_ATTRIBUTEPROXY_H__ */
|
||||
71
src/core/tango/DevFailed/lut_DevFailed.cpp
Normal file
71
src/core/tango/DevFailed/lut_DevFailed.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DevFailed.cpp
|
||||
//
|
||||
// Binding for DevFailed exceptions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lut_DevFailed.h"
|
||||
|
||||
int lut_DevFailed(lua_State* L, Tango::DevFailed e, const char* source)
|
||||
{
|
||||
int nerr = e.errors.length();
|
||||
lua_createtable(L, nerr, 2);
|
||||
int top = lua_gettop(L);
|
||||
|
||||
lua_pushstring(L, source);
|
||||
lua_setfield(L, -2, "source");
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, -2, "is_DevFailed");
|
||||
|
||||
for(int i = 0; i < nerr; i++)
|
||||
{
|
||||
lua_pushnumber(L, i+1);
|
||||
lua_createtable(L, 0, 4);
|
||||
|
||||
lua_pushstring(L, severity_str(e.errors[i].severity));
|
||||
lua_setfield(L, -2, "severity");
|
||||
|
||||
lua_pushstring(L, e.errors[i].reason);
|
||||
lua_setfield(L, -2, "reason");
|
||||
|
||||
lua_pushstring(L, e.errors[i].desc);
|
||||
lua_setfield(L, -2, "desc");
|
||||
|
||||
lua_pushstring(L, e.errors[i].origin);
|
||||
lua_setfield(L, -2, "origin");
|
||||
|
||||
lua_settable(L, top);
|
||||
}
|
||||
|
||||
return lua_error(L);
|
||||
}
|
||||
|
||||
const char* severity_str(Tango::ErrSeverity s)
|
||||
{
|
||||
switch(s)
|
||||
{
|
||||
case Tango::WARN:
|
||||
return "WARNING";
|
||||
break;
|
||||
|
||||
case Tango::ERR:
|
||||
return "ERROR";
|
||||
break;
|
||||
|
||||
case Tango::PANIC:
|
||||
return "PANIC";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
}
|
||||
23
src/core/tango/DevFailed/lut_DevFailed.h
Normal file
23
src/core/tango/DevFailed/lut_DevFailed.h
Normal file
@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DevFailed.h
|
||||
//
|
||||
// Binding for DevFailed exceptions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUT_DEVFAILED_H__
|
||||
# define __LUT_DEVFAILED_H__
|
||||
|
||||
#include <core/tango.h>
|
||||
#include <core/lua.h>
|
||||
|
||||
int lut_DevFailed(lua_State* L, Tango::DevFailed e, const char* source);
|
||||
const char* severity_str(Tango::ErrSeverity s);
|
||||
|
||||
#endif /* __LUT_DEVFAILED_H__ */
|
||||
27
src/core/tango/DevState/lut_DevState.cpp
Normal file
27
src/core/tango/DevState/lut_DevState.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DevState.cpp
|
||||
//
|
||||
// Binding for DevState type
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lut_DevState.h"
|
||||
|
||||
void lut_DevState(lua_State* L, Tango::DevState state)
|
||||
{
|
||||
LUT_LOG(TRACE, "Converting DevState(%d) into lut_DevState", state);
|
||||
|
||||
load_lua_lib(L, LUTANGO);
|
||||
lua_getglobal(L, LUTANGO);
|
||||
|
||||
lua_getfield(L, -2, "DevState");
|
||||
lua_pushnumber(L, (int)state);
|
||||
|
||||
lua_call(L, 1, 1);
|
||||
}
|
||||
25
src/core/tango/DevState/lut_DevState.h
Normal file
25
src/core/tango/DevState/lut_DevState.h
Normal file
@ -0,0 +1,25 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DevState.h
|
||||
//
|
||||
// Binding for DevState type
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUT_DEVSTATE_H__
|
||||
# define __LUT_DEVSTATE_H__
|
||||
|
||||
#include <core/tango.h>
|
||||
#include <core/lua.h>
|
||||
#include <core/global.h>
|
||||
#include <core/logging/log.h>
|
||||
#include <core/lua/load.h>
|
||||
|
||||
void lut_DevState(lua_State* L, Tango::DevState state);
|
||||
|
||||
#endif /* __LUT_DEVSTATE_H__ */
|
||||
315
src/core/tango/DeviceProxy/lut_DeviceProxy.cpp
Normal file
315
src/core/tango/DeviceProxy/lut_DeviceProxy.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DeviceProxy.cpp
|
||||
//
|
||||
// Binding for DeviceProxy class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "lut_DeviceProxy.h"
|
||||
|
||||
// WRAPPER CLASS --------------------------------------------------------------
|
||||
DeviceProxyWrapper::DeviceProxyWrapper(const char* name)
|
||||
{
|
||||
dev = new Tango::DeviceProxy(name);
|
||||
Tango::AttributeInfoListEx* attrlist = dev->attribute_list_query_ex();
|
||||
Tango::CommandInfoList* cmdlist = dev->command_list_query();
|
||||
|
||||
for(int i = 0; i < attrlist->size(); i++)
|
||||
attr_info[(*attrlist)[i].name] = (*attrlist)[i];
|
||||
for(int i = 0; i < cmdlist->size(); i++)
|
||||
cmd_info[(*cmdlist)[i].cmd_name] = (*cmdlist)[i];
|
||||
|
||||
delete attrlist;
|
||||
delete cmdlist;
|
||||
}
|
||||
|
||||
DeviceProxyWrapper::~DeviceProxyWrapper()
|
||||
{
|
||||
delete dev;
|
||||
}
|
||||
|
||||
// COMMAND WRAPPER ------------------------------------------------------------
|
||||
int __cmd_wrapper(lua_State* L)
|
||||
{
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lua_touserdata(L, lua_upvalueindex(1));
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
const char* cmd_name = lua_tostring(L, lua_upvalueindex(2));
|
||||
std::string full_name = build_name(dev_name, cmd_name, true);
|
||||
|
||||
LUT_LOG(TRACE, "Running command wrapper %s", full_name.c_str());
|
||||
|
||||
int in_type = udata->cmd_info[cmd_name].in_type;
|
||||
int out_type = udata->cmd_info[cmd_name].out_type;
|
||||
LUT_LOG(TRACE, "Command: %s in:%d out:%d", full_name.c_str(), in_type, out_type);
|
||||
|
||||
try
|
||||
{
|
||||
Tango::DeviceData in = lut_toTangoType<Tango::DeviceData>(L, 1, in_type);
|
||||
Tango::DeviceData out = udata->dev->command_inout(cmd_name, in);
|
||||
lut_fromTangoType(L, out, out_type);
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, full_name.c_str());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TANGO API ------------------------------------------------------------------
|
||||
int lut_DeviceProxy_status(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:status()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
|
||||
try
|
||||
{
|
||||
lua_pushstring(L, udata->dev->status().c_str());
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, dev_name.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_get_attribute_list(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:get_attribute_list()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
|
||||
try
|
||||
{
|
||||
std::vector<std::string>* attrlist = udata->dev->get_attribute_list();
|
||||
lua_newtable(L);
|
||||
for(int i = 0; i < attrlist->size(); i++)
|
||||
{
|
||||
lua_pushstring(L, (*attrlist)[i].c_str());
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
delete attrlist;
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, dev_name.c_str());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_get_attribute_config(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:get_attribute_config()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
const char* name = luaL_checkstring(L, 3); // arg[2] is Lua "self"
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
std::string full_name = build_name(dev_name, name);
|
||||
|
||||
if(udata->attr_info.find(name) == udata->attr_info.end())
|
||||
{
|
||||
LUT_LOG(ERROR, "Attribute %s not found!", full_name.c_str());
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
lut_AttributeInfo(L, udata->attr_info[name]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_attribute_list_query(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:attribute_list_query()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
int top = lua_gettop(L);
|
||||
for(AttrInfoMap::iterator i = udata->attr_info.begin(); i != udata->attr_info.end(); i++)
|
||||
{
|
||||
lut_AttributeInfo(L, i->second);
|
||||
lua_setfield(L, top, i->first.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_get_command_list(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:get_command_list()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
|
||||
try
|
||||
{
|
||||
std::vector<std::string>* cmdlist = udata->dev->get_command_list();
|
||||
|
||||
lua_newtable(L);
|
||||
for(int i = 0; i < cmdlist->size(); i++)
|
||||
{
|
||||
lua_pushstring(L, (*cmdlist)[i].c_str());
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
delete cmdlist;
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, dev_name.c_str());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_get_command_config(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:get_command_config()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
const char* name = luaL_checkstring(L, 3); // arg[2] is Lua "self"
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
std::string full_name = build_name(dev_name, name);
|
||||
|
||||
if(udata->cmd_info.find(name) == udata->cmd_info.end())
|
||||
{
|
||||
LUT_LOG(ERROR, "Command %s not found!", full_name.c_str());
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
lut_CommandInfo(L, udata->cmd_info[name]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_command_list_query(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "TANGO API DeviceProxy:command_list_query()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
|
||||
lua_newtable(L);
|
||||
int top = lua_gettop(L);
|
||||
for(CmdInfoMap::iterator i = udata->cmd_info.begin(); i != udata->cmd_info.end(); i++)
|
||||
{
|
||||
lut_CommandInfo(L, i->second);
|
||||
lua_setfield(L, top, i->first.c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// LUA API --------------------------------------------------------------------
|
||||
void lut_lua_register_DeviceProxy(lua_State* L)
|
||||
{
|
||||
// create table, register funcs and add it as DeviceProxy to lutango's table
|
||||
lua_newtable(L);
|
||||
va_lua_register(L, lut_DeviceProxy);
|
||||
lua_setfield(L, -2, "DeviceProxy");
|
||||
|
||||
LUT_LOG(INFO, "Registered DeviceProxy table");
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_create(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L, 1);
|
||||
|
||||
LUT_LOG(TRACE, "LUA API DeviceProxy:create(%s)", name);
|
||||
|
||||
// push userdata containing the DeviceProxy
|
||||
DeviceProxyWrapper** udata = (DeviceProxyWrapper**)lua_newuserdata(L, sizeof(DeviceProxyWrapper*));
|
||||
try
|
||||
{
|
||||
*udata = new DeviceProxyWrapper(name);
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, name);
|
||||
}
|
||||
|
||||
// set metatable, that allows userdata proper garbage collection
|
||||
luaL_newmetatable(L, LUT_DEVICEPROXY);
|
||||
va_lua_register(L, lut_DeviceProxy_userdata);
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lut_DeviceProxy_destroy(lua_State* L)
|
||||
{
|
||||
LUT_LOG(TRACE, "LUA API DeviceProxy:destroy()");
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
delete udata;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// aka read_attribute / run command
|
||||
int lut_DeviceProxy_index(lua_State* L)
|
||||
{
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
const char* name = luaL_checkstring(L, 2);
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
std::string full_name = build_name(dev_name, name);
|
||||
|
||||
LUT_LOG(TRACE, "LUA API DeviceProxy(%s):index(%s)", dev_name.c_str(), name);
|
||||
|
||||
if(udata->cmd_info.find(name) != udata->cmd_info.end())
|
||||
{
|
||||
// index is a command, push wrapper closure
|
||||
// commands are supposed to be called, to allow this
|
||||
// command "read" returns a function closure
|
||||
lua_pushlightuserdata(L, udata);
|
||||
lua_pushstring(L, name);
|
||||
lua_pushcclosure(L, __cmd_wrapper, 2);
|
||||
}
|
||||
else if(udata->attr_info.find(name) != udata->attr_info.end())
|
||||
{
|
||||
// index is an attribute
|
||||
try
|
||||
{
|
||||
LUT_LOG(TRACE, "Reading attribute %s", full_name.c_str());
|
||||
Tango::DeviceAttribute attr = udata->dev->read_attribute(name);
|
||||
lut_fromTangoType(L, attr, attr.get_type(), attr.get_data_format());
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, full_name.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LUT_LOG(ERROR, "%s is neither command nor attribute!", full_name.c_str());
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// aka write_attribute
|
||||
int lut_DeviceProxy_newindex(lua_State* L)
|
||||
{
|
||||
DeviceProxyWrapper* udata = (DeviceProxyWrapper*)lut_getobj(L, 1);
|
||||
const char* attr_name = luaL_checkstring(L, 2);
|
||||
std::string dev_name = udata->dev->dev_name();
|
||||
std::string full_name = build_name(dev_name, attr_name);
|
||||
|
||||
LUT_LOG(TRACE, "LUA API DeviceProxy(%s):newindex(%s)", dev_name.c_str(), attr_name);
|
||||
|
||||
if(udata->attr_info.find(attr_name) == udata->attr_info.end())
|
||||
LUT_LOG(ERROR, "Not an attribute: %s!", full_name.c_str());
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Tango::DeviceAttribute v = lut_toTangoType<Tango::DeviceAttribute>(L, 3, udata->attr_info[attr_name].data_type, udata->attr_info[attr_name].data_format);
|
||||
v.set_name(attr_name);
|
||||
udata->dev->write_attribute(v);
|
||||
}
|
||||
catch(Tango::DevFailed e)
|
||||
{
|
||||
lut_DevFailed(L, e, full_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
90
src/core/tango/DeviceProxy/lut_DeviceProxy.h
Normal file
90
src/core/tango/DeviceProxy/lut_DeviceProxy.h
Normal file
@ -0,0 +1,90 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: lut_DeviceProxy.h
|
||||
//
|
||||
// Binding for DeviceProxy class
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LUT_DEVICEPROXY_H__
|
||||
# define __LUT_DEVICEPROXY_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <core/tango.h>
|
||||
#include <core/lua.h>
|
||||
#include <core/utils.h>
|
||||
|
||||
#include <core/lua/object.h>
|
||||
#include <core/lua/version_agnostic.h>
|
||||
#include <core/logging/log.h>
|
||||
|
||||
#include <core/tango/types.h>
|
||||
#include <core/tango/AttrCmdInfo/lut_AttrCmdInfo.h>
|
||||
#include <core/tango/DevFailed/lut_DevFailed.h>
|
||||
|
||||
#define LUT_DEVICEPROXY "lut_DeviceProxy"
|
||||
|
||||
// Wrapper class
|
||||
class DeviceProxyWrapper
|
||||
{
|
||||
public:
|
||||
Tango::DeviceProxy* dev;
|
||||
AttrInfoMap attr_info;
|
||||
CmdInfoMap cmd_info;
|
||||
|
||||
DeviceProxyWrapper(const char* name);
|
||||
~DeviceProxyWrapper();
|
||||
};
|
||||
|
||||
// Command wrapper
|
||||
int __cmd_wrapper(lua_State* L);
|
||||
|
||||
// Tango API
|
||||
int lut_DeviceProxy_status(lua_State* L);
|
||||
int lut_DeviceProxy_get_attribute_list(lua_State* L);
|
||||
int lut_DeviceProxy_get_attribute_config(lua_State* L);
|
||||
int lut_DeviceProxy_attribute_list_query(lua_State* L);
|
||||
int lut_DeviceProxy_get_command_list(lua_State* L);
|
||||
int lut_DeviceProxy_get_command_config(lua_State* L);
|
||||
int lut_DeviceProxy_command_list_query(lua_State* L);
|
||||
|
||||
// Lua API
|
||||
void lut_lua_register_DeviceProxy(lua_State* L);
|
||||
int lut_DeviceProxy_create(lua_State* L);
|
||||
int lut_DeviceProxy_destroy(lua_State* L);
|
||||
int lut_DeviceProxy_index(lua_State* L);
|
||||
int lut_DeviceProxy_newindex(lua_State* L);
|
||||
|
||||
static const luaL_Reg lut_DeviceProxy[] =
|
||||
{
|
||||
// Lua API
|
||||
{ "create", lut_DeviceProxy_create },
|
||||
{ "index", lut_DeviceProxy_index },
|
||||
{ "newindex", lut_DeviceProxy_newindex },
|
||||
|
||||
// Tango API
|
||||
{ "status", lut_DeviceProxy_status },
|
||||
{ "get_attribute_list", lut_DeviceProxy_get_attribute_list },
|
||||
{ "get_attribute_config", lut_DeviceProxy_get_attribute_config },
|
||||
{ "attribute_list_query", lut_DeviceProxy_attribute_list_query },
|
||||
{ "get_command_list", lut_DeviceProxy_get_command_list },
|
||||
{ "get_command_config", lut_DeviceProxy_get_command_config },
|
||||
{ "command_list_query", lut_DeviceProxy_command_list_query },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static const luaL_Reg lut_DeviceProxy_userdata[] =
|
||||
{
|
||||
{ "__gc", lut_DeviceProxy_destroy },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif /* __LUT_DEVICEPROXY_H__ */
|
||||
440
src/core/tango/types.cpp
Normal file
440
src/core/tango/types.cpp
Normal file
@ -0,0 +1,440 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: types.cpp
|
||||
//
|
||||
// Tango type conversions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "types.h"
|
||||
|
||||
template void lut_fromTangoType(lua_State* L, Tango::DeviceAttribute data, int type, Tango::AttrDataFormat format);
|
||||
template void lut_fromTangoType(lua_State* L, Tango::DeviceData data, int type, Tango::AttrDataFormat format);
|
||||
|
||||
template<class T>
|
||||
void lut_fromTangoType(lua_State* L, T data, int type, Tango::AttrDataFormat format)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case Tango::DEV_VOID: // 0 - void
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
|
||||
case Tango::DEV_BOOLEAN: // 1 - bool
|
||||
extract_bool(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_SHORT: // 2 - short
|
||||
extract_number<short>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_LONG: // 3 - long
|
||||
extract_number<long>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_FLOAT: // 4 - float
|
||||
extract_number<float>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_DOUBLE: // 5 - double
|
||||
extract_number<double>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_USHORT: // 6 - ushort
|
||||
extract_number<unsigned short>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_ULONG: // 7 - ulong
|
||||
extract_number<unsigned long>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_STRING: // 8 - string
|
||||
case Tango::DEVVAR_CHARARRAY: // 9 - char[]
|
||||
case Tango::CONST_DEV_STRING: // 20 - const string
|
||||
extract_string(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_SHORTARRAY: // 10 - short[]
|
||||
{
|
||||
std::vector<short> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_LONGARRAY: // 11 - long[]
|
||||
{
|
||||
std::vector<long> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_FLOATARRAY: // 12 - float[]
|
||||
{
|
||||
std::vector<float> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_DOUBLEARRAY: // 13 - double[]
|
||||
{
|
||||
std::vector<double> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_USHORTARRAY: // 14 - ushort[]
|
||||
{
|
||||
std::vector<unsigned short> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_ULONGARRAY: // 15 - ulong[]
|
||||
{
|
||||
std::vector<unsigned long> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_STRINGARRAY: // 16 - string[]
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
data >> v;
|
||||
push_string_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_STATE: // 19 - DevState
|
||||
{
|
||||
Tango::DevState v;
|
||||
data >> v;
|
||||
lut_DevState(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_UCHAR: // 22 - uchar
|
||||
{
|
||||
unsigned char v;
|
||||
// data >> v;
|
||||
lua_pushstring(L, (const char *)&v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_LONG64: // 23 - long64
|
||||
extract_number<int64_t>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEV_ULONG64: // 24 - ulong64
|
||||
extract_number<uint64_t>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_LONG64ARRAY: // 25 - long64[]
|
||||
{
|
||||
std::vector<int64_t> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_ULONG64ARRAY: // 26 - ulong64[]
|
||||
{
|
||||
std::vector<uint64_t> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_INT: // 27 - int
|
||||
extract_number<int>(L, data, format);
|
||||
break;
|
||||
|
||||
case Tango::DEVVAR_LONGSTRINGARRAY: // 17 - longstring[] ???
|
||||
case Tango::DEVVAR_DOUBLESTRINGARRAY: // 18 - doublestring[] ???
|
||||
case Tango::DEVVAR_BOOLEANARRAY: // 21 - bool[]
|
||||
case Tango::DEV_ENCODED: // 28 - DevEncoded
|
||||
case Tango::DEV_ENUM: // 29 - DevEnum
|
||||
case Tango::DEV_PIPE_BLOB: // 30 - DevPipeBlob
|
||||
case Tango::DEVVAR_STATEARRAY: // 31 - DevState[]
|
||||
LUT_LOG(WARNING, "Command type conversion not implemented yet: %d", type);
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
|
||||
case Tango::DATA_TYPE_UNKNOWN: // 32 - unknown
|
||||
default:
|
||||
LUT_LOG(ERROR, "Unknown type: %d", type);
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template Tango::DeviceAttribute lut_toTangoType(lua_State* L, int idx, int type, Tango::AttrDataFormat format);
|
||||
template Tango::DeviceData lut_toTangoType(lua_State* L, int idx, int type, Tango::AttrDataFormat format);
|
||||
|
||||
template<class T>
|
||||
T lut_toTangoType(lua_State* L, int idx, int type, Tango::AttrDataFormat format)
|
||||
{
|
||||
T data = T();
|
||||
switch(type)
|
||||
{
|
||||
case Tango::DEV_VOID: // 0 - void
|
||||
break;
|
||||
|
||||
case Tango::DEV_BOOLEAN: // 1 - bool
|
||||
{
|
||||
Tango::DevBoolean v = lua_toboolean(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_SHORT: // 2 - short
|
||||
{
|
||||
Tango::DevShort v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_LONG: // 3 - long
|
||||
{
|
||||
Tango::DevLong v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_FLOAT: // 4 - float
|
||||
{
|
||||
Tango::DevFloat v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_DOUBLE: // 5 - double
|
||||
{
|
||||
Tango::DevDouble v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_USHORT: // 6 - ushort
|
||||
{
|
||||
Tango::DevUShort v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_ULONG: // 7 - ulong
|
||||
{
|
||||
Tango::DevULong v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_STRING: // 8 - string
|
||||
case Tango::DEVVAR_CHARARRAY: // 9 - char[]
|
||||
case Tango::CONST_DEV_STRING: // 20 - const string
|
||||
{
|
||||
const char* v = luaL_checkstring(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_SHORTARRAY: // 10 - short[]
|
||||
{
|
||||
std::vector<Tango::DevShort> v = pop_number_table<Tango::DevShort>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_LONGARRAY: // 11 - long[]
|
||||
{
|
||||
std::vector<Tango::DevLong> v = pop_number_table<Tango::DevLong>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_FLOATARRAY: // 12 - float[]
|
||||
{
|
||||
std::vector<Tango::DevFloat> v = pop_number_table<Tango::DevFloat>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_DOUBLEARRAY: // 13 - double[]
|
||||
{
|
||||
std::vector<Tango::DevDouble> v = pop_number_table<Tango::DevDouble>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_USHORTARRAY: // 14 - ushort[]
|
||||
{
|
||||
std::vector<Tango::DevUShort> v = pop_number_table<Tango::DevUShort>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_ULONGARRAY: // 15 - ulong[]
|
||||
{
|
||||
std::vector<Tango::DevULong> v = pop_number_table<Tango::DevULong>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_STRINGARRAY: // 16 - string[]
|
||||
{
|
||||
std::vector<std::string> v = pop_string_table(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_LONG64: // 23 - long64
|
||||
{
|
||||
Tango::DevLong64 v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_ULONG64: // 24 - ulong64
|
||||
{
|
||||
Tango::DevULong64 v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_LONG64ARRAY: // 25 - long64[]
|
||||
{
|
||||
std::vector<Tango::DevLong64> v = pop_number_table<Tango::DevLong64>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_ULONG64ARRAY: // 26 - ulong64[]
|
||||
{
|
||||
std::vector<Tango::DevULong64> v = pop_number_table<Tango::DevULong64>(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEV_INT: // 27 - int
|
||||
{
|
||||
int v = luaL_checknumber(L, idx);
|
||||
data << v;
|
||||
break;
|
||||
}
|
||||
|
||||
case Tango::DEVVAR_LONGSTRINGARRAY: // 17 - longstring[] ???
|
||||
case Tango::DEVVAR_DOUBLESTRINGARRAY: // 18 - doublestring[] ???
|
||||
case Tango::DEV_STATE: // 19 - DevState
|
||||
case Tango::DEVVAR_BOOLEANARRAY: // 21 - bool[]
|
||||
case Tango::DEV_UCHAR: // 22 - uchar
|
||||
case Tango::DEV_ENCODED: // 28 - DevEncoded
|
||||
case Tango::DEV_ENUM: // 29 - DevEnum
|
||||
case Tango::DEV_PIPE_BLOB: // 30 - DevPipeBlob
|
||||
case Tango::DEVVAR_STATEARRAY: // 31 - DevState[]
|
||||
LUT_LOG(WARNING, "Conversion to Tango type not implemented yet: %d", type);
|
||||
break;
|
||||
|
||||
case Tango::DATA_TYPE_UNKNOWN: // 32 - unknown
|
||||
default:
|
||||
LUT_LOG(ERROR, "Tango type is unknown: %d", type);
|
||||
break;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
template<class dT, class T>
|
||||
void extract_number(lua_State* L, T data, Tango::AttrDataFormat format)
|
||||
{
|
||||
if(format == Tango::SCALAR)
|
||||
{
|
||||
dT v;
|
||||
data >> v;
|
||||
lua_pushnumber(L, v);
|
||||
}
|
||||
else if(format == Tango::SPECTRUM)
|
||||
{
|
||||
std::vector<dT> v;
|
||||
data >> v;
|
||||
push_number_table(L, v);
|
||||
}
|
||||
else if(format == Tango::IMAGE)
|
||||
{
|
||||
// std::vector<std::vector<T>> v;
|
||||
// //attr >> v;
|
||||
// // push_number_2d(L, v);
|
||||
LUT_LOG(WARNING, "IMAGE data format is not supported yet");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
LUT_LOG(ERROR, "Invalid data format");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void extract_bool(lua_State* L, T data, Tango::AttrDataFormat format)
|
||||
{
|
||||
if(format == Tango::SCALAR)
|
||||
{
|
||||
bool v;
|
||||
data >> v;
|
||||
lua_pushboolean(L, v);
|
||||
}
|
||||
else if(format == Tango::SPECTRUM)
|
||||
{
|
||||
// TODO: cannot insert std::vector<bool(or DevBoolean)> to DeviceData
|
||||
// std::vector<bool> v;
|
||||
// data >> v;
|
||||
// push_bool_table(L, v);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if(format == Tango::IMAGE)
|
||||
{
|
||||
LUT_LOG(WARNING, "IMAGE data format is not supported yet");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
LUT_LOG(ERROR, "Invalid data format");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void extract_string(lua_State* L, T data, Tango::AttrDataFormat format)
|
||||
{
|
||||
if(format == Tango::SCALAR)
|
||||
{
|
||||
std::string v;
|
||||
data >> v;
|
||||
lua_pushstring(L, v.c_str());
|
||||
}
|
||||
else if(format == Tango::SPECTRUM)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
data >> v;
|
||||
push_string_table(L, v);
|
||||
}
|
||||
else if(format == Tango::IMAGE)
|
||||
{
|
||||
LUT_LOG(WARNING, "IMAGE data format is not supported yet");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
LUT_LOG(ERROR, "Invalid data format");
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
46
src/core/tango/types.h
Normal file
46
src/core/tango/types.h
Normal file
@ -0,0 +1,46 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: types.h
|
||||
//
|
||||
// Tango type conversions
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __TYPES_H__
|
||||
# define __TYPES_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <core/lua.h>
|
||||
#include <core/tango.h>
|
||||
#include <core/logging/log.h>
|
||||
#include <core/lua/stack.h>
|
||||
#include <core/tango/DevState/lut_DevState.h>
|
||||
|
||||
typedef std::map<std::string, Tango::AttributeInfoEx> AttrInfoMap;
|
||||
typedef std::map<std::string, Tango::CommandInfo> CmdInfoMap;
|
||||
|
||||
template<class T>
|
||||
void lut_fromTangoType(lua_State* L, T data, int type, Tango::AttrDataFormat format=Tango::SCALAR);
|
||||
|
||||
template<class T>
|
||||
T lut_toTangoType(lua_State* L, int idx, int type, Tango::AttrDataFormat format=Tango::SCALAR);
|
||||
|
||||
template<class dT, class T>
|
||||
void extract_number(lua_State* L, T data, Tango::AttrDataFormat format);
|
||||
|
||||
template<class T>
|
||||
void extract_bool(lua_State* L, T data, Tango::AttrDataFormat format);
|
||||
|
||||
template<class T>
|
||||
void extract_string(lua_State* L, T data, Tango::AttrDataFormat format);
|
||||
|
||||
#endif /* __TYPES_H__ */
|
||||
23
src/core/utils.cpp
Normal file
23
src/core/utils.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: utils.cpp
|
||||
//
|
||||
// Various utilities
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
std::string build_name(std::string dev_name, std::string name, bool cmd)
|
||||
{
|
||||
std::string r(dev_name);
|
||||
r += "/";
|
||||
r += name;
|
||||
if(cmd) r += "()";
|
||||
return r;
|
||||
}
|
||||
21
src/core/utils.h
Normal file
21
src/core/utils.h
Normal file
@ -0,0 +1,21 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// luTango - Lua binding for Tango
|
||||
//
|
||||
// Copyright (C) 2023 Grzegorz Kowalski
|
||||
// See LICENSE for legal information
|
||||
//
|
||||
// file: utils.h
|
||||
//
|
||||
// Various utilities
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __UTILS_H__
|
||||
# define __UTILS_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string build_name(std::string dev_name, std::string name, bool cmd=false);
|
||||
|
||||
#endif /* __UTILS_H__ */
|
||||
32
src/init.lua
Normal file
32
src/init.lua
Normal file
@ -0,0 +1,32 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: init.lua
|
||||
--
|
||||
-- Lua module entry point
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local log = require "lutango.log"
|
||||
local core = require "lutango.core"
|
||||
local utils = require "lutango.utils"
|
||||
local lutObject = require "lutango.lutObject"
|
||||
|
||||
local lutango = {
|
||||
__prefix = prefix,
|
||||
log = log,
|
||||
sys = core.sys,
|
||||
lutObject = lutObject,
|
||||
DeviceProxy = lutObject("DeviceProxy"),
|
||||
AttributeProxy = lutObject("AttributeProxy"),
|
||||
DevState = require "lutango.lutDevState"
|
||||
}
|
||||
|
||||
lutango.sys.lua_version = utils.lua_version
|
||||
|
||||
log(log.level.TRACE, "luTango module ready")
|
||||
return lutango
|
||||
48
src/log.lua
Normal file
48
src/log.lua
Normal file
@ -0,0 +1,48 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: log.lua
|
||||
--
|
||||
-- Logging facilities for Lua part
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local core = require "lutango.core"
|
||||
local utils = require "lutango.utils"
|
||||
|
||||
local _log_level = {
|
||||
CRITICAL = 0,
|
||||
ERROR = 1,
|
||||
WARNING = 2,
|
||||
INFO = 3,
|
||||
DEBUG = 4,
|
||||
TRACE = 5
|
||||
}
|
||||
|
||||
local log = {
|
||||
level = _log_level,
|
||||
current_log_level = _log_level.WARNING
|
||||
}
|
||||
|
||||
function log:__call(level, msg)
|
||||
if level <= self.current_log_level then
|
||||
level = utils.get_key_by_value(self.level, level)
|
||||
local caller = debug.getinfo(2)
|
||||
local file = utils.get_file_name(caller.source)
|
||||
local func = caller.name or "<anonymous>"
|
||||
local line = caller.linedefined
|
||||
io.stderr:write("["..level.."]@[API:"..file..":"..func..":"..line.."]: "..msg.."\n")
|
||||
end
|
||||
end
|
||||
|
||||
function log:set_log_level(level)
|
||||
self.current_log_level = level
|
||||
core.log.set_log_level(level)
|
||||
end
|
||||
|
||||
setmetatable(log, log)
|
||||
return log
|
||||
50
src/lutDevState.lua
Normal file
50
src/lutDevState.lua
Normal file
@ -0,0 +1,50 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: lutDevState.lua
|
||||
--
|
||||
-- DevState type implementation
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local utils = require "lutango.utils"
|
||||
local log = require "lutango.log"
|
||||
|
||||
local lutDevState = {
|
||||
labels = {[0] = "ON", "OFF", "CLOSE", "OPEN", "INSERT", "EXTRACT", "MOVING", "STANDBY", "FAULT", "INIT", "RUNNING", "ALARM", "DISABLE", "UNKNOWN"}
|
||||
}
|
||||
|
||||
lutDevState.__index = lutDevState
|
||||
|
||||
function lutDevState:__call(state)
|
||||
log(log.level.TRACE, "New DevState("..tostring(state)..")")
|
||||
|
||||
o = { value = state}
|
||||
|
||||
setmetatable(o, lutDevState)
|
||||
return o
|
||||
end
|
||||
|
||||
function lutDevState:number()
|
||||
return self.value
|
||||
end
|
||||
|
||||
function lutDevState:__tostring()
|
||||
return self.labels[self.value]
|
||||
end
|
||||
|
||||
function lutDevState:__eq(other)
|
||||
return self.state == other.state
|
||||
end
|
||||
|
||||
local r = {}
|
||||
-- pregenerate available state objects
|
||||
for i = 0,#lutDevState.labels do
|
||||
r[lutDevState.labels[i]] = lutDevState:__call(i)
|
||||
end
|
||||
setmetatable(r, lutDevState)
|
||||
return r
|
||||
77
src/lutObject.lua
Normal file
77
src/lutObject.lua
Normal file
@ -0,0 +1,77 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: lutObject.lua
|
||||
--
|
||||
-- Generic Lua object for interacting with C++ objects
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local core = require "lutango.core"
|
||||
local log = require "lutango.log"
|
||||
local try = require "lutango.try"
|
||||
|
||||
local lutObject = {}
|
||||
|
||||
local function create_lutObject(type)
|
||||
log(log.level.TRACE, "New lutObject for "..type)
|
||||
local o = {
|
||||
__is_instance = false,
|
||||
__type = type
|
||||
}
|
||||
|
||||
setmetatable(o, lutObject)
|
||||
return o
|
||||
end
|
||||
|
||||
function lutObject:__call(...)
|
||||
if self.__is_instance then
|
||||
if self.__type then
|
||||
return try(core[self.__type].call, self.__obj, ...)
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
log(log.level.TRACE, "New "..self.__type.."("..table.concat({...}, ", ")..")")
|
||||
local o = {
|
||||
__is_instance = true,
|
||||
__type = self.__type
|
||||
}
|
||||
|
||||
if self.__type then
|
||||
o.__obj = try(core[self.__type].create, ...)
|
||||
end
|
||||
|
||||
setmetatable(o, lutObject)
|
||||
return o
|
||||
end
|
||||
end
|
||||
|
||||
function lutObject:__index(key)
|
||||
if self.__type then
|
||||
local from_core = core[self.__type][key]
|
||||
if from_core then
|
||||
return function(...)
|
||||
return try(from_core, self.__obj, ...)
|
||||
end
|
||||
end
|
||||
return try(core[self.__type].index, self.__obj, key)
|
||||
else return nil end
|
||||
end
|
||||
|
||||
function lutObject:__newindex(key, value)
|
||||
if self.__type then
|
||||
local from_core = core[self.__type][key]
|
||||
if from_core then
|
||||
log(log.level.ERROR, "Cannot write non-attribute: "..key)
|
||||
return nil
|
||||
end
|
||||
try(core[self.__type].newindex, self.__obj, key, value)
|
||||
else return nil end
|
||||
end
|
||||
|
||||
return create_lutObject
|
||||
39
src/try.lua
Normal file
39
src/try.lua
Normal file
@ -0,0 +1,39 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: try.lua
|
||||
--
|
||||
-- Exception handling
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
require "lutango.version_agnostic"
|
||||
|
||||
local function default_handler(e)
|
||||
io.stderr:write("\n=================================== EXCEPTION ===================================\n")
|
||||
if e.is_DevFailed then
|
||||
io.stderr:write("Tango Error Stack:\t"..e.source.."\n")
|
||||
for i,v in ipairs(e) do
|
||||
io.stderr:write("\t"..i..":\n")
|
||||
io.stderr:write("\t\t"..v.severity.."\t\t"..v.reason.."\n")
|
||||
io.stderr:write("\t\t"..v.desc.."\n")
|
||||
io.stderr:write("\t\t"..v.origin.."\n\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write(tostring(e))
|
||||
end
|
||||
io.stderr:write(debug.traceback("", 6))
|
||||
io.stderr:write("\n=================================================================================\n\n")
|
||||
end
|
||||
|
||||
local function try(f, ...)
|
||||
local f_arg = {...}
|
||||
local ok, ret = xpcall(function() return f(va_unpack(f_arg)) end, default_handler)
|
||||
return ret
|
||||
end
|
||||
|
||||
return try
|
||||
36
src/utils.lua
Normal file
36
src/utils.lua
Normal file
@ -0,0 +1,36 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: utils.lua
|
||||
--
|
||||
-- Various utilities
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local utils = {}
|
||||
|
||||
function utils.get_key_by_value(t, value)
|
||||
for k,v in pairs(t) do
|
||||
if v == value then return k end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function utils.get_file_name(path)
|
||||
return path:match("^.+[/\\](.+)$")
|
||||
end
|
||||
|
||||
function utils.lua_version()
|
||||
if type(jit) == "table" and jit.version then
|
||||
-- running on LuaJIT
|
||||
return jit.version.." (".._VERSION..")"
|
||||
else
|
||||
return _VERSION
|
||||
end
|
||||
end
|
||||
|
||||
return utils
|
||||
21
src/version_agnostic.lua
Normal file
21
src/version_agnostic.lua
Normal file
@ -0,0 +1,21 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: version_agnostic.lua
|
||||
--
|
||||
-- Facilitate different versions of Lua
|
||||
-- WARNING! This module sets globals!
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local version = tonumber(_VERSION:match("%d.%d"))
|
||||
|
||||
if version > 5.1 then
|
||||
va_unpack = table.unpack
|
||||
else
|
||||
va_unpack = unpack
|
||||
end
|
||||
27
tests/_print_kv.lua
Normal file
27
tests/_print_kv.lua
Normal file
@ -0,0 +1,27 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: _print_kv.lua
|
||||
--
|
||||
-- Nested table printing utility
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function print_kv(k, v, prefix)
|
||||
prefix = prefix or ""
|
||||
print(prefix..tostring(k)..": "..tostring(v))
|
||||
if type(v) == "table" then
|
||||
for kk,vv in ipairs(v) do
|
||||
print_kv(kk, vv, prefix.."\t")
|
||||
end
|
||||
for kk,vv in pairs(v) do
|
||||
print_kv(kk, vv, prefix.."\t")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return print_kv
|
||||
38
tests/attributeproxy.lua
Normal file
38
tests/attributeproxy.lua
Normal file
@ -0,0 +1,38 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: attributeproxy.lua
|
||||
--
|
||||
-- Test script for AttributeProxy class
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
local print_kv = require "_print_kv"
|
||||
lut.log:set_log_level(lut.log.level.WARNING)
|
||||
|
||||
local ap = lut.AttributeProxy("sys/tg_test/1/ampli")
|
||||
|
||||
print("Reading state and status")
|
||||
print("State = "..tostring(ap:state()))
|
||||
print("Status = "..ap:status())
|
||||
|
||||
print("Reading attribute")
|
||||
local v = ap()
|
||||
print("ampli = "..v)
|
||||
|
||||
print("Writing attribute")
|
||||
ap(v+1)
|
||||
|
||||
print("Reading again")
|
||||
print("ampli = "..ap())
|
||||
|
||||
local info = ap:get_config()
|
||||
print("\nAttribute info: "..tostring(info))
|
||||
for k,v in pairs(info) do
|
||||
print_kv(k, v)
|
||||
end
|
||||
49
tests/dp_info.lua
Normal file
49
tests/dp_info.lua
Normal file
@ -0,0 +1,49 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: dp_info.lua
|
||||
--
|
||||
-- Test script for attribute and command info
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
local print_kv = require "_print_kv"
|
||||
lut.log:set_log_level(lut.log.level.WARNING)
|
||||
|
||||
local dp = lut.DeviceProxy(arg[1] or "sys/tg_test/1")
|
||||
|
||||
print("Get full lists:")
|
||||
local ai_list = dp:attribute_list_query()
|
||||
for k,v in pairs(ai_list) do
|
||||
print_kv(k, v)
|
||||
end
|
||||
|
||||
local ci_list = dp:command_list_query()
|
||||
for k,v in pairs(ci_list) do
|
||||
print_kv(k, v)
|
||||
end
|
||||
|
||||
print("\nGet single attr:")
|
||||
local ai = dp:get_attribute_config("double_spectrum_ro")
|
||||
for k,v in pairs(ai) do
|
||||
print_kv(k, v)
|
||||
end
|
||||
|
||||
print("\nGet single command:")
|
||||
local ci = dp:get_command_config("DevLong64")
|
||||
for k,v in pairs(ci) do
|
||||
print_kv(k, v)
|
||||
end
|
||||
|
||||
print("\nGet non-existent attr:")
|
||||
local non_ai = dp:get_attribute_config("non_existent_attr")
|
||||
print(tostring(non_ai))
|
||||
|
||||
print("\nGet non-existent command:")
|
||||
local non_ci = dp:get_command_config("NonExistentCommand")
|
||||
print(tostring(non_ci))
|
||||
40
tests/invalid_actions.lua
Normal file
40
tests/invalid_actions.lua
Normal file
@ -0,0 +1,40 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: invalid_actions.lua
|
||||
--
|
||||
-- Test script attempting to perform various invalid actions
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
lut.log:set_log_level(lut.log.level.TRACE)
|
||||
|
||||
print("Attempting to access non-existent device")
|
||||
local invalid = lut.DeviceProxy("non/existent/device")
|
||||
|
||||
local dp = lut.DeviceProxy(arg[1] or "sys/tg_test/1")
|
||||
|
||||
print("Attempting to write core function")
|
||||
dp.get_attribute_list = 120
|
||||
|
||||
print("Attempting to write device command")
|
||||
dp.SwitchStates = 0
|
||||
|
||||
print("Attempting to write read-only attribute")
|
||||
dp.short_scalar_ro = 100
|
||||
|
||||
print("Attempting to access non-existent attribute")
|
||||
local invalid2 = lut.AttributeProxy("sys/tg_test/1/nonexistent")
|
||||
|
||||
print("Attempting to write read-only attribute via AttributeProxy")
|
||||
local attr_name = "sys/tg_test/1/short_scalar_ro"
|
||||
if arg[1] and arg[2] then
|
||||
attr_name = arg[1].."/"..arg[2]
|
||||
end
|
||||
local ap = lut.AttributeProxy(attr_name)
|
||||
ap(100)
|
||||
19
tests/print_versions.lua
Normal file
19
tests/print_versions.lua
Normal file
@ -0,0 +1,19 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: print_versions.lua
|
||||
--
|
||||
-- Test script printing libraries, interpreter and compiler versions
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
|
||||
print("luTango "..lut.sys.version())
|
||||
print("Tango "..lut.sys.tango_version())
|
||||
print(lut.sys.cpp_version())
|
||||
print(lut.sys.lua_version())
|
||||
36
tests/read_attrs.lua
Normal file
36
tests/read_attrs.lua
Normal file
@ -0,0 +1,36 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: read_attrs.lua
|
||||
--
|
||||
-- Test script for reading attributes
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
|
||||
lut.log:set_log_level(lut.log.level.WARNING)
|
||||
|
||||
local dp = lut.DeviceProxy(arg[1] or "sys/tg_test/1")
|
||||
local attrlist = dp:get_attribute_list()
|
||||
|
||||
for _,v in ipairs(attrlist) do
|
||||
local r = dp[v]
|
||||
io.write(v.." = "..tostring(r))
|
||||
if type(r) == "table" then
|
||||
io.write(": {")
|
||||
for _,i in ipairs(r) do
|
||||
io.write(tostring(i)..", ")
|
||||
end
|
||||
io.write("}")
|
||||
end
|
||||
print()
|
||||
end
|
||||
|
||||
print("\nReading non existent attribute")
|
||||
local ne = dp.non_existent_attr
|
||||
print(tostring(ne))
|
||||
80
tests/run_cmds.lua
Normal file
80
tests/run_cmds.lua
Normal file
@ -0,0 +1,80 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: run_cmds.lua
|
||||
--
|
||||
-- Test script for running commands
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
lut.log:set_log_level(lut.log.level.WARNING)
|
||||
|
||||
local dp = lut.DeviceProxy(arg[1] or "sys/tg_test/1")
|
||||
|
||||
function run_void_cmd(cmd)
|
||||
io.write(cmd.."(): ")
|
||||
print(dp[cmd]())
|
||||
end
|
||||
|
||||
function run_scalar_cmd(cmd, input)
|
||||
io.write(cmd.."("..tostring(input).."): ")
|
||||
print(dp[cmd](input))
|
||||
end
|
||||
|
||||
function run_array_cmd(cmd, input)
|
||||
io.write(cmd.."({")
|
||||
for _,v in ipairs(input) do
|
||||
io.write(v..", ")
|
||||
end
|
||||
io.write("}): ")
|
||||
local r = dp[cmd](input)
|
||||
io.write(tostring(r)..": {")
|
||||
for _,v in ipairs(input) do
|
||||
io.write(v..", ")
|
||||
end
|
||||
print("}")
|
||||
end
|
||||
|
||||
run_void_cmd("State")
|
||||
run_void_cmd("Status")
|
||||
run_void_cmd("SwitchStates")
|
||||
run_void_cmd("DevVoid")
|
||||
|
||||
run_scalar_cmd("DevBoolean", true)
|
||||
run_scalar_cmd("DevBoolean", false)
|
||||
run_scalar_cmd("DevDouble", 88.888)
|
||||
run_scalar_cmd("DevDouble", -88.888)
|
||||
run_scalar_cmd("DevFloat", 8.88)
|
||||
run_scalar_cmd("DevFloat", -8.88)
|
||||
run_scalar_cmd("DevLong", 99112233)
|
||||
run_scalar_cmd("DevLong", -99112233)
|
||||
run_scalar_cmd("DevLong64", 1199228833775566)
|
||||
run_scalar_cmd("DevLong64", -1199228833775566)
|
||||
run_scalar_cmd("DevShort", 101)
|
||||
run_scalar_cmd("DevShort", -101)
|
||||
run_scalar_cmd("DevString", "hello world")
|
||||
run_scalar_cmd("DevULong", 9911223344)
|
||||
run_scalar_cmd("DevULong64", 1199228833775566)
|
||||
run_scalar_cmd("DevUShort", 101)
|
||||
-- run_scalar_cmd("DevVarCharArray", "hello world")
|
||||
|
||||
run_array_cmd("DevVarDoubleArray", {1.1111, -2.2222, 3.3333})
|
||||
-- run_array_cmd("DevVarDoubleStringArray", {???})
|
||||
run_array_cmd("DevVarFloatArray", {1.11, -2.22, 3.33})
|
||||
run_array_cmd("DevVarLong64Array", {11111111111, -22222222222, 33333333333})
|
||||
run_array_cmd("DevVarLongArray", {11111111111, -22222222222, 33333333333})
|
||||
-- run_array_cmd("DevVarLongStringArray", {???})
|
||||
run_array_cmd("DevVarShortArray", {1111, -2222, 3333})
|
||||
run_array_cmd("DevVarStringArray", {"hello", "world", "from", "Lua"})
|
||||
run_array_cmd("DevVarULong64Array", {11111111111, 22222222222, 33333333333})
|
||||
run_array_cmd("DevVarULongArray", {11111111111, 22222222222, 33333333333})
|
||||
run_array_cmd("DevVarUShortArray", {1111, 2222, 3333})
|
||||
|
||||
print("\nRunning non-existent command:")
|
||||
local ok, ret = pcall(dp.NonExistentCmd)
|
||||
print("ok="..tostring(ok).." ret="..tostring(ret))
|
||||
35
tests/test_state.lua
Normal file
35
tests/test_state.lua
Normal file
@ -0,0 +1,35 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: test_state.lua
|
||||
--
|
||||
-- Test script for DevState class
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
|
||||
local states = {}
|
||||
for i = 0,13 do
|
||||
states[i] = lut.DevState(i)
|
||||
print(tostring(states[i]).." = "..states[i]:number())
|
||||
end
|
||||
|
||||
print(states[0] == lut.DevState.ON)
|
||||
print(states[1] == lut.DevState.OFF)
|
||||
print(states[2] == lut.DevState.CLOSE)
|
||||
print(states[3] == lut.DevState.OPEN)
|
||||
print(states[4] == lut.DevState.INSERT)
|
||||
print(states[5] == lut.DevState.EXTRACT)
|
||||
print(states[6] == lut.DevState.MOVING)
|
||||
print(states[7] == lut.DevState.STANDBY)
|
||||
print(states[8] == lut.DevState.FAULT)
|
||||
print(states[9] == lut.DevState.INIT)
|
||||
print(states[10] == lut.DevState.RUNNING)
|
||||
print(states[11] == lut.DevState.ALARM)
|
||||
print(states[12] == lut.DevState.DISABLE)
|
||||
print(states[13] == lut.DevState.UNKNOWN)
|
||||
21
tests/write_attrs.lua
Normal file
21
tests/write_attrs.lua
Normal file
@ -0,0 +1,21 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- luTango - Lua binding for Tango
|
||||
--
|
||||
-- Copyright (C) 2023 Grzegorz Kowalski
|
||||
-- See LICENSE for legal information
|
||||
--
|
||||
-- file: write_attrs.lua
|
||||
--
|
||||
-- Test script for writing attributes
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local lut = require "lutango"
|
||||
lut.log:set_log_level(lut.log.level.WARNING)
|
||||
|
||||
dp = lut.DeviceProxy(arg[1] or "sys/tg_test/1")
|
||||
|
||||
dp.ampli = dp.ampli + 1
|
||||
local b = dp.boolean_scalar
|
||||
dp.boolean_scalar = not b
|
||||
Loading…
x
Reference in New Issue
Block a user