openLuup : Kiosk (Touchscreen) Idea ?
-
Hi,
I have an old raspberry pi and 7" touchscreen gathering dust, and have started to explore how I could potentially use the openLuup feature to ‘specify my own’ index.html?
The openLuup manual suggests it’s straightforward to set up, the challenge is going to be around how best to create a single html for just one of my plugins so i can use it in a kiosk type mode..
As you can probably tell, html and web development are alien to me
- but I assume I can do something basic, like create buttons that just call
luup.call_action
- e.g. here’s one from a plugin I created.Luup
luup.call_action("urn:nodecentral-net:serviceId:Matrix1","SYCall",{ action ="I3" },1083)
Html
<form action="https://google.com"> <input type="submit" value="Go to Google" /> </form>
Not sure how that luup.call_action translate to a url, but I guess it’s something like this..
http://ip_address:3480/data_request?id=action&output_format=xml&DeviceNum=1083&serviceId=urn:nodecentral-net:serviceId:SYMatrix1&SYCall={action=I3}
Has anyone done anything like this already, and has any examples of their own html content they can share ?
Is there maybe something out there that can translates any Vera static .json file into something presentable on a .html page. ? I had a quick look through @amg0 AltUi content on GitHub for inspiration but that is a way more comprehensive interface, compared to the single screen look I’m going for..
Any suggestion/advice (examples ideally) would be much appreciated..
I'm doing something like that, but my dashboard is based on C#. It's effectively running inside a Fire Tablet with Fully Kiosk and it's a web app. I've posted screenshots before, but here we go again:
(sorry, it's in Italian, but you'll get the point thanks to the icons - if you see lower temperature don't worry, we're fine, it's just the wife changing air - a typical Italian habit :D).
It's effectively calling Vera's endpoint, beside a couple of things calling my own stuff (via HTTP calls).
I had to re-create every widget I wanted to support, and it's pretty tied to my needs, but it's working good for us. Wife is happy and it's not easy. I'll probably add a new scene for the morning, to show a different view with weather and appointments later this year. Everything is updated in real-time via WebSockets. Fully Kioks has the ability to trigger external apps, so I'm launching the cams when a motion is detected. Screen is always on, but it's managed to dim to 0 automatically and turn on based on motion and/or an event (like doorbel, motion detected, doors opened, etc).
If you want something ready to use, MSR has a dashboard capability you could try.
-
Yes, I've used openLuup in this way, although nowadays my go-to dashboard is Grafana (which can have arbitrary HTML links too.)
Your HTTP action call syntax is not quite right – the parameters are not enclosed within braces – see:
-
Thanks all,
I’ve decided to use the Vera Smartphone UI plugin code as my guide - > https://apps.mios.com/plugin.php?id=6 .
This seems to be a reasonably straight forward approach as it’s Lua based and leverages the
luup.register_handler
route .. Although admittedly it’s a little dated, and a trip down memory lane for those old Vera 2 users (before UI5) , but it seems a very viable option for my OpenLuup Kiosk idea.Has anyone worked with this phone UI code before ?
-
After a little bit of tweaking and a whole lot of luck, I’ve managed to repurpose aspects of the Vers Smartphone UI to give me a basic kiosk page for my new HDMI Matrix plugin..
I’m currently running it on my Vera, and have been installing it via the startup Lua, so I can make constant tweaks.
My limited of knowledge in all the parts at play and the coding languages involved, means I’m fumbling around quite a bit with this - but I’m pleased with the progress so far
-
For those that are interest, here’s the code I have at the moment..
Next steps are (1) to try this on openLuup , (2) to see where I can streamline the code, as it there seems more than I probably need and (3) look at linking to content elsewhere rather than mios.com..
sPh_LAYOUT_PFX = 'https://download1.mios.com/L_sPhoneUI_layout' g_is_remote = 0 function string:template(variables) return (self:gsub('{%%(.-)%%}', function (key) return tostring(variables[key] or _G[key] or '') end)) end function flag(v) if( v==nil or tonumber(v)==0 ) then return '0' end return '1' end luup.register_handler("lug_sKioskRequest","sKiosk") luup.register_handler("lug_sPhoneRequest_action_js","sPhone_action_js") -- http://192.168.102.10:3480/data_request?id=lr_sKiosk local html_header = ([[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Vera Mobile</title> <meta http-equiv="pragma" content="nocache"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;"/> <script src="{%sPh_LAYOUT_PFX%}/js/mobile.js" language="javascript"></script> <link rel="stylesheet" href="{%sPh_LAYOUT_PFX%}/css/iui.css" type="text/css" /> </head> <body onLoad="js_prepare_urls();set_layout_prefix('{%sPh_LAYOUT_PFX%}');"> ]]):template ({}) local html_footer=[[ </body> </html>]] function list_devices (lul_room, out, lul_js) local grouphead_inserted = false for k,v in pairs(luup.devices) do if( v.room_num==tonumber(lul_room) and v.hidden==false and v.invisible==false ) then if not grouphead_inserted then table.insert (out,'<li class="group">Devices</li>\n') grouphead_inserted = true; end if v.category_num==0 then table.insert (out, '<li class="bg">' .. lug_sPhoneRequest_switch(k,v.description,lul_js) .. "</li>\n") end end end end function lug_sPhoneRequest_switch(lul_device,lul_description,lul_js) local lul_Status = luup.variable_get("urn:nodecentral-net:serviceId:SYMatrix1","Input",lul_device) local tmpl_params = { device = lul_device, description = lul_description, room = luup.devices[tonumber(lul_device)].room_num, time = os.clock(), status_0 = lul_Status=="1" and '_h' or '', status_25 = lul_Status=="2" and '_h' or '', status_50 = lul_Status=="3" and '_h' or '', status_100 = lul_Status=="4" and '_h' or '', } if( lul_js=='1' ) then return ([[ <img src="{%sPh_LAYOUT_PFX%}/icons/switch.gif" alt="" width="44" height="43" align="absmiddle" class="icon" id="pic_device_{%device%}" />{%description%}<br> <img src="{%sPh_LAYOUT_PFX%}/images/spacer.gif" border="0" width="20" height="20" id="action_icon_{%lul_device%}"> <a href="javascript:void(0);" onClick="set_device_icon({%device%},1);send_command('data_request?id=lr_sPhone_action_js&room={%room%}&device={%device%}&service=urn:nodecentral-net:serviceId:SYMatrix1&action=SYCall&SetInput=I1&time={%time%}',{%device%})"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_0%}.gif" alt="" border="0"/></a> <a href="javascript:void(0);" onClick="set_device_icon({%device%},1);send_command('data_request?id=lr_sPhone_action_js&room={%room%}&device={%device%}&service=urn:nodecentral-net:serviceId:SYMatrix1&action=SYCall&SetInput=I2&time={%time%}',{%device%})"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_25%}.gif" alt="" border="0"/></a> <a href="javascript:void(0);" onClick="set_device_icon({%device%},1);send_command('data_request?id=lr_sPhone_action_js&room={%room%}&device={%device%}&service=urn:nodecentral-net:serviceId:SYMatrix1&action=SYCall&SetInput=I3&time={%time%}',{%device%})"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_50%}.gif" alt="" border="0"/></a> <a href="javascript:void(0);" onClick="set_device_icon({%device%},1);send_command('data_request?id=lr_sPhone_action_js&room={%room%}&device={%device%}&service=urn:nodecentral-net:serviceId:SYMatrix1&action=SYCall&SetInput=I4&time={%time%}',{%device%})"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_100%}.gif" alt="" border="0"/></a> ]]):template (tmpl_params) else return ([[ <img src="{%sPh_LAYOUT_PFX%}/icons/switch.gif" alt="" width="44" height="43" align="absmiddle" class="icon" />{%description%}<br> <a href="data_request?id=lr_sPhone_action&room={%room%}&device={%device%}&service=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&time={%time%}"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_0%}.gif" alt="" border="0"/></a> <a href="data_request?id=lr_sPhone_action&room={%room%}&device={%device%}&service=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&time={%time%}"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_25%}.gif" alt="" border="0"/></a> <a href="data_request?id=lr_sPhone_action&room={%room%}&device={%device%}&service=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&time={%time%}"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_50%}.gif" alt="" border="0"/></a> <a href="data_request?id=lr_sPhone_action&room={%room%}&device={%device%}&service=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&time={%time%}"><img src="{%sPh_LAYOUT_PFX%}/buttons/on{%status_100%}.gif" alt="" border="0"/></a> ]]):template (tmpl_params) end end function lug_sKioskRequest(lul_request,lul_parameters,lul_outputformat) local lul_js = flag(lul_parameters.js) g_is_remote = flag (lul_parameters.r) -- if( lul_js==nil or tonumber(lul_js)==0 ) then -- lul_js = 0 -- end luup.log("lul_js = " .. lul_js) local out = {html_header, [[ <div id="toolbar" class="toolbar"><!--logout_btn--></div> <ul id="searches" title="MyHome" selected="true"> ]]} local time = os.clock() list_devices (0, out, lul_js) table.insert (out, '</ul>') table.insert (out, html_footer) return table.concat (out),"text/html" end function lug_sPhoneRequest_action_js(lul_request,lul_parameters,lul_outputformat) local lul_room = lul_parameters.room local lul_device = lul_parameters.device local lul_action = lul_parameters.action local lul_service = lul_parameters.service if( lul_device==nil or lul_action==nil or lul_service==nil ) then luup.log("lug_sPhoneRequest_action: missing arguments") return 'ERROR: Missing arguments' end local lul_arguments = {} for k,v in pairs(lul_parameters) do if( k~="device" and k~="action" and k~="service" and k~="room" and k~="time" ) then lul_arguments[k]=v end luup.log("lug_sPhoneRequest_action: " .. tostring(k) .. "=" .. v) end for k,v in pairs(lul_arguments ) do luup.log("lug_sPhoneRequest_action: argument " .. tostring(k) .. "=" .. v) end luup.log("luup.call_action(" ..lul_service..","..lul_action..","..lul_arguments..","..tonumber(lul_device)")") local lul_resultcode,lul_resultstring,lul_job,lul_returnarguments = luup.call_action(lul_service,lul_action,lul_arguments,tonumber(lul_device)) luup.log("lug_sPhoneRequest_action: device: " .. tostring(lul_device) .. " action: " .. tostring(lul_action) .. " service: " .. tostring(lul_service) .. " returned: " .. tostring(lul_resultcode) .. " str " ..tostring(lul_resultstring) .. " job " .. tostring(lul_job)) if( lul_resultcode~=0 ) then return 'ERROR: ' .. tostring(lul_resultcode) .. ': ' .. tostring(lul_resultstring) end luup.log("lul_resultcode: " .. lul_resultcode) luup.log("lul_resultstring: " .. lul_resultstring) if( lul_job==0 ) then return 'OK' end return 'Running: ' .. lul_job .. '|' .. lul_device end
-
Hi @akbooer
I’ve just got the Pi set up with openLuup installed and run the script above via the
Misc / Lua code test
option but when I go to the addresshttp://10.10.10.72:3480/data_request?id=lr_sKiosk
it gives me the follow error.No handler for data_request?id=lr_sKiosk
I also tried pasting it into the start up Lua and restarted it, but I got the same message again..
As always, any ideas/suggestions appreciated
-
I haven't looked through the code, but I know that defining a handler works from the openLuup Lua Test page works just fine:
function FOO() return "Hello" end luup.register_handler ("FOO","FOO")
then calling with
openLuupIP:3480/data_request?id=lr_FOO
yields the expected output "Hello". -
Thanks @akbooer , ok, the issue seems to be where I declare the luup.register_handler…
The smartphone UI code has it near the very top, which seems to work fine when it’s run on my Vera, but openLuup doesn’t like it like that.. , However if I move the handle(s) to the very end it works..
-
Thanks, and I seem to have a working (single plugin kiosk) UI now
FYI - I’ve also managed to embed the .js and .css into the luup.handler HTML creation script, thus reducing the external MIOS dependencies. (I still need to explore alternative hosting for button/images etc.)
Now admittedly it’s not the most sophisticated of UI, or the prettiest of Lua scripts, but it’s functional, and it means I have a dedicated UI for my plugin 🥳🥳🥳🥳🥳!
@akbooer - What are your thoughts on making this a ‘feature’ of openLuup? Not sure how, just thinking out-loud ? If it helps, I’ve created my script within a K_xxxxxx.lua file to help identify it, maybe that could be a thing for others to follow too?
-
Glad you have it working to your satisfaction.
I'm not quite sure what you're suggesting as an openLuup feature, but as you've found, all the tools are there and it's not hard. Not sure how much use it might get since there are so many difference options for this sort of thing.
-
P parkerc referenced this topic on