OpenWrt Forum Archive

Topic: LuCi web gui based on angular js

The content of this topic has been archived between 18 Apr 2018 and 22 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I'm currently working on a replacement for the luci2 daemon which is for a company I work for.

We have looked at our alternatives with luci2 and came to the conclusion that we must make better use of modern javascript frameworks such as angularjs in the gui. We wanted to have a user interface that was easy to program, quick to setup and easy to test.

So I have started a project called luci-express which is built on top of ubus to communicate with the router. It is also an angularjs application making it very easy for you to extend the gui and still have full freedom regarding the layout. And full multilanguage support is supported too. For that I use grunt and po files. 

The project is located at: https://github.com/mkschreder/luci-express

Please note that at the moment there is not much there but you can test the gui locally using nodejs and running "node server.js". This friday I have added the code as a package to our in house version of openwrt.

It would be nice if more people can take a look at the code and see what possibilities we have to develop a fully angular based replacement for luci.

// Martin

Nice and thank you for making it an open-source project.

Great idea. I can't contribute but would love to see the direction you're taking with this. Maybe post some screenshots, which might also generate some interest from those that can help.

What are your thoughts on memory budgets?  Do you think it'll be workable on devices with 64MB memory, or are you looking toward larger devices?

I am in the early stages of getting a nodejs project running on a 64MB device (Carambola2) and my biggest constraint seems to be RAM.

@danielchisholm, it works on any device that can serve static files. The angular framework runs in your browser. The gui communicates with device through jsonrpc. Jsonrpc is already implemented in openwrt in the form of ubus daemon.

So all you need to do to add new functions on the device is write appropriate rpc calls in C (on the device) and then access them easily through the supplied $rpc service in the browser (in angular). smile

nice project!

I'm curious, so today I've try to setup a local server, but it seems that performing an:

npm install

It was unable to retrieve all the needed dependencies...

I was missing something??


if not:
performing

npm install -g 

doesn't help very much (too many modules still missing) so, can I kindly ask you to upload somewhere the package.json output of

npm init

thank oyu very much in advance,
regards.

