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 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_sys(L);
|
||||
lut_lua_register_DeviceProxy(L);
|
||||
lut_lua_register_AttributeProxy(L);
|
||||
|
||||
LUT_LOG(TRACE, "Core module table registered.");
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <core/sys/sys.h>
|
||||
|
||||
#include <core/tango/DeviceProxy/lut_DeviceProxy.h>
|
||||
#include <core/tango/AttributeProxy/lut_AttributeProxy.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
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);
|
||||
lua_getglobal(L, LUTANGO);
|
||||
|
||||
lua_getfield(L, 1, "DevState");
|
||||
lua_getfield(L, -2, "DevState");
|
||||
lua_pushnumber(L, (int)state);
|
||||
|
||||
lua_call(L, 1, 1);
|
||||
|
||||
@ -9,6 +9,7 @@ local lutango = {
|
||||
sys = core.sys,
|
||||
lutObject = lutObject,
|
||||
DeviceProxy = lutObject("DeviceProxy"),
|
||||
AttributeProxy = lutObject("AttributeProxy"),
|
||||
DevState = require "lutango.lutDevState"
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ local lutObject = {}
|
||||
function create_lutObject(type)
|
||||
log(log.level.TRACE, "New lutObject for "..type)
|
||||
local o = {
|
||||
__is_instance = false,
|
||||
__type = type
|
||||
}
|
||||
|
||||
@ -15,17 +16,26 @@ function create_lutObject(type)
|
||||
end
|
||||
|
||||
function lutObject:__call(...)
|
||||
log(log.level.TRACE, "New "..self.__type.."("..table.concat({...}, ", ")..")")
|
||||
local o = {
|
||||
__type = self.__type
|
||||
}
|
||||
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, ...)
|
||||
if self.__type then
|
||||
o.__obj = try(core[self.__type].create, ...)
|
||||
end
|
||||
|
||||
setmetatable(o, lutObject)
|
||||
return o
|
||||
end
|
||||
|
||||
setmetatable(o, lutObject)
|
||||
return o
|
||||
end
|
||||
|
||||
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