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简介相关推荐

  1. luci编程 openwrt_openwrt开源系统LUCI配置界面

    转自:http://www.right.com.cn/forum/thread-131035-1-1.html 本人菜鸟,最近在学习这方面的知识,在参考资料的基础上总结如下内容. 这篇文章针对如何对o ...

  2. 决策树编程python_Python如何制定决策:编程中的控制流简介

    决策树编程python by Ivan Leo 伊万·利奥(Ivan Leo) Python如何制定决策:编程中的控制流简介 (How Python makes decisions: an intro ...

  3. Java并发编程一线程池简介

    推荐:Java并发编程汇总 Java并发编程一线程池简介 为什么我们需要使用线程池? 我们知道线程是一种比较昂贵的资源,我们通过程序每创建一个线程去执行,其实操作系统都会对应地创建一个线程去执行我们的 ...

  4. 网络编程:网络协议简介

    这是张富涛的第10篇原创 网络编程:网络协议简介 网络协议在网络编程中是一个比较神秘的概念,今天就由我们揭开它神秘的面纱吧. 1. 什么是网络协议? 网络协议是指对于网络中传输的数据格式的规定.在计算 ...

  5. Matlab编程入门指南:简介、安装、学习路线和几十个编程案例分析。

    一.Matlab编程入门指南:简介.安装.学习路线和几十个编程案例分析. 1.Matlab编程语言是一种广泛应用于科学计算.工程计算.数据分析.统计分析.信号处理等领域的高级数值计算和数据可视化软件. ...

  6. 【华为】可编程ASIC设计方法简介(一)

    本次分享华为公司的<大规模逻辑设计指导书>中的"可编程ASIC设计方法简介"的部分内容. 关键词 :可编程逻辑电路 ASIC FPGA. 摘 要 :本文根据当今可编程逻 ...

  7. 【Groovy】编译时元编程 ( ASTTransformation#visit 方法简介 | org.codehaus.groovy.ast.ModuleNode 脚本节点 )

    文章目录 一.ASTTransformation#visit 方法简介 二.org.codehaus.groovy.ast.ModuleNode 脚本节点 一.ASTTransformation#vi ...

  8. 机器学习速成课程 | 练习 | Google Development——编程练习:神经网络简介

    神经网络简介 学习目标: 使用 TensorFlow DNNRegressor 类定义神经网络 (NN) 及其隐藏层 训练神经网络学习数据集中的非线性规律,并实现比线性回归模型更好的效果 在之前的练习 ...

  9. 机器学习速成课程 | 练习 | Google Development——编程练习:Pandas 简介

    Pandas 简介 学习目标: 大致了解 pandas 库的 DataFrame 和 Series 数据结构 存取和处理 DataFrame 和 Series 中的数据 将 CSV 数据导入 pand ...

  10. java基础:网络编程(一)简介

    网络编程简介 这些知识点在学习计算机网络时都有详细讲,我这就简单介绍下,具体的看计算机网络相关知识. 1.软件结构 常见的软件结构有C/S和B/S C/S (Client/Server) 表示客户端/ ...

最新文章

  1. 鼠标跟随flash代码_FLASH如何制作密码锁功能(AS3)
  2. 马斯克星际火箭原型机爆炸!测试失败,3年内至少还需迭代19版
  3. php多用户商城,php多用户商城选择开源的好
  4. Ubuntu 下 Python自由切换
  5. (转载)python多行注释
  6. c语言标准库 swap,swap
  7. Spark Structured SQL报错:Stream stream joins without equality predicate is not supported
  8. pap认证过程_PPP协议当中LCP协商过程详解和PAP认证原理介绍
  9. 「leetcode」142.环形链表II,如何求环?如何找入口?各个细节讲的明明白白!你疑惑的地方,这里都有!
  10. 全国计算机报名入口攀枝花学院,2017年攀枝花学院艺术类专业考试网上报名入口...
  11. PHP程序员40点陋习
  12. win7计算机管理快捷键,win7系统快捷键有哪些|win7常用的15个快捷键
  13. 小米便签产品级的源码
  14. MTSP遗传算法解决
  15. Linux QT无法切换中文输入法
  16. 录屏:mac系统自带功能录制屏幕的方法
  17. php的sql什么意思,php sql删除语句是什么
  18. 移植 u-boot-2020.07 到 iTOP-4412(二)地址相关码 boot
  19. 基于多项式拟合的结构光系统标定
  20. 计算机大赛可以跨学校组队吗,大学生创新创业大赛可以跨校组队吗

热门文章

  1. python爬虫大众点评字体反爬
  2. python常用单词读法-Python常用单词
  3. dingo php,Laravel Lumen RESTFul API 扩展包:Dingo API(一) —— 安装配置篇
  4. TestCenter测试管理工具功能详解八(M)
  5. anaconda必须安装在c盘吗_安装anaconda
  6. linux磁盘满了删除docker文件夹,Docker磁盘空间使用分析与清理的方法
  7. rebase和merge区别
  8. HtmlHelper、TagHelper、局部视图、视图组件
  9. onvif 添加H265开发流程
  10. 我认为到现在写的最好的一本小说 《紫川》