forked from daneos/lutango
add AttributeProxy support
This commit is contained in:
parent
152734b329
commit
361e3abead
@ -1,4 +1,4 @@
|
|||||||
# luTango - Lua binding for Tango
|
# luTango - Lua binding for Tango
|
||||||
|
|
||||||
luTango is a module providing access to [Tango Control System](https://www.tango-controls.org/) with Lua.
|
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), although not all Tango types are supported.
|
In it's current state, a basic subset of client API is available (DeviceProxy, AttributeProxy), although not all Tango types are supported.
|
||||||
|
|||||||
@ -14,6 +14,7 @@ int luaopen_lutango_core(lua_State* L)
|
|||||||
lut_lua_register_log(L);
|
lut_lua_register_log(L);
|
||||||
lut_lua_register_sys(L);
|
lut_lua_register_sys(L);
|
||||||
lut_lua_register_DeviceProxy(L);
|
lut_lua_register_DeviceProxy(L);
|
||||||
|
lut_lua_register_AttributeProxy(L);
|
||||||
|
|
||||||
LUT_LOG(TRACE, "Core module table registered.");
|
LUT_LOG(TRACE, "Core module table registered.");
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <core/sys/sys.h>
|
#include <core/sys/sys.h>
|
||||||
|
|
||||||
#include <core/tango/DeviceProxy/lut_DeviceProxy.h>
|
#include <core/tango/DeviceProxy/lut_DeviceProxy.h>
|
||||||
|
#include <core/tango/AttributeProxy/lut_AttributeProxy.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|||||||
141
src/core/tango/AttributeProxy/lut_AttributeProxy.cpp
Normal file
141
src/core/tango/AttributeProxy/lut_AttributeProxy.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "lut_AttributeProxy.h"
|
||||||
|
|
||||||
|
// WRAPPER CLASS --------------------------------------------------------------
|
||||||
|
AttributeProxyWrapper::AttributeProxyWrapper(const char* name)
|
||||||
|
: type_cached(false)
|
||||||
|
{
|
||||||
|
attr = new Tango::AttributeProxy(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeProxyWrapper::~AttributeProxyWrapper()
|
||||||
|
{
|
||||||
|
delete attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tango::DeviceAttribute read_attr(AttributeProxyWrapper* udata)
|
||||||
|
{
|
||||||
|
Tango::DeviceAttribute attr_data = udata->attr->read();
|
||||||
|
udata->type_desc.type = attr_data.get_type();
|
||||||
|
udata->type_desc.format = attr_data.get_data_format();
|
||||||
|
udata->type_cached = true;
|
||||||
|
return attr_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
luaL_register(L, NULL, 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);
|
||||||
|
luaL_register(L, NULL, 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());
|
||||||
|
unpack_attr_data(L, read_attr(udata));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!udata->type_cached)
|
||||||
|
{
|
||||||
|
// no cached type mapping
|
||||||
|
LUT_LOG(TRACE, "Type mapping for attribute %s doesn't exist, reading first", attr_name.c_str());
|
||||||
|
read_attr(udata);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tango::DeviceAttribute v = pack_attr_data(L, 2, udata->type_desc, attr_name.c_str());
|
||||||
|
udata->attr->write(v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Tango::DevFailed e)
|
||||||
|
{
|
||||||
|
lut_DevFailed(L, e, attr_name.c_str());
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
62
src/core/tango/AttributeProxy/lut_AttributeProxy.h
Normal file
62
src/core/tango/AttributeProxy/lut_AttributeProxy.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#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/logging/log.h>
|
||||||
|
|
||||||
|
#include <core/tango/attrdata.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:
|
||||||
|
AttributeProxyWrapper(const char* name);
|
||||||
|
~AttributeProxyWrapper();
|
||||||
|
Tango::AttributeProxy* attr;
|
||||||
|
AttrTypeDescription type_desc;
|
||||||
|
bool type_cached;
|
||||||
|
};
|
||||||
|
|
||||||
|
Tango::DeviceAttribute read_attr(AttributeProxyWrapper* udata);
|
||||||
|
|
||||||
|
// Tango API
|
||||||
|
int lut_AttributeProxy_state(lua_State* L);
|
||||||
|
int lut_AttributeProxy_status(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
|
||||||
|
{ "status", lut_AttributeProxy_status },
|
||||||
|
{ "state", lut_AttributeProxy_state },
|
||||||
|
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const luaL_reg lut_AttributeProxy_userdata[] =
|
||||||
|
{
|
||||||
|
{ "__gc", lut_AttributeProxy_destroy },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __LUT_ATTRIBUTEPROXY_H__ */
|
||||||
@ -7,7 +7,7 @@ void lut_DevState(lua_State* L, Tango::DevState state)
|
|||||||
load_lua_lib(L, LUTANGO);
|
load_lua_lib(L, LUTANGO);
|
||||||
lua_getglobal(L, LUTANGO);
|
lua_getglobal(L, LUTANGO);
|
||||||
|
|
||||||
lua_getfield(L, 1, "DevState");
|
lua_getfield(L, -2, "DevState");
|
||||||
lua_pushnumber(L, (int)state);
|
lua_pushnumber(L, (int)state);
|
||||||
|
|
||||||
lua_call(L, 1, 1);
|
lua_call(L, 1, 1);
|
||||||
|
|||||||
@ -9,6 +9,7 @@ local lutango = {
|
|||||||
sys = core.sys,
|
sys = core.sys,
|
||||||
lutObject = lutObject,
|
lutObject = lutObject,
|
||||||
DeviceProxy = lutObject("DeviceProxy"),
|
DeviceProxy = lutObject("DeviceProxy"),
|
||||||
|
AttributeProxy = lutObject("AttributeProxy"),
|
||||||
DevState = require "lutango.lutDevState"
|
DevState = require "lutango.lutDevState"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ local lutObject = {}
|
|||||||
function create_lutObject(type)
|
function create_lutObject(type)
|
||||||
log(log.level.TRACE, "New lutObject for "..type)
|
log(log.level.TRACE, "New lutObject for "..type)
|
||||||
local o = {
|
local o = {
|
||||||
|
__is_instance = false,
|
||||||
__type = type
|
__type = type
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,17 +16,26 @@ function create_lutObject(type)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function lutObject:__call(...)
|
function lutObject:__call(...)
|
||||||
log(log.level.TRACE, "New "..self.__type.."("..table.concat({...}, ", ")..")")
|
if self.__is_instance then
|
||||||
local o = {
|
if self.__type then
|
||||||
__type = self.__type
|
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
|
if self.__type then
|
||||||
o.__obj = try(core[self.__type].create, ...)
|
o.__obj = try(core[self.__type].create, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
setmetatable(o, lutObject)
|
||||||
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
setmetatable(o, lutObject)
|
|
||||||
return o
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function lutObject:__index(key)
|
function lutObject:__index(key)
|
||||||
|
|||||||
18
tests/attributeproxy.lua
Normal file
18
tests/attributeproxy.lua
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
local lut = require "lutango"
|
||||||
|
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())
|
||||||
Loading…
x
Reference in New Issue
Block a user