I am using lgi dynamic Lua binding to GObject based libraries to communicate between applications through dbus.Below is some portion of output of the dbus-send command for the method_call of my application.
method return sender=:1.2 -> dest=:1.19 reply_serial=2
array [
dict entry(
string "XYZ"
variant int32 1
)
dict entry(
string "ABC"
variant int32 0
)
dict entry(
string "EFG"
variant string "str"
)
dict entry(
string "HIJ"
variant string "8c011401-4836-4889-8fa5-32ddb894a97a"
)
dict entry(
string "KLM"
variant string "dummy"
)
Now I want to set the "DEF" value in the above output which has signature as 'a{sv}'. Below is the code I wrote to do the same:
local lgi=require 'lgi'
local Gio=lgi.require 'Gio'
local GLib=lgi.GLib
local db=require 'debugger'
local factory=function()
return Gio.bus_get_sync(Gio.BusType.SYSTEM)
end
local bus=factory()
local j=GLib.Variant.new('s','value')
local k2=GLib.Variant('a{sv}',{DEF=j})
str,err=bus:call_sync('org.destination','/my/application/obj_path','org.destination.path','Method_name',k2,nil,Gio.DBusConnectionFlags.NONE,-1)
if err then
print(err)
else
print(str)
end
When I run the above script I am facing the following error:
(process:19120): GLib-GIO-CRITICAL **: g_dbus_connection_call_sync_internal: assertion '(parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)' failed.
How to set the above value ? Where am I doing wrong ? Can someone help me ?
Thanks in advance.
The error tells you pretty clearly what the problem is. The "parameter" argument to call_sync (g_dbus_connection_call_sync in the C API) needs to be a tuple. You have provided a dictionary. Change k2 so that it is a tuple variant.
Related
Using Krakend as api gateway.
I have an endpoint configured in krakend.json:
"endpoint":"/call",
"extra_config":{
"github.com/devopsfaith/krakend-lua/proxy":{
"sources":[
"/function.lua"
],
"pre":"pre_backend(request.load())",
"live":true,
"allow_open_libs":true
}
},
"method":"POST",
"output_encoding":"json",
"headers_to_pass":[
"*"
],
"backend":[
{
"url_pattern":"/api/v1/get_client_id",
[...]]
},
The endopont "/api/v1/get_client_id" recives just a param:
{"user_mail_1":"test#test.es"}
I want, whith the lua script my endopoint "/call" recives:
{"email":"test#test.es"}
and transform on before send:
{"user_mail_1":"test#test.es"}
I tried with gsub, but use body() as "string" is no efficient.
function pre_backend( req )
print('--Backend response, pre-logic:');
local r = req;
r:params('test','test');
r:query('lovelyquery')
r:body('test','test');
lolcal v = r:body():gsub('email', 'user_mail_1')
...
Is a way to parse "req" as a table, dict or something i can transform data?
Is another way to transform REQUEST data?
EXAMPLE WORKING WITH GSUB:
function pre_backend( req )
print('--Backend response, pre-logic:');
print('--req');
print(req);
print(type(req));
local r = req;
print('--body');
print(type(r:body()));
print(r:body())
local body_transformed = r:body():gsub('email', 'user_mail_1');
print('--body_transformed');
print(body_transformed);
print(type(body_transformed));
end
Console output:
2022/02/11 09:59:52 DEBUG: [http-server-handler: no extra config]
--Backend response, pre-logic:
--req
userdata: 0xc0004f9b60
userdata
--body
string
{"email" : "test#test.es","test_field":"email"}
--body_transformed
{"user_mail_1" : "test#test.es","test_field":"user_mail_1"}
string
As we can see the gsub is not efficient becouse replace all strings.
If I can work with req as table, dict or something similar, I can replace dict key/value. ex: req['xxx] = 'xxx' or iterate req.keys
gsub stands for global substitution. It replaces all occurances of the pattern in the string.
If you just want to replace "email" infront of an email address simply use a pattern that takes this into account.
print((r:body():gsub('(")(email)("%s-:%s-"%w+#%w+%.%w+")', "%1user_mail_1%3")))
Alternatively if you knwo that you only want to replace the first occurance of email you can simply do this:
print((r:body():gsub("email", "user_mail_1", 1)))
The thrid parameter will stop gsub after the first replacement.
it has been days I'm trying to create a comboBox with all available models.
The code is this
for name , models in SortedPairs( player_manager.AllValidModels() ) do
print("name: "..name.." model: "..models)
custCbox:AddChoice(name , models , false)
end
I tried to print every name and model to know if I was wrong, but that's ok: name prints the display name and models prints the path.
The OnSelect function is this:
custCbox.OnSelect = function( index, value, data )
modelPanel:SetModel( data )
print("Data " .. data)
print("Value " .. value)
end
Data gives the display name and value gives a number.
Why?
From the DComboBox documentation:
local cbox = vgui.Create( "DComboBox", BGPanel )
...
cbox:AddChoice( "Pink", Color( 255, 0, 255 ) )
function cbox:OnSelect( index, text, data )
-- Set background panel color
BGPanel:SetBackgroundColor( data )
end
Note the difference to your
custCbox.OnSelect = function( index, value, data )
modelPanel:SetModel( data )
print("Data " .. data)
print("Value " .. value)
end
which is equivalent to
function custCbox.onSelect(index, value, data)
-- ...
end
And the example that uses the colon syntax.
function cbox:OnSelect(index, text, data)
end
is equivalent to
function cbox.OnSelect(self, index, text, data)
end
This difference causes a parameter shift by one. So what you think is index is actually your combobox, text is the selected index and data is the choices text.
Please read
Lua 5.4 Reference Manual: 3.4.10 Function Calls
Lua 5.4 Reference Manual: 3.4.11 Function Definitions
This is a very common mistake among beginners.
I have a lua table which I used to share values between files. But I am getting confused in the following case
utility.lua file
M = {}
M.host_url = '192.168.0.1'
function M.myFunc()
print(M.host_url )
end
return M
in my main.lua
utility = require('utility')
utility.myFunc() -- this gives me 'a nil value' error
I get an error (nil value) for the host_url?
In M.myFunc doing only print action that function nothing will be return.in your utility file returning whole array see he below code that will clear your doudt.
In main.lua
utility = require('util')
value = utility.host_url
print(value)
I am having a table data in string form. Sample is given below:
{"engName1":"HOLDER","validDurPeriod":3,"engName2":"INFORMATION","appStatus":2,"stayExpDate":"01/10/2012","engName3":"","appExpDate":"12/04/2010"}
How can I convert it into a proper table type variable so that I can access keys.I am new to lua and I am not aware if there is any existing method to do so.
There is plenty of JSON parsers available for Lua, for example dkjson:
local json = require ("dkjson")
local str = [[
{
"numbers": [ 2, 3, -20.23e+2, -4 ],
"currency": "\u20AC"
}
]]
local obj, pos, err = json.decode (str, 1, nil)
if err then
print ("Error:", err)
else
print ("currency", obj.currency)
for i = 1,#obj.numbers do
print (i, obj.numbers[i])
end
end
Output:
currency €
1 2
2 3
3 -2023
4 -4
Try this code to start with
J=[[
{"engName1":"HOLDER","validDurPeriod":3,"engName2":"INFORMATION","appStatus":2,"stayExpDate":"01/10/2012","engName3":"","appExpDate":"12/04/2010"}
]]
J=J:gsub("}",",}")
L={}
for k,v in J:gmatch('"(.-)":(.-),') do
L[k]=v
print(k,v)
end
You'll still need to convert some values to number and remove quotes.
Alternatively, you can let Lua do the hard work, if you trust the source string. Just replace the loop by this:
J=J:gsub('(".-"):(.-),','[%1]=%2,\n')
L=loadstring("return "..J)()
Situation:
I want to save the record of a data which is a value of the sensor in the certain file.
Code is..
--Header file
require("TIMER")
require("IPBOX")
require("ANALOG_IN")
require("LOG")
function OnExit()
print("Exit code...do something")
end
function main()
timer = "Timer"
local analogsensor_1 = "AIR_1"
local analogsensor_2 = "AIR_2"
local timestr = os.data("%Y-%m-%d %H:%M:%S")
-- open the file for writing binary data
local filehandle = io.open("collection_of_data.txt", "a")
while true do
valueOfSensor_1 = ANALOG_IN.readAnalogIn(analogsensor_1);
valueOfSensor_2 = ANALOG_IN.readAnalogIn(analogsensor_2);
if (valueOfSensor_1 > 0 and valueOfSensor_2 > 0) then
-- save values of sensors
filehandle:write(timestr, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2)"\n");
-- save values using rolling log appender:
LOG.log_event( ScenarioLoggerDevicenameInDeviceList, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2), "any other string you wish to add", "etc", "etc")
LOG.log_event( ScenarioLoggerDevicenameInDeviceList, " -The Value of the Sensors: ", tostring(valueOfSensor_1))
print("Hello3"..valueOfSensor_1)
end
TIMER.sleep(timer,500)
end
-- close the file
filehandle:close()
end
print("start main")
main()
In this line:
filehandle:write(timestr, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2)"\n");
I get an error:
"attemp to index global 'filehandle' (a nil value)"
How can I fix it?
io.open returns nil if it cannot open the file. This can be due to "file not found", "permissions denied" and maybe other reasons. To figure out the problem, io.open has a second return value, which lets you inspect the error (in fact, it even returns a third value, which is an error-code integer - but its meaning is system dependent).
Change:
local filehandle = io.open("collection_of_data.txt", "a")
to
local filehandle, message = io.open("collection_of_data.txt", "a")
if not filehandle then
print(message)
end
You can also use the following Lua idiom:
local filehandle = assert(io.open("collection_of_data.txt", "a"))
This will do the same. If the first argument to assert is nil, then the second argument (the second return value of io.open will be printed. If the first argument is not nil, it will simply be returned.