If you create a project in Brightauthor you can access the variables on port 8008, this is very useful for htmlwidget where the html page can read / write the variable via the 8008 port. and JS script
The thing with Brightauthor is that you always have to use brightauthor to update / adjust scripts due to the md5 file naming and publishing technic.
Often it far more universal to just run a custom autorun.brs with the need logic to check GPIO and to play some simple videofiles which can be changed just be replacing them straight on the SD card with the a new file with the same name (much easier for non technical people)... so far so good.
When it get a bit more advanced like html widget you will need the have the variables exchanged via eg port 8008.
So I try to use the official index.html for set / get variable
I place the index.html in the root on the sd card toget with my test.brs file
//------------------------- index.html--------
<!DOCTYPE html>
<html>
<head>
<script>
var currentUserVarIndex = 0;
window.onload = function() {
getUserVars(doUserVars);
}
;
function getUserVars(callback) {
console.log('getUserVars');
sUrl = '/GetUserVars';
var varlist = new Array();
fetch(sUrl).then( (response) => response.text()).then( (str) => new window.DOMParser().parseFromString(str, 'text/xml')).then( (data) => {
const nodes = data.getElementsByTagName('BrightSignVar');
for (let i = 0; i < nodes.length; i++) {
const name = nodes[i].getAttribute('name');
const val = nodes[i]?.childNodes[0]?.nodeValue ?? '';
uv = new userVar(name,val);
printObj(uv);
varlist.push(uv);
}
callback(varlist);
}
);
}
function userVar(key, value) {
this.key = key;
this.value = value;
}
function doUserVars(us) {
printObj(us);
if (typeof us === 'undefined') {
console.log('userVars not defined');
setTimeout(function() {
getUserVars(doUserVars);
}, 1000);
return;
}
// create the form
const form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/SetValues');
// iterate through key/value pair and create inputs with labels
for (let t = 0; t < us.length; t++) {
const keyTest = us[t].key;
const valueTest = us[t].value;
form.appendChild(document.createElement('br'));
const lbl = document.createElement('LABEL');
lbl.textContent = keyTest;
const inp = document.createElement('input');
inp.setAttribute('class', 'bs_input');
inp.setAttribute('type', 'text');
inp.setAttribute('name', keyTest);
inp.setAttribute('value', valueTest);
form.appendChild(lbl);
form.appendChild(document.createElement('br'));
form.appendChild(inp);
}
form.appendChild(document.createElement('br'));
form.appendChild(document.createElement('br'));
// create and add submit button for the form
const sbm = document.createElement('input');
sbm.setAttribute('id', 'button');
sbm.setAttribute('type', 'submit');
sbm.setAttribute('value', 'Set Values');
form.appendChild(sbm);
const varForm = document.querySelector('div.varform');
varForm.appendChild(form);
}
function printObj(obj) {
console.log(JSON.stringify(obj));
}
</script>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,user-scalable=no"/>
<title>User Variables</title>
<style>
body {
background-color: rgba(184, 177, 218, 1);
background-size: auto;
font-family: Verdana, Geneva, sans-serif;
}
.bs_input {
width: 90%;
font: Verdana, Geneva, sans-serif;
font-size: 16px;
font-family: Verdana, Geneva, sans-serif;
color: rgba(0, 0, 0, 1);
}
.bs_uservariable {
font: Verdana, Geneva, sans-serif;
font-size: 16px;
}
#header {
font: Verdana, Geneva, sans-serif;
font-size: 36px;
text-align: center;
text-color: rgba(255, 255, 255, 1);
font-family: Verdana, Geneva, sans-serif;
padding-bottom: 2%;
}
#button {
font: Verdana, Geneva, sans-serif;
font-size: 16px;
font-family: Verdana, Geneva, sans-serif;
color: rgba(0, 0, 0, 1);
}
</style>
</head>
<body>
<div id="header">User Variables</div>
<center>
<div class="varform"></div>
<div id="logo"></div>
</center>
</body>
</html>
//------------------------- index.html end--------
//---------------test.brs ------------------------
' Initialize user variables
m.userVars = CreateObject("roAssociativeArray")
m.userVars["Brightness"] = "75"
m.userVars["Volume"] = "50"
m.userVars["ScreenMode"] = "Normal"
m.userVars["PlayState"] = "Stopped"
m.userVars["CustomMessage"] = "Hello, BrightSign!"
' Instantiate the HTTP server
server = createObject("roHttpServer", { port: 8008 })
' Handler/Callback for the GetUserVars request
httpGetUserVarsCallback = function (event)
m.userVars = CreateObject("roAssociativeArray")
m.userVars["Brightness"] = "75"
m.userVars["Volume"] = "50"
m.userVars["ScreenMode"] = "Normal"
m.userVars["PlayState"] = "Stopped"
m.userVars["CustomMessage"] = "Hello, BrightSign!"
' Create XML root element
root = CreateObject("roXMLElement")
root.SetName("BrightSignUserVariables")
' Debugging: Check if userVars is being populated correctly
print "User Variables: "; m.userVars
' Loop through the userVars and add them to the XML
for each key in m.userVars
varElement = CreateObject("roXMLElement")
varElement.SetName("BrightSignVar")
varElement.AddAttribute("name", key)
varElement.AppendChildText(m.userVars[key])
' Debugging: Check if each element is added to the XML correctly
print "Adding Variable: "; key; " = "; m.userVars[key]
root.AppendChild(varElement)
end for
' Generate XML string
xml = root.GenXML({ indent: " ", newline: chr(10), header: true })
' Debugging: Print the final XML response to check if it is correctly generated
print "Generated XML: "; xml
' Send the response as XML
event.AddResponseHeader("Content-type", "text/xml; charset=utf-8")
event.SetResponseBodyString(xml)
event.SendResponse(200)
end function
' Configure the server to handle /GetUserVars requests
serverConfig = {
url_path: "/GetUserVars"
content_type: "application/xml; charset=utf-8"
user_data: { fnCallback: httpGetUserVarsCallback }
}
' Add the handler to the server for the /GetUserVars path
server.AddGetFromEvent( serverConfig )
' Wait for incoming HTTP events
msgPort = createObject("roMessagePort")
server.setPort(msgPort)
print "Waiting for event..."
' Event loop to handle incoming requests
while true
event = msgPort.WaitMessage(0)
print "Event type: "; type(event), event.GetMethod()
' Ensure the event is an HTTP event before processing
if type(event) = "roHttpEvent" then
userData = event.getUserData()
' Ensure the callback is valid
if type(userData) = invalid or type(userData.fnCallback) <> "roFunction" then
' Skip this iteration and wait for the next event
msgPort.WaitMessage(0)
else
' Call the callback function
userData.fnCallback(event)
end if
end if
end while
//---------------test.brs end------------------------
then I run the script via telnet and expected to get the viables by the
http://192.168.1.188:8008/GetUserVars
and the respond are:
{"Brightness":"75","CustomMessage":"Hello, BrightSign!","PlayState":"Stopped","ScreenMode":"Normal","Volume":"50"}
This is a JSON format
If I try http://192.168.1.188:8008/ I get the purple BrightSign page but no variables
And in the index code it look for XML format, I have tried many test without any luck and I hope someone in her can show a a simple brs script supporting the XML Get / Set of user variables.
I did see this page and it was a good inspiration https://blog.brightscripters.com/rohttpserver-example
Please advise how to do this or maybe there are some samplecode around?
Thank you