首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LUA (ESP8266)如何通过字符串调用/输入模块命令

LUA (ESP8266)如何通过字符串调用/输入模块命令
EN

Stack Overflow用户
提问于 2020-11-09 08:05:11
回答 2查看 91关注 0票数 0

请原谅,我甚至不知道我问的是不是正确的术语。

So...here走了。

我构建了一个自定义的Nodemcu Dali固件(来自Hackerspace Stutgart)。这包括一个达利照明控制“味道”,因为他们指的是。我不得不修改它以与最新的LUA版本一起工作。无论如何,这是工作和模块是内置在固件。

从LUA命令行/解释器(Esplorer接口,我可以调用模块,一切都很好。

要使用您输入的模块:

代码语言:javascript
复制
dali.arc(address_Mode,0,parameter)

代码语言:javascript
复制
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的示例命令如下:

代码语言:javascript
复制
dali.arc(dali.BROADCAST,0,128)   -- direct arc mode ( all lights,*ignored*,50% dimmed)

我想用MQTT来控制这个东西。我可以使用MQTT主题:

代码语言:javascript
复制
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”,然后代码应该将其排序到一个包含元素的表中:

代码语言:javascript
复制
table[1] = dali.BROADCAST
table[2] = 0
table[3] = 128

并调用dali.arc(table1,table2,table3)

表创建工作正常,但我无法将dali.BROADCAST传递给模块/function?打电话。首先是因为它是一个字符串,其次是因为它不能转换为数字或任何需要替换的东西。

如果可以这样做,Command字段也可以与MQTT有效负载一起发送,而不需要50个MQTT主题。

我想我也可以尝试许多if语句或搜索查找表,但也许有一种简单的方法可以将命令字段插入到函数/模块调用中?

非常感谢您的帮助。

编辑以下是一些LUA输出:

代码语言:javascript
复制
table ={"dali.BROADCAST",0,128}
dali.arc(table[1],table[2],table[3])

结果:

代码语言:javascript
复制
Lua error:  stdin:1: bad argument #1 to 'arc' (number expected, got boolean)

因为如果你使用print("dali.BROADCAST"),你得到的是nil

代码语言:javascript
复制
table[4] = dali.BROADCAST
dali.arc(table[4],table[2],table[3])

结果工作正常。

代码语言:javascript
复制
print( type(dali.BROADCAST ))

提供number

那么,如何传递接收为" dali.BROADCAST“的mqtt字符串dali.BROADCAST并将其转换为dali.BROADCAST呢?注意:我不是在发送"“该消息是由MQTT以CSV字符串的形式发送的。

从dali模块的固件源..在模块文件夹中: dali.c

代码语言:javascript
复制
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文件夹中

EN

回答 2

Stack Overflow用户

发布于 2020-11-09 15:29:47

编辑:考虑到这一点,您可能总是会对dali进行索引,在这种情况下,您可以直接这样做,只需像这样构造您的表:

代码语言:javascript
复制
table[1] = "arc"
table[2] = "BROADCAST"
table[3] = 0
table[4] = 128

这样,您可以通过执行dali[table[2]]获得dali.BROADCAST,通过执行dali[table[1]]获得dali.arc

提示:您可能仍然应该保留一个白名单,说明允许在何处执行操作,因为有人可以发送任何字符串,而您的程序不应该盲目地使用该字符串对dali表进行索引并返回它。

你可能想要像this这样的东西

相关代码如下:

代码语言:javascript
复制
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

家庭作业:这个函数也适用于数字的[]索引,这是你不需要的。应该很容易将函数简化为只使用.进行字符串索引

您可以在全局环境中使用它来使用单个字符串对其进行索引:

代码语言:javascript
复制
deepindex(_G, "dali.BROADCAST")
-- Which is the same as
_G.dali.BROADCAST
-- And, unless dali is a local, also
dali.BROADCAST

但请记住,这允许您使用任何内容对_G进行远程索引,这是一个巨大的安全噩梦。最好这样做:

代码语言:javascript
复制
local whitelist = {}
whitelist.dali = dali

deepindex(whitelist, "dali.BROADCAST") -- this works
deepindex(whitelist, "some.evil.submodule") -- This does nothing
票数 1
EN

Stack Overflow用户

发布于 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页面。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64744315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档