请原谅,我甚至不知道我问的是不是正确的术语。
So...here走了。
我构建了一个自定义的Nodemcu Dali固件(来自Hackerspace Stutgart)。这包括一个达利照明控制“味道”,因为他们指的是。我不得不修改它以与最新的LUA版本一起工作。无论如何,这是工作和模块是内置在固件。
从LUA命令行/解释器(Esplorer接口,我可以调用模块,一切都很好。
要使用您输入的模块:
dali.arc(address_Mode,0,parameter)或
dali.send(Address_Mode,Command,Address,parameter)Address_mode可以是:dali.SLAVE , dali.GROUP
命令可以是dali.UP_200MS , dali.IMMEDIATE_OFF , dali.GO_TO_SCENE --... about 50 commands.
向所有驱动器发送光级128的示例命令如下:
dali.arc(dali.BROADCAST,0,128) -- direct arc mode ( all lights,*ignored*,50% dimmed)我想用MQTT来控制这个东西。我可以使用MQTT主题:
dali_topic/arc_broadcast -- for dali.arc(dali.BROADCAST,var1,var2)
dali_topic/group -- for dali.arc(dali.GROUP,var1,var2)
dali_topic/slave -- for dali.arc(dali.SLAVE,var1,var2)并且我的有效负载字符串只有2个变量,逗号分隔,例如。0,128。
我每天都可以做到这一点,但现在我想让它“更好”……
我希望能够发送消息“dali.BROADCAST,0,128”,然后代码应该将其排序到一个包含元素的表中:
table[1] = dali.BROADCAST
table[2] = 0
table[3] = 128并调用dali.arc(table1,table2,table3)
表创建工作正常,但我无法将dali.BROADCAST传递给模块/function?打电话。首先是因为它是一个字符串,其次是因为它不能转换为数字或任何需要替换的东西。
如果可以这样做,Command字段也可以与MQTT有效负载一起发送,而不需要50个MQTT主题。
我想我也可以尝试许多if语句或搜索查找表,但也许有一种简单的方法可以将命令字段插入到函数/模块调用中?
非常感谢您的帮助。
编辑以下是一些LUA输出:
table ={"dali.BROADCAST",0,128}
dali.arc(table[1],table[2],table[3])结果:
Lua error: stdin:1: bad argument #1 to 'arc' (number expected, got boolean)因为如果你使用print("dali.BROADCAST"),你得到的是nil
table[4] = dali.BROADCAST
dali.arc(table[4],table[2],table[3])结果工作正常。
print( type(dali.BROADCAST ))提供number
那么,如何传递接收为" dali.BROADCAST“的mqtt字符串dali.BROADCAST并将其转换为dali.BROADCAST呢?注意:我不是在发送"“该消息是由MQTT以CSV字符串的形式发送的。
从dali模块的固件源..在模块文件夹中: dali.c
LROT_BEGIN(dali, NULL, 0)
LROT_FUNCENTRY( setup, dali_setup )
LROT_FUNCENTRY( arc, dali_arc )
LROT_FUNCENTRY( send, dali_send )
LROT_NUMENTRY( BROADCAST, BROADCAST )
LROT_NUMENTRY( SLAVE, SLAVE )
LROT_NUMENTRY( GROUP, GROUP )
LROT_NUMENTRY( IMMEDIATE_OFF, DALI_IMMEDIATE_OFF)
LROT_NUMENTRY( GO_TO_SCENE, DALI_GO_TO_SCENE)shackspace github链接是正确的,它只是基于LUA1.45或类似的低版本。我只需修改Modules中的dali.c即可使用最新的LUA。
固件中的相关dali文件位于app/modules app/include app/dali文件夹中
发布于 2020-11-09 15:29:47
编辑:考虑到这一点,您可能总是会对dali进行索引,在这种情况下,您可以直接这样做,只需像这样构造您的表:
table[1] = "arc"
table[2] = "BROADCAST"
table[3] = 0
table[4] = 128这样,您可以通过执行dali[table[2]]获得dali.BROADCAST,通过执行dali[table[1]]获得dali.arc。
提示:您可能仍然应该保留一个白名单,说明允许在何处执行操作,因为有人可以发送任何字符串,而您的程序不应该盲目地使用该字符串对dali表进行索引并返回它。
你可能想要像this这样的东西
相关代码如下:
function deepindex(tab, path)
if type(path)~="string" then
return nil, "path is not a string"
end
local index, rest = path:match("^%.?([%a%d]+)(.*)")
if not index then
index, rest = path:match("^%[(%d+)%](.*)")
index = tonumber(index)
end
if index then
if #rest>0 then
if tab[index] then
return deepindex(tab[index], rest)
else
return nil, "full path not present in table"
end
else
return tab[index]
end
else
return nil, "malformed index-path string"
end
end家庭作业:这个函数也适用于数字的[]索引,这是你不需要的。应该很容易将函数简化为只使用.进行字符串索引
您可以在全局环境中使用它来使用单个字符串对其进行索引:
deepindex(_G, "dali.BROADCAST")
-- Which is the same as
_G.dali.BROADCAST
-- And, unless dali is a local, also
dali.BROADCAST但请记住,这允许您使用任何内容对_G进行远程索引,这是一个巨大的安全噩梦。最好这样做:
local whitelist = {}
whitelist.dali = dali
deepindex(whitelist, "dali.BROADCAST") -- this works
deepindex(whitelist, "some.evil.submodule") -- This does nothing发布于 2020-11-09 11:56:51
我在找一个有更多细节的维基词条,但我什么也没找到。如果您碰巧知道文档在哪里,其中指定了有关可用Lua命令的更多信息,请在您的问题中包含链接。
看起来可能还有其他函数可以接近相同的结果,但我不确定它们在您的特定构建中是如何表达的。
https://github.com/shackspace/nodemcu-firmware-dali/blob/master/app/dali/dali_encode.c
当你print( type( dali.BROADCAST ))的时候会返回什么?
我猜想它可能是原始的C userdata,即那个arc命令的特定大小写开关,然而,我刚刚找到了一个类似的Lua项目,它将其列为十六进制255
https://github.com/a-lurker/Vera-Plugin-DALI-Planet/blob/master/Luup_device/L_DaliPlanet1.lua
是的,它可能只是发送十六进制数字。
https://en.wikipedia.org/wiki/Digital_Addressable_Lighting_Interface
尝试发送dali.arc( 0xFF, 0x00, 0x80 )
或dali.arc( 0xFE, 0x80 )
它们使其听起来像是“1111 1110”( 0xFE )后面紧跟着亮度值,因此第二个命令可能会亮起。
我不确定为什么当您将代码放入表中时,它似乎不能发送正确的代码。你写的似乎是正确的,但它很可能是单向广播,所以你不会收到任何错误消息……
如果您不能使用arc命令来处理表格,那么使用dali.send()命令可能会更好。可能只是那个应用程序的一个缺陷。如果你不能解决它,提交一个错误报告到他们的GitHub页面。
https://stackoverflow.com/questions/64744315
复制相似问题