Luci: Visualizing JSON Data

Hi,
is there a easy way to visualize JSON Data in LuCI?
The data I want to display is like

SSID:
{
BSSID:
{
Client Mac:
{
}
}
}

What do you mean with "visualizing"? Pretty printing?

I would like to have something like this Associated Stations.
But I don't understand the code. :confused:

Ok. The code calls wifi_assoclist function.
And this uses json too. Maybe I can somehow modify this...
And the code uses the wifi_assoclist from tools.

The question is whether you want to render the resulting HTML on the server side or on the client side. Depending on that, you have to use different approaches.

function index()
   entry({"admin", "bla", "view_hearing_map"}, call("get_hearing_map"), "View
end

function get_hearing_map()
    local utl = require "luci.util"
    local http = require "luci.http"
    local stat = utl.ubus("bla", "get_hearing_map", { })
    luci.http.prepare_content("application/json")
    luci.http.write_json(stat)
end

This looks like this because my firefox renders this.
hearing_map_json

I want more integrated stuff...

If I try

m = Map("wireless", translate("Wireless Overview"))                                                                                                                                             
m:chain("network")                                                                                                                                                                              
m.pageaction = false                                                                                                                                                                            
                                                                                                                                                                                            
s = m:section(NamedSection, "__assoclist__")                                                                                                                                                    
                                                                                                                                                                                            
function s.render(self, sid)                                                                                                                                                                    
        local tpl = require "luci.template"                                                                                                                                                     
        tpl.render_string([[                                                                                                                                                                    
                <h2><%:Hearing Map%></h2>                                                                                                                                                       
                <%                                                                                                                                                                              
                local utl = require "luci.util"                                                                                                                                                 
                local http = require "luci.http"                                                                                                                                                
                local stat = utl.ubus("bla", "get_hearing_map", { })                                                                                                                           
                luci.http.prepare_content("application/json")                                                                                                                                   
                luci.http.write_json(stat)                                                                                                                                                      
                %>                                                                                                                                                                              
                ]])                                                                                                                                                                             
     end     

I get an output like this (using cbi)
hearing_map_cbi

Why should the server render a html? xD
Sorry I'm not that into javascript and html and php and so on...

What is the best solution? :slight_smile:

Well you need to somehow turn the JSON data into a series of HTML elements. A table, or list or whatever.
This can either be done in the browser, where some JavaScript is fetching the JSON data from the server using XMLHTTPRequest and turning it into HTML with something like doucment.getElementByID('blah').innerHTML = '... assembled html data made from json ...'; or you print the HTML on the server side right away (like you do with tpl.render_string()). But then you cannot simply push out the JSON as is but you'll need to iterate it and build the appropriate structure.

1 Like

Example:

function s.render(self, sid)
	local tpl = require "luci.template"
	tpl.render_string([[
		<h2><%:Hearing Map%></h2>
		<ul>
			<%
				local utl = require "luci.util"
				local stat = utl.ubus("bla", "get_hearing_map", { })
				local name, macs
				for name, macs in pairs(stat) do
					local mac, data
					for mac, data in pairs(macs) do
						local mac2, data2
						for mac2, data2 in pairs(data) do
			%>
				<li>
					<strong>Name is: </strong><%= name %><br />
					<strong>MAC is: </strong><%= mac2 %> (or maybe <%= mac %>?)<br />
					<strong>Frequency is: </strong><%= "%.3f" %( data2.freq / 1024 ) %>GHz<br />
					<strong>VHT support is: </strong><%= (data2.vht == 1) and "available" or "not available" %><br />
					...
				</li>
			<%
						end
					end
				end
			%>
		</ul>
	]])
end

Couldn't really make sense of you JSON structure as it is not possible to infer what these nested MACs/BSSIDs are supposed to mean, but a construct like above should allow you to access the inner data.

Start with bringing your data into a structured manner, see that you manage to access and print all items you intend to display. Then you can take a look at the HTML markup of other LuCI parts like the associated station table and attempt to replicate that by reusing structure, CSS classes etc.

Thanks a lot for your example!!! :slight_smile:
This is a very good start for me.

luci_hearing_map

I will do this! :slight_smile:

I just noticed the vht field is a bool in your JSON, so instead of:

it needs to be (data2.vht == true)

I edited some stuff and this is what I wanted. :slight_smile:
Will be soon some luci-app ^^

nearlyfinished

1 Like

Result can be found here. :slight_smile:

@jow: There was a mistake :stuck_out_tongue: