luci编程 openwrt_openWRT之Luci简介
Luci简介:
lua是一个小巧的脚本语言,容易嵌入其他语言。轻量级LUA语言的官方版本只包含一个精简的核心和最基本的库,使lua体积小、启动速度快,从而适合嵌入在别的程序里。
uci(unified configuration interface):统一配置接口。即UCI系统。
//UCI系统用途就是为OpenWrt提供一个集中控制的接口。OpenWrt实现的这个工具,能够让你的不管是Lua还是PHP程序,或者SHELL程序或C程序,只要执行命令传输参数就能达到修改系统参数的目的。
//UCI系统的优势是UCI可以视为OpenWrt系统功能设置的主要用户配置接口,通常来说这些配置与系统的功能关联性较大,想像一下我们平常所使用的路由器或嵌入式设备中的WEB界面中的那些配置项,就是路由器或嵌入式设备系统所集成了的功能。常见的例子如路由器的网络接口设置,无线参数设置,logging设置和远程登录设置等。
Luci的启动--uhttpd
uhttpd是一个简单的web服务器程序,主要是cgi的处理,openwrt是利用uhttpd作为web服务器,实现客户端web页面配置功能。对于request处理方式,采用的是cgi,而所用的cgi程序就是luci
LuCI
首先回答一个问题:什么是Luci?
>LuCI是OpenWrt上的Web管理界面,LuCI采用了MVC三层架构,使用Lua脚本开发.
简单地说,Luci就是用来做openwrt的页面的.不同于常见的html+css+javascript,Openwrt是用lua脚本语言开发的.
怎么开发一个页面呢?
要开发一个新的功能页面,开发者只要根据MVC框架写些简单的lua脚本,剩下的部分由openwrt为你自动完成.
说到MVC框架了,什么是MVC框架呢?
MVC是model+view+controller的简写.为了便于开发,openwrt将实现不同功能的lua脚本放在不同的文件夹中.
什么是controller控制器?
我们在这里设置功能在页面的位置,同时设置点击页面后,将要调用的功能.是要去Model模型读写配置数据呢?还是要呈现一个静态页面,或者是直接执行lua脚本函数.
什么是model模型?
这里我们常用的是,通过cbi模块和UCI(统一配置接口)进行交互.简单地说,就是我们在这里将页面和路由器里面的配置关联起来,从而将页面的设置写到路由器当中.
什么是view视图?
这个应该是最容易理解的,就是呈现的页面的样式,有点类似于传统的html页面.
上面说到了UCI(Unified Configuartion Interface),这是什么龟?
openwrt将配置用统一的格式书写,放在规定的地方(/etc/config/),同时提供接口函数进行读取和设置.
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式:[1]
Model(模型)表示应用程序核心(比如数据库记录列表)。
View(视图)显示数据(数据库记录)。
Controller(控制器)处理输入(写入数据库记录)。
MVC 模式同时提供了对 HTML、CSS 和 JavaScript 的完全控制。
Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。
通常模型对象负责在数据库中存取数据。
View(视图)是应用程序中处理数据显示的部分。
通常视图是依据模型数据创建的。
Controller(控制器)是应用程序中处理用户交互的部分。
通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC 分层有助于管理复杂的应用程序,因为您可以在一个时间内专门关注一个方面。例如,您可以在不依赖业务逻辑的情况下专注于视图设计。同时也让应用程序的测试更加容易。
MVC 分层同时也简化了分组开发。不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。
------------------------------------------------------------------------------------
http://lib.csdn.net/article/embeddeddevelopment/34868
------------------------------------------------------------------------------------
Luci
轻量级LUA语言的官方版本只包括一个精简核心和最基库。这使得LUA体积小、启动速度快,从而适合嵌入在别的程序里。
UCI是Openwrt中为实现所有系统配置的一个接口,英文名 Unified Configuration Interface,即统一配置接口。
LuCI即是这两个项目的合体,可以实现路由网页配置界面。
先学习LUA脚本编程.
LuCI使用 MVC(模型 /视图 /控制 )模型 ,在/usr/lib/lua/luci/下有三个目录 model、view、controller,它们分别对应 M、V、C。我们要做的主工作就是基于 LuCI框架编写LUA脚本、在html页面中嵌入LUA脚本。
LuCI将网页中的每一个菜单视作节点,如下图1:
这里有一级节点Status、System、Network、Logout,二级节点 System、Administration、Software、Startup等。我们使用浏览器向路由发起请求时, LuCI会从controller目录下的 index.lua开始组织这些节点。index.lua中定义了根节点 root,其他所有的节点都挂在这个根节点上。
我们可以将controller目录下的这些.lua文件叫做模块,这样的模块文件第一行必须是如下格式:
module("luci.controller.xx.xx.xx",package.seeall)
上面的luci.controller.xx.xx.xx表示该文件的路径luci. controller表示 /usr/lib/lua/luci/controller/,比如上面的index.lua其第一行为: module("luci.controller.admin.index", package.seeall),表示其路径为: /usr/lib/lua/luci/controller/admin/index.lua
接着是定义一个index方法,其主要工作是调用entry方法创建节点,可以多次调用创建多个节点。其调用方式如下:
entry (path, target, title, order)
a.path指定该节点的位置 (例如 node1.node2.node3)
b.target指定当该节点被调度( 即用户点击) 时的行为主要有三种:
call、template和 cbi,后面有3个实例。
c.title:标题,即我们在网页中看到的菜单
d.order:同一级节点之间的顺序,越小越靠前,反之越靠后(可选)
LuCI默认开启了缓存机制,这样当我们修改 了代码后,不会立即生效除非删缓存操作如下:
root@OpenWrt:/# rm -rf /tmp/luci-*
为了便于调试,我们可以直接关闭缓存,修改配置文件 /etc/config/luci,操作如下: 操作如下:
root@OpenWrt:/# uci set luci.ccache.enable=0
root@OpenWrt:/# uci commit
eg1:call
root@OpenWrt:/# cat /usr/lib/lua/luci/controller/example.lua
module("luci.controller.example",package.seeall)
function index()
entry({"admin","example"},firstchild(),"Example",60)
entry({"admin","example","first"},call("first_action"),"First")
end
function first_action()--加载 /usr/lib/lua/luci/view/header.htm
luci.template.render("header")--输出 html内容
luci.http.write("
hello world_call
")
end
说明:
创建一级菜单example,firstchild()表示链接到其第一个子节点,即当我们单 击菜Example时,LuCI将调度其第一个子节点。"Example"即在网页中显示的菜单。
60表示其顺序,LuCI自带的模块顺序为:
Administration(10),Status(20),System(30),Network(50),Logout(90)。
call("first_action")表示当子节点被调度时将执行下面定义的方法first_action()
在lua脚本中,使用 --表示单行注释,--[[ --]]表示多行注释。
eg2:template
效果call一样,不同的是上节使用call调度执行一个函数,本节直接用html页面。
root@OpenWrt:/# cat /usr/lib/lua/luci/controller/example.lua
module("luci.controller.example",package.seeall)
function index()
entry({"admin","example"},firstchild(),"Example",60)
entry({"admin","example","first"},template("example/example"),"First")
end
root@OpenWrt:/# mkdir /usr/lib/lua/luci/view/example/
root@OpenWrt:/# cat /usr/lib/lua/luci/view/example/example.htm
hello world_template
说明:
创建一级菜单example,firstchild()表示链接到其第一个子节点,即当我们单击菜当我们单 击菜Example时,LuCI将调度其第一个子节点。"Example"即
在网页中显示的菜单。
60表示其顺序,LuCI自带的模块顺序为:
Administration(10),Status(20),System(30),Network(50),Logout(90)
template ("example/example")表示当子节点被调度时LuCI将使用我们指定的html页面 /usr/lib/lua/luci/view/example/example.htm来生成页面。
eg3:cbi
该方法与UCI配置息相关,主要用来修改UCI配置文件以及使配置生效。
root@OpenWrt:/# cat /usr/lib/lua/luci/controller/example.lua
module("luci.controller.example",package.seeall)
function index()
entry({"admin","example"},firstchild(),"Example",60)
entry({"admin","example","first"},template("example/example"),"First",1)
if nixio.fs.access("/etc/config/example")then
entry({"admin","example","second"},cbi("example/example"),"Second",2)
end
end
root@OpenWrt:/# mkdir /usr/lib/lua/luci/model/cbi/example
root@OpenWrt:/# vim /usr/lib/lua/luci/model/cbi/example/example.lua
root@OpenWrt:/# cat /usr/lib/lua/luci/model/cbi/example/example.lua
m=Map("example","Example for cbi","This is very simple example for cbi")
return m
//有关Map相关的用法参考LuCI官方文档:
http://luci.subsignal.org/trac/wiki/Documentation/CBI
Map (config, title, description)
现在刷新网页,看下效果:
没有出现Second这个节点,是因为还没创建配置文件 /etc/config/example,touch命令创建这个文件:
root@OpenWrt:/# touch /etc/config/example
现在还没添加具体的业务功能,只是一个模型下面继续修改 /usr/lib/lua/luci/model/cbi/example/example.lua,内容如下:
root@OpenWrt:/# cat /usr/lib/lua/luci/model/cbi/example/example.lua
m=Map("example","Example for cbi","This is very simple example for cbi")
s=m:section(TypedSection,"example","Example","The section of type is example")
s.addremove=true
s.anonymous=false
n=s:option(Value,"num","Number")
n.rmempty=true
return m
----------------图2705
----------------图2706
现在在路由器开发板上查看一些配置文件:
root@OpenWrt:/# cat /etc/config/example
config example 'first'
option num '12'
root@OpenWrt:/# uci export example
package example
config example 'first'
option num '12'
重点说明:
一般情况下,一个配置文件与启动脚本对应,比如/etc/config/network和/etc/init.d/network,当我们在页面上单击Save & Apply时,LuCI首先保存配置文件,然后就以 reload为参数调用配置文件对应的启动脚本。
为配置文件example创建一个启动脚本/etc/init.d/example,同时为其添加可执行权限。其内容如下:
root@OpenWrt:/# cat /etc/init.d/example
#!/bin/sh /etc/rc.common
#example
START=50
start(){
echo "start example">/dev/ttyS0
}
reload(){
echo "reload example">/dev/ttyS0
}
另外,LuCI通过以配置文件名作为参数调用/sbin/luci-reload来使配置生效,而luci-reload会解析另一个配置文件/etc/config/ucitrack,我们需要将我们的example添加进去 。用 vi打开 /etc/config/ucitrack,在最后添加如下内容:
root@OpenWrt:/# vim /etc/config/ucitrack
root@OpenWrt:/# tail -2 /etc/config/ucitrack
config example
option init example
当我们单击网页中的Save&Apply后,LuCI将会调用/sbin/luci-reload example,最终调用到/etc/rc.d/example中的函数,因此还需要执行如下操作:
root@OpenWrt:/# /etc/init.d/example enable
现在单击网页中的Save & Apply,可以看到开发板中输出了如下内容:
reload example
说明确实执行了/etc/init.d/example中的reload函数。
---------------------------------------------------------
CBI参考手册:
1. Map
Map (config, title, description)
//映射一个配置文件,返回一个Map对象。其中description可以省略。
m = Map("example", "Example for cbi"), "This is very simple example for cbi")
2. section
s = m:section(TypedSection, type, title, description)
//根据section类型解析section
s = m:section(NamedSection, name, type, title, description)
//根据section类型和名称解析section,其中m为Map返回的对象,s为Map类的成员函数 section返回的section对象。
section对象有一些属性如下:
template: html模板,默认为 "cbi/tsection"
addremove:是否可以增加和删除,默认为 false
anonymous:是否为匿名section,默认为 false
3. option
o = s:option(type, name, title, description)
//调用section对象的成员函数option,返回一个option对象。其中 type有多个取值: 有多个取值:Value、DynamicList、Flag、ListValue。
option对象的一些属性如下:
rmempty:如果为空值则删除该选项,默认为true
default:默认值,如果为空值,则设置该默认值
datatype:限制输入类型。 例如 "and(uinteger,min(1))"限制输入无符号整形而且大于 0,"ip4addr"限制输入IPv4地址,"port"限制输入类型为端口,更多参考/usr/lib/lua/luci/cbi/datatypes.lua
placeholder:占位符 (html5才支持 )
4. Tab
s:tab(tabname, title)
//调用section的tab函数创建一个名称为tabname,标题为title的Tab标签。
对应的option则使用taboption
s:taboption(tabname, type, name, title)
在指定的tabname下创建一个option。
luci编程 openwrt_openWRT之Luci简介相关推荐
- luci编程 openwrt_openwrt开源系统LUCI配置界面
转自:http://www.right.com.cn/forum/thread-131035-1-1.html 本人菜鸟,最近在学习这方面的知识,在参考资料的基础上总结如下内容. 这篇文章针对如何对o ...
- 决策树编程python_Python如何制定决策:编程中的控制流简介
决策树编程python by Ivan Leo 伊万·利奥(Ivan Leo) Python如何制定决策:编程中的控制流简介 (How Python makes decisions: an intro ...
- Java并发编程一线程池简介
推荐:Java并发编程汇总 Java并发编程一线程池简介 为什么我们需要使用线程池? 我们知道线程是一种比较昂贵的资源,我们通过程序每创建一个线程去执行,其实操作系统都会对应地创建一个线程去执行我们的 ...
- 网络编程:网络协议简介
这是张富涛的第10篇原创 网络编程:网络协议简介 网络协议在网络编程中是一个比较神秘的概念,今天就由我们揭开它神秘的面纱吧. 1. 什么是网络协议? 网络协议是指对于网络中传输的数据格式的规定.在计算 ...
- Matlab编程入门指南:简介、安装、学习路线和几十个编程案例分析。
一.Matlab编程入门指南:简介.安装.学习路线和几十个编程案例分析. 1.Matlab编程语言是一种广泛应用于科学计算.工程计算.数据分析.统计分析.信号处理等领域的高级数值计算和数据可视化软件. ...
- 【华为】可编程ASIC设计方法简介(一)
本次分享华为公司的<大规模逻辑设计指导书>中的"可编程ASIC设计方法简介"的部分内容. 关键词 :可编程逻辑电路 ASIC FPGA. 摘 要 :本文根据当今可编程逻 ...
- 【Groovy】编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )
文章目录 一.ASTTransformation#visit 方法简介 二.org.codehaus.groovy.ast.ModuleNode 脚本节点 一.ASTTransformation#vi ...
- 机器学习速成课程 | 练习 | Google Development——编程练习:神经网络简介
神经网络简介 学习目标: 使用 TensorFlow DNNRegressor 类定义神经网络 (NN) 及其隐藏层 训练神经网络学习数据集中的非线性规律,并实现比线性回归模型更好的效果 在之前的练习 ...
- 机器学习速成课程 | 练习 | Google Development——编程练习:Pandas 简介
Pandas 简介 学习目标: 大致了解 pandas 库的 DataFrame 和 Series 数据结构 存取和处理 DataFrame 和 Series 中的数据 将 CSV 数据导入 pand ...
- java基础:网络编程(一)简介
网络编程简介 这些知识点在学习计算机网络时都有详细讲,我这就简单介绍下,具体的看计算机网络相关知识. 1.软件结构 常见的软件结构有C/S和B/S C/S (Client/Server) 表示客户端/ ...
最新文章
- 鼠标跟随flash代码_FLASH如何制作密码锁功能(AS3)
- 马斯克星际火箭原型机爆炸!测试失败,3年内至少还需迭代19版
- php多用户商城,php多用户商城选择开源的好
- Ubuntu 下 Python自由切换
- (转载)python多行注释
- c语言标准库 swap,swap
- Spark Structured SQL报错:Stream stream joins without equality predicate is not supported
- pap认证过程_PPP协议当中LCP协商过程详解和PAP认证原理介绍
- 「leetcode」142.环形链表II,如何求环?如何找入口?各个细节讲的明明白白!你疑惑的地方,这里都有!
- 全国计算机报名入口攀枝花学院,2017年攀枝花学院艺术类专业考试网上报名入口...
- PHP程序员40点陋习
- win7计算机管理快捷键,win7系统快捷键有哪些|win7常用的15个快捷键
- 小米便签产品级的源码
- MTSP遗传算法解决
- Linux QT无法切换中文输入法
- 录屏:mac系统自带功能录制屏幕的方法
- php的sql什么意思,php sql删除语句是什么
- 移植 u-boot-2020.07 到 iTOP-4412(二)地址相关码 boot
- 基于多项式拟合的结构光系统标定
- 计算机大赛可以跨学校组队吗,大学生创新创业大赛可以跨校组队吗
热门文章
- python爬虫大众点评字体反爬
- python常用单词读法-Python常用单词
- dingo php,Laravel Lumen RESTFul API 扩展包:Dingo API(一) —— 安装配置篇
- TestCenter测试管理工具功能详解八(M)
- anaconda必须安装在c盘吗_安装anaconda
- linux磁盘满了删除docker文件夹,Docker磁盘空间使用分析与清理的方法
- rebase和merge区别
- HtmlHelper、TagHelper、局部视图、视图组件
- onvif 添加H265开发流程
- 我认为到现在写的最好的一本小说 《紫川》