@mirko47, try latest commit. If you ever get a "cannot find module" error then just do "npm install <module_name>" in the project directory. It will install the module into local node_modules directory of the project (I wouldn't use -g option unless you want to install it globally)

Some notes on latest commit:
- plugin and themes system is in place.
- rpc forwarding is in place (currently configurable in server.js): no more cross origin request hassle
- on demand dynamic loading of all scripts based on config (lots of room for improvement!): no more long list of includes in index.html
- many page templates are in place (although not much is implemented yet - much work needs to be done. Most of it involves creating gui pages and connecting them with ubus functions.)

Page examples:
- router/pages/settings.uci - check this out for how to easily set up a complete control panel for all uci funcitons (you will need to modify access control to access the actual uci calls). This example sets up tables from uci configs and let's the user modify any uci setting. It is available in the gui when expert mode is chosen at the top.
- wifi/pages/wifi.general - work in progress right now to implement wifi support
- router/pages/status.dsl - dsl info page (although you are unlikely to have that ubus call since I have added it to our local branch)
- core/pages/overview - a work in progress front page
- app/init - init script that loads all resources first time application is loaded.

Note that if you run local server, you may not be able to access some pages unless you also have dummy json rpc calls implemented locally. Also there will be numerous rpc calls missing unless you use the same hardware that I'm using. Local server currently works best by simply forwarding ubus calls to an actual hardware (so you avoid having to copy packages to the router - but it does not actually do much apart from handing autologin and providing the application with a full menu). I will look into a possibility of making the gui automatically detect available rpc calls and gracefully regress to a more limited gui if some calls are missing..

You can easily add new pages by doing the following:
- add your page either to existing plugin or create a new plugin. Create an html file and a js file. Same name, different extension.
- add a reference to the page to plugin.json in the plugin directory.
- add your plugin to main config (js/config.js) if it is not already there
- add a menu entry for your new page into the access control enabled menu config in share/menu.d

if you have questions, feel free to post them on github project page.

Would you do support for openvpn as in the gargoyle?

badziewiak wrote:

Would you do support for openvpn as in the gargoyle?

Not planned at the moment. Eventually maybe. If the client decides they want to ship it with their routers, it will definitely go higher up on the priority list.

There are several steps to implement support for new configuration:

First you need to decide on how you are going to organise your settings. All config style settings will then go into UCI configs which the gui can easily access and modify using ubus calls. When user changes stuff in the gui, the easiest way to apply the settings is to store it back to uci and then to have a script that runs in the background on the router apply them to running services like openvpn. So that's how you would implement it if you decide to do it yourself.

The gui is at the moment like 3 weeks old. So as you may imagine it is not very complete yet. But the good news is that it is very easy to work with and you can easily add new pages that modify settings in the uci model. Also in the latest develop branch I have been working on a new way to access uci settings that eliminate all need to write glue code almost to the level of requiring only two calls to load and apply settings. So in the future it will be even simpler to work with settings pages and add new ones to the interface.

The angular library that is executed in the web browser is about 125kb - a file that must be stored on and served from the router. For devices with 4MB Flash this might be a real challenge... and with 8MB of flash it might not be the right priority. It is of course possible to use a public link to Angular instead of serving from the router, but then the OpenWrt GUI won't work without an internet connection.

Perhaps
- it would be possible to generate a subset of Angular to get a smaller library
- it could replace other components (in Luci) that also take up storage space

@zo0ok, jquery library used in luci2 is 264kb. Your point being?

But if space is an issue I have some good news for you: you don't even have to store the app on the device. Just write ubus plugins in C and store them on the device. Then run your app locally on PC or have a small index.html file on the device that loads everything from elsewhere on the internet. And you eliminate the space problem completely.

In the repo there is a server.js file. You can run it using "node server.js" and it will run a local server that supports logging in remotely to a device over rpc. So you can use it to test things. Be sure though to run "cd luci-express; npm install" first so that you get all the nodejs plugins installed before you run the local server...

LuCI2 contains a full copy of jquery for debugging purposes atm. The minified version would be around 90K and down to 30K after LZMA.

mkschreder wrote:

@zo0ok, jquery library used in luci2 is 264kb. Your point being?

But if space is an issue I have some good news for you: you don't even have to store the app on the device.

Don't get me wrong, I like Angular and I use it myself.
I have hesitated to use it for my fwreject, just for space reasons (currently there is no javascript at all there):
https://forum.openwrt.org/viewtopic.php?id=53468

And I have used it for my table of hardware:
https://dl.dropboxusercontent.com/u/906 … index.html

If we can throw something out (jquery) and put something better in (Angular) no one is happier than me.
And, we hardly need all Angular features for openwrt, and perhaps it would be possible to use a reduced version (although, I have never seen any such thing).

But this IS OpenWrt, space IS an issue.

And I think the MOST IMPORTANT requirement of any router WebGUI is that it runs 100% off the router, with no need to install anything on the client computer (which might as well be an iPad), and not requiring internet connection.

(Last edited by zo0ok on 3 May 2015, 18:51)

I have not tried: http://angularlight.org
... I don't know if it is any good and if it has any future...

...but it could be that it mostly does the good stuff with Angular that would be great for building OpenWrt interfaces, and that it does not include lots of heavy stuff found in AngularJS.

I tried gzipping angular.min.js and the result is less than 50k. Not bad (especially if it could replace jquery).

Very cool!
I will check this out tomorrow after my last exam.
Will all the luci-app-* packages also need to be redone?

deese.john wrote:

Very cool!
I will check this out tomorrow after my last exam.
Will all the luci-app-* packages also need to be redone?

Eventually new plugins will need to be created for juci to support what luci does. This is because juci (luciexpress or lua-uci in javascript instead of lua) does not run on the gateway but instead runs in the client browser. This allows us to have really compact and small backend that just parses and responds to json messages and all the heavy gui creation can be moved to the client. But this also means that we would need to rethink current code that is available in luci because that code is written in lua and runs directly on the device instead.

The upside is that it is about 70% less code with angular than it is with luci. :-)

Not all routers have an ADSL, so consider moving things related to ADSL as a separate module/plugin.

mkschreder wrote:

The upside is that it is about 70% less code with angular than it is with luci. :-)

Thats no big achievement if there's only a view demo views wink

LuCI2 is already approaching the size of LuCI and no, thats not due to excessive jQuery code, its merely the size of the features + assets.

Features simply take space, no way around that.

