Skip to content

Commit

Permalink
Add HTML configuration page
Browse files Browse the repository at this point in the history
This helps configuring which scenario to select.

Change-Id: I5bf6e2f4e59b424d2075ede49d7fe976ee970941
Signed-off-by: Joakim Roubert <joakimr@axis.com>
  • Loading branch information
joakimr-axis committed Oct 25, 2024
1 parent 9515874 commit 3745822
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ RUN . /opt/axis/acapsdk/environment-setup* && \

# Build ACAP package
WORKDIR "$ACAP_BUILD_DIR"
COPY html/ ./html
ADD https://code.jquery.com/jquery-3.7.1.min.js ./html/js/jquery.min.js
COPY LICENSE \
Makefile \
manifest.json \
Expand Down
92 changes: 92 additions & 0 deletions html/config.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!DOCTYPE HTML>
<html lang="en">

<head>
<style>
* {
font-family: OpenSans, Arial, sans-serif;
}

body {
height: 100%;
background: linear-gradient(135deg, #ffffff 35%, #ffcc33 10%) fixed;
}

h1,
h3 {
color: #9a8b7d;
}

table {
border-collapse: collapse;
width: 50%;
background-color: rgba(114, 205, 244, 0.5);
}

table, th, td {
border: 1px solid rgba(216, 207, 198, 0.5);
}

th, td {
padding: 8px;
}

th {
text-align: left;
background-color: #72cdf4;
}

th.common {
background-color: #8dc63f;
}

td.common {
background-color: rgba(214, 224, 61, 0.5);
}
</style>
<title>Modbus ACAP Configuration</title>
</head>

<body>
<div style="float: left; margin-right: 20px;">
<img alt="" src="/camera/img/logo.png" />
</div>
<h1>Modbus ACAP Configuration</h1>
<table>
<tr>
<th class="common">Application mode</td>
<th class="common">
<select id="modeselection" onchange="modeChange(this.value)">
<option value="0">Server</option>
<option value="1">Client</option>
</select>
</td>
</tr>
<tr>
<td class="common">Modbus TCP/IP port</td>
<td class="common"><input id="port" type="number" min="1024" max="65535" onchange="portChange(this.value)"></td>
</tr>
</table>

<div id="clientcfg">
<h3>Modbus server</h3>
<input id="server" type="input" onchange="serverChange(this.value)"></td>

<h3>AOA Scenarios</h3>
<table id="scenarios">
<tr>
<th>Name</th>
<th>ID no.</th>
<th>Type</th>
</tr>
</table>

<h3>Scenario selected for Modbus output</h3>
<select id="scenarioselection" onchange="scenarioChange(this.value)"></select>
</div>

<script src="js/jquery.min.js"></script>
<script src="js/modbusconfig.js"></script>
</body>

</html>
128 changes: 128 additions & 0 deletions html/js/modbusconfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
var params = {};
var scenarios = {};
const appname = 'Modbusacap';
const parambaseurl = '/axis-cgi/param.cgi?action=';
const paramgeturl = parambaseurl + 'list&group= ' + appname + '.';
const paramseturl = parambaseurl + 'update&' + appname + '.';
const scenariourl = '/local/objectanalytics/control.cgi';
const table = document.getElementById("scenarios");
const port = document.getElementById("port");
const server = document.getElementById("server");
const clientcfg = document.getElementById("clientcfg");
const modeselection = document.getElementById("modeselection");
const scenarioselection = document.getElementById("scenarioselection");
const UpdateInterval = 5;
const SERVER = 0;
const CLIENT = 1;

function portChange(newport) {
setNewValue('Port', newport);
}

function modeChange(newmode, setparam = true) {
if (setparam) {
setNewValue('Mode', newmode);
}
switch (+newmode) {
case SERVER:
clientcfg.style.display = 'none';
break;
case CLIENT:
clientcfg.style.display = 'block';
break;
default:
console.error('Unknown application mode: ' + newmode);
}
}

function serverChange(newserver) {
setNewValue('Server', newserver);
}

function scenarioChange(newscenario) {
setNewValue('Scenario', newscenario);
}

function updateScenarioTable() {
for (let i = table.rows.length - 1; i > 0; i--) {
table.deleteRow(i);
}
for (const scenario of scenarios) {
const row = table.insertRow();
var i = 0;
const nameCell = row.insertCell(i++);
const idCell = row.insertCell(i++);
const typeCell = row.insertCell(i++);

idCell.innerText = scenario.id;
nameCell.innerText = scenario.name;
typeCell.innerText = scenario.type.replace(/([A-Z])/g, ' $1').toLowerCase();
}
}

function updateScenarioSelection() {
while (scenarioselection.options.length > 0) {
scenarioselection.remove(0);
}
for (const scenario of scenarios) {
scenarioselection.add(new Option(`${scenario.name} (ID: ${scenario.id})`, scenario.id));
}
scenarioselection.value = +(params['Scenario']);
}

async function getScenarios() {
try {
const scenarioData = await $.post({
url: scenariourl,
headers: {
'Content-Type': 'application/json'
},
data: '{"apiVersion": "1.2", "method": "getConfiguration"}'
});
scenarios = scenarioData.data.scenarios;
for (i in scenarioData.data.scenarios) {
console.log('scenario id: ' + scenarios[i].id + ', scenario name: ' + scenarios[i].name + ', type: ' + scenarios[i].type);
}
updateScenarioTable();
} catch (error) {
alert('Failed to get scenario info from AOA');
console.error('Failed to get scenario info from AOA: ', error)
}
}

async function getCurrentValue(param) {
try {
const paramData = await $.get(paramgeturl + param);
params[param] = paramData.split('=')[1];
console.log('Got ' + param + ' value ' + params[param]);
} catch (error) {
alert('Failed to get parameter ' + param);
}
}

async function setNewValue(param, value) {
try {
await $.get(paramseturl + param + '=' + value);
params[param] = value;
console.log('Set ' + param + ' value to ' + value);
} catch (error) {
alert('Failed to set parameter ' + param);
}
}

async function updateValues() {
await getCurrentValue('Mode');
await getCurrentValue('Port');
await getCurrentValue('Scenario');
await getCurrentValue('Server');
await getScenarios();
modeChange(+(params['Mode']), false);
modeselection.value = +(params['Mode']);
port.value = +(params['Port']);
updateScenarioSelection();
server.value = params['Server'];
console.log('Will call again in ' + UpdateInterval + ' seconds to make sure we are in sync with device');
setTimeout(updateValues, 1000 * UpdateInterval);
}

updateValues();
3 changes: 2 additions & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
"vendor": "Axis Communications AB",
"embeddedSdkVersion": "3.0",
"runMode": "respawn",
"version": "1.2.0"
"version": "1.2.1"
},
"configuration": {
"settingPage": "config.html",
"paramConfig": [
{"name": "Mode", "type": "enum:0|Server, 1|Client", "default": "0"},
{"name": "Port", "type": "int:min=1024,max=65535", "default": "5020"},
Expand Down

0 comments on commit 3745822

Please sign in to comment.