add command and attribute info to DeviceProxy

This commit is contained in:
Grzegorz Kowalski 2023-02-09 02:26:47 +01:00
parent 9bd078b221
commit 3535cfc13b
7 changed files with 203 additions and 82 deletions

View File

@ -21,9 +21,9 @@ DeviceProxyWrapper::DeviceProxyWrapper(const char* name)
Tango::CommandInfoList* cmdlist = dev->command_list_query();
for(int i = 0; i < attrlist->size(); i++)
attr_cache[(*attrlist)[i].name] = (*attrlist)[i];
attr_info[(*attrlist)[i].name] = (*attrlist)[i];
for(int i = 0; i < cmdlist->size(); i++)
cmd_cache[(*cmdlist)[i].cmd_name] = (*cmdlist)[i];
cmd_info[(*cmdlist)[i].cmd_name] = (*cmdlist)[i];
delete attrlist;
delete cmdlist;
@ -34,26 +34,6 @@ DeviceProxyWrapper::~DeviceProxyWrapper()
delete dev;
}
int DeviceProxyWrapper::attr_type(const char* name)
{
return attr_cache[name].data_type;
}
Tango::AttrDataFormat DeviceProxyWrapper::attr_format(const char* name)
{
return attr_cache[name].data_format;
}
int DeviceProxyWrapper::cmd_in_type(const char* name)
{
return cmd_cache[name].in_type;
}
int DeviceProxyWrapper::cmd_out_type(const char* name)
{
return cmd_cache[name].out_type;
}
// COMMAND WRAPPER ------------------------------------------------------------
int __cmd_wrapper(lua_State* L)
{
@ -64,13 +44,12 @@ int __cmd_wrapper(lua_State* L)
LUT_LOG(TRACE, "Running command wrapper %s", full_name.c_str());
try
{
int in_type = udata->cmd_in_type(cmd_name);
int out_type = udata->cmd_out_type(cmd_name);
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);
@ -125,6 +104,41 @@ int lut_DeviceProxy_get_attribute_list(lua_State* L)
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()");
@ -150,6 +164,41 @@ int lut_DeviceProxy_get_command_list(lua_State* L)
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)
{
@ -204,11 +253,7 @@ int lut_DeviceProxy_index(lua_State* L)
LUT_LOG(TRACE, "LUA API DeviceProxy(%s):index(%s)", dev_name.c_str(), name);
try
{
std::vector<std::string>* cmdlist = udata->dev->get_command_list();
if(std::count(cmdlist->begin(), cmdlist->end(), 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
@ -217,19 +262,25 @@ int lut_DeviceProxy_index(lua_State* L)
lua_pushstring(L, name);
lua_pushcclosure(L, __cmd_wrapper, 2);
}
else
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());
}
delete cmdlist;
}
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;
}
@ -244,18 +295,13 @@ int lut_DeviceProxy_newindex(lua_State* L)
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
{
std::vector<std::string>* attrlist = udata->dev->get_attribute_list();
if(!std::count(attrlist->begin(), attrlist->end(), attr_name))
{
// name is not an attribute
LUT_LOG(ERROR, "Not an attribute: %s", full_name.c_str());
return 0;
}
Tango::DeviceAttribute v = lut_toTangoType<Tango::DeviceAttribute>(L, 3, udata->attr_type(attr_name), udata->attr_format(attr_name));
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);
}
@ -263,6 +309,7 @@ int lut_DeviceProxy_newindex(lua_State* L)
{
lut_DevFailed(L, e, full_name.c_str());
}
}
return 0;
}

View File

@ -26,6 +26,7 @@
#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"
@ -35,18 +36,11 @@ class DeviceProxyWrapper
{
public:
Tango::DeviceProxy* dev;
AttrInfoMap attr_info;
CmdInfoMap cmd_info;
DeviceProxyWrapper(const char* name);
~DeviceProxyWrapper();
int attr_type(const char* name);
Tango::AttrDataFormat attr_format(const char* name);
int cmd_in_type(const char* name);
int cmd_out_type(const char* name);
private:
AttrInfoMap attr_cache;
CmdInfoMap cmd_cache;
};
// Command wrapper
@ -55,7 +49,11 @@ 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);
@ -74,7 +72,11 @@ static const luaL_Reg lut_DeviceProxy[] =
// 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 }
};

27
tests/_print_kv.lua Normal file
View 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

View File

@ -12,21 +12,9 @@
-------------------------------------------------------------------------------
local lut = require "lutango"
local print_kv = require "_print_kv"
lut.log:set_log_level(lut.log.level.WARNING)
local function print_kv(k, v, prefix)
prefix = prefix or ""
print(prefix..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
local ap = lut.AttributeProxy("sys/tg_test/1/ampli")
print("Reading state and status")

49
tests/dp_info.lua Normal file
View 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))

View File

@ -30,3 +30,7 @@ for _,v in ipairs(attrlist) do
end
print()
end
print("\nReading non existent attribute")
local ne = dp.non_existent_attr
print(tostring(ne))

View File

@ -74,3 +74,7 @@ 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))