I have realized that occasionally I forget to update the project repo for several weeks ^^ I have pushed most recent changes to luciexpress repo now. Lots and lots of changes since last commit.. smile

http://s24.postimg.org/j0cphnujo/openwrt_inteno.jpg

Btw, for a more complete repo with all the dependencies, you can checkout my BB-martin branch which is part of openwrt Inteno branch of BB available here: https://github.com/mkschreder/iopsys-op … nteno.git. I push most of my latest stuff both to the inteno sdk repo and to github.

So, to build luciexpress package for Inteno dg301 router, you would generally do this:
git clone https://github.com/mkschreder/iopsys-openwrt-inteno.git
cd iopsys-openwrt-inteno
git checkout BB-martin
./genconfig -o dg301
make # (make will fail when it gets to proprietry kernel stuff because this repo does not have broadcom stuff included)
make package/inteno/luciexpress/compile

(Last edited by mkschreder on 12 May 2015, 22:10)

sure want and can contribute (limited time available).
There are also other packages i want to release to the public domain written as NodeJS server components to run on the router

in our labs we ar using Linksys WRT54L and a big hurdle is still installing nodeJS, so all info about easy way to do that will help

zo0ok wrote:

And I think the MOST IMPORTANT requirement of any router WebGUI is that it runs 100% off the router, with no need to install anything on the client computer (which might as well be an iPad), and not requiring internet connection.

Please share your reasoning in more detail.

jow wrote:

LuCI2 is already approaching the size of LuCI and no, thats not due to excessive jQuery code, its merely the size of the features + assets.

Features simply take space, no way around that.

So the solution is to increase the level of modularization and implement a kind of Image Builder in Javascript so clicking save & apply could trigger a full reflash. No need to waste space storing dead and unreachable code or extra layers of fancy parsers to compute a few lines of static initialization code.

bkil wrote:
zo0ok wrote:

And I think the MOST IMPORTANT requirement of any router WebGUI is that it runs 100% off the router, with no need to install anything on the client computer (which might as well be an iPad), and not requiring internet connection.

Please share your reasoning in more detail.

I think he was referring to the possibility of not even loading the gui from the router (which is not a good idea in final product indeed, but is a possibility and works great for testing new code). Right now there are basically two ways to run the gui - either install all the files to router's www root and load them by going to the router ip in web browser, or load up the local server written with nodejs and go to localhost and then instruct it to connect to router's ubus over http endpoint (router obviously needs to have uhttpd-mod-ubus and all the dependencies installed).

Worth noting though that the gui does not use nodejs at all when it runs completely off the router. Nodejs is only for local testing on pc. BUT, also worth noting, is that if anybody feels like implementing rpc functions in node then it is very easy to do (because json is native to javascript). It is however also a lot more resource-demanding than implementing rpc functions as rpcd plugins in C (the way it is currently done).

mkschreder wrote:
bkil wrote:
zo0ok wrote:

And I think the MOST IMPORTANT requirement of any router WebGUI is that it runs 100% off the router, with no need to install anything on the client computer (which might as well be an iPad), and not requiring internet connection.

Please share your reasoning in more detail.

I think he was referring to the possibility of not even loading the gui from the router (which is not a good idea in final product indeed, but is a possibility and works great for testing new code). Right now there are basically two ways to run the gui - either install all the files to router's www root and load them by going to the router ip in web browser, or load up the local server written with nodejs and go to localhost and then instruct it to connect to router's ubus over http endpoint (router obviously needs to have uhttpd-mod-ubus and all the dependencies installed).

Worth noting though that the gui does not use nodejs at all when it runs completely off the router. Nodejs is only for local testing on pc. BUT, also worth noting, is that if anybody feels like implementing rpc functions in node then it is very easy to do (because json is native to javascript). It is however also a lot more resource-demanding than implementing rpc functions as rpcd plugins in C (the way it is currently done).

Yes, that is correctly understood and I don't have much more to add to it.
I agree that "it" can be ok for development, but not for production. At least in theory. If it is a truly good idea for OpenWrt I don't know.

Edit: this reminds me about Visual Studio developers who spend most of their time with their development environment and think things work but then when deployed to a real environment subtle bugs show up (that did not occur or can be reproduced in Visual Stuidio).

(Last edited by zo0ok on 15 May 2015, 08:01)