feature-webapp #3
@@ -37,3 +37,52 @@
|
||||
--bs-btn-disabled-border-color: #0d6efd;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1.5rem!important;
|
||||
margin-bottom: 1.5rem!important;
|
||||
}
|
||||
|
||||
.mt-0 {
|
||||
margin-top: 0!important;
|
||||
}
|
||||
|
||||
.me-2 {
|
||||
margin-right: .5rem!important;
|
||||
}
|
||||
|
||||
.mb-2 {
|
||||
margin-bottom: .5rem!important;
|
||||
}
|
||||
|
||||
.mb-3 {
|
||||
margin-bottom: 1rem!important;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1.5rem!important;
|
||||
}
|
||||
|
||||
.mb-5 {
|
||||
margin-bottom: 3rem!important;
|
||||
}
|
||||
|
||||
.mb-7 {
|
||||
margin-bottom: 6rem !important;
|
||||
}
|
||||
|
||||
.mb-auto {
|
||||
margin-bottom: auto!important;
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.me-md-auto {
|
||||
margin-right: auto!important;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width:768px) {
|
||||
.mb-md-0 {
|
||||
margin-bottom: 0!important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ body {
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
border-radius: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: rgba(136, 165, 191, 0.48) 6px 2px 16px 0px, rgba(255, 255, 255, 0.8) -6px -2px 16px 0px;
|
||||
--bs-btn-hover-bg: #5780f2;
|
||||
background-color: #5278e1;
|
||||
@@ -277,3 +277,44 @@ table {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.p-login {
|
||||
text-align: left;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0;
|
||||
color: #3E4C66;
|
||||
}
|
||||
|
||||
.h-login {
|
||||
font-weight: 600;
|
||||
color: #2E3A59;
|
||||
}
|
||||
|
||||
#file-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-setting {
|
||||
border-radius: 8px;
|
||||
border: white solid 3px;
|
||||
}
|
||||
|
||||
#drop-area {
|
||||
border: 2px dashed #ccc;
|
||||
border-radius: 20px;
|
||||
width: 400px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-family: sans-serif;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s, border-color 0.2s;
|
||||
}
|
||||
|
||||
#drop-area.highlight {
|
||||
background: #f0f8ff;
|
||||
border-color: #0d6efd;
|
||||
color: #0d6efd;
|
||||
}
|
||||
|
||||
|
||||
31
html/webpage/assets/js/dragdrop.js
vendored
Normal file
31
html/webpage/assets/js/dragdrop.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
const dropArea = document.getElementById("drop-area");
|
||||
const fileInput = document.getElementById("file-input");
|
||||
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
dropArea.addEventListener(eventName, e => e.preventDefault());
|
||||
dropArea.addEventListener(eventName, e => e.stopPropagation());
|
||||
});
|
||||
|
||||
['dragenter', 'dragover'].forEach(eventName => {
|
||||
dropArea.addEventListener(eventName, () => dropArea.classList.add('highlight'));
|
||||
});
|
||||
|
||||
['dragleave', 'drop'].forEach(eventName => {
|
||||
dropArea.addEventListener(eventName, () => dropArea.classList.remove('highlight'));
|
||||
});
|
||||
|
||||
|
||||
dropArea.addEventListener('click', () => fileInput.click());
|
||||
|
||||
dropArea.addEventListener('drop', e => {
|
||||
const files = e.dataTransfer.files;
|
||||
handleFiles(files);
|
||||
});
|
||||
|
||||
fileInput.addEventListener('change', e => {
|
||||
handleFiles(e.target.files);
|
||||
});
|
||||
|
||||
function handleFiles(files) {
|
||||
console.log("file dropped");
|
||||
}
|
||||
@@ -101,28 +101,30 @@ $(document).ready(function () {
|
||||
let $schedulehour = $schedulemodal.find('#schedulehour');
|
||||
// number input 0-59
|
||||
let $scheduleminute = $schedulemodal.find('#scheduleminute');
|
||||
// text input
|
||||
let $schedulesoundpath = $schedulemodal.find('#schedulesoundpath');
|
||||
// select2 for message
|
||||
let $schedulemessage = $schedulemodal.find('#schedulemessage');
|
||||
$schedulemessage.select2({});
|
||||
// number input 0-5
|
||||
let $schedulerepeat = $schedulemodal.find('#schedulerepeat');
|
||||
// checkbox
|
||||
let $scheduleenable = $schedulemodal.find('#scheduleenable');
|
||||
// div for list of checkboxes
|
||||
// select2 for broadcastzones
|
||||
let $schedulezones = $schedulemodal.find('#schedulezones');
|
||||
$schedulezones.select2({});
|
||||
// radio button for everyday
|
||||
let $scheduleeveryday = $schedulemodal.find('#scheduleeveryday');
|
||||
// radio button for weekdays
|
||||
let $schedulesunday = $schedulemodal.find('#schedulesunday');
|
||||
let $schedulemonday = $schedulemodal.find('#schedulemonday');
|
||||
let $scheduletuesday = $schedulemodal.find('#scheduletuesday');
|
||||
let $schedulewednesday = $schedulemodal.find('#schedulewednesday');
|
||||
let $schedulethursday = $schedulemodal.find('#schedulethursday');
|
||||
let $schedulefriday = $schedulemodal.find('#schedulefriday');
|
||||
let $schedulesaturday = $schedulemodal.find('#schedulesaturday');
|
||||
// radio button for weekly
|
||||
let $scheduleweekly = $schedulemodal.find('#scheduleweekly');
|
||||
// select2 for weekly selection
|
||||
let $weeklyselect = $schedulemodal.find('#weeklyselect');
|
||||
$weeklyselect.select2({});
|
||||
// radio button for specific date
|
||||
let $schedulespecialdate = $schedulemodal.find('#schedulespecialdate');
|
||||
// date input
|
||||
let $scheduledate = $schedulemodal.find('#scheduledate');
|
||||
// select2 for language
|
||||
let $languageselect = $schedulemodal.find('#languageselect');
|
||||
$languageselect.select2({});
|
||||
|
||||
$schedulespecialdate.on('change', function () {
|
||||
if ($(this).is(':checked')) {
|
||||
@@ -137,17 +139,10 @@ $(document).ready(function () {
|
||||
$scheduledescription.val('');
|
||||
$schedulehour.val('0');
|
||||
$scheduleminute.val('0');
|
||||
$schedulesoundpath.val('');
|
||||
$schedulerepeat.val('0');
|
||||
$scheduleenable.prop('checked', true);
|
||||
$scheduleeveryday.prop('checked', false);
|
||||
$schedulesunday.prop('checked', false);
|
||||
$schedulemonday.prop('checked', false);
|
||||
$scheduletuesday.prop('checked', false);
|
||||
$schedulewednesday.prop('checked', false);
|
||||
$schedulethursday.prop('checked', false);
|
||||
$schedulefriday.prop('checked', false);
|
||||
$schedulesaturday.prop('checked', false);
|
||||
|
||||
$schedulespecialdate.prop('checked', false);
|
||||
$scheduledate.prop('disabled', true).val('');
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -195,9 +195,9 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-3">Description</th>
|
||||
<th class="col">IP Address</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class75">Description</th>
|
||||
<th class="class20">IP Address</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="soundchanneltablebody"></tbody>
|
||||
@@ -236,11 +236,11 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-2">Description</th>
|
||||
<th class="col-sm-2">SoundChannel</th>
|
||||
<th class="col-sm-2">ID</th>
|
||||
<th class="col">BP</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class40">Description</th>
|
||||
<th class="class20">SoundChannel</th>
|
||||
<th class="class05">ID</th>
|
||||
<th class="class30">BP</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="broadcastzonetablebody"></tbody>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -42,9 +42,9 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-2">TAG</th>
|
||||
<th class="col">Languages</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class20">TAG</th>
|
||||
<th class="class75">Languages</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="languagebanktablebody"></tbody>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -39,11 +39,11 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-1 col-md-1">No</th>
|
||||
<th class="col-2 col-md-2 col-lg-2">Date</th>
|
||||
<th class="col-2 col-md-2 col-lg-2">Time</th>
|
||||
<th class="col-2 col-md-2 col-lg-2">Machine</th>
|
||||
<th>Description</th>
|
||||
<th class="class10">No</th>
|
||||
<th class="class15">Date</th>
|
||||
<th class="class15">Time</th>
|
||||
<th class="class15">Machine</th>
|
||||
<th class="class45">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="logtablebody"></tbody>
|
||||
|
||||
@@ -14,22 +14,21 @@
|
||||
<body>
|
||||
<section class="position-relative py-4 py-xl-5">
|
||||
<div class="container">
|
||||
<div class="row mb-5">
|
||||
<div class="col-md-8 col-xl-6 text-center mx-auto">
|
||||
<h2>Sign In</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="row mb-4"></div>
|
||||
<div class="row d-flex justify-content-center mb-7">
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<div class="card mb-5 card-login">
|
||||
<div class="card-body d-flex flex-column align-items-center">
|
||||
<div class="bs-icon-xl bs-icon-circle bs-icon-primary my-4 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-person bg-icon-login">
|
||||
<div class="bs-icon-xl bs-icon-circle bs-icon-primary my-4 bs-icon bg-icon-login"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-person bg-icon-login">
|
||||
<path d="M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664z"></path>
|
||||
</svg></div>
|
||||
<form class="text-center" method="post">
|
||||
<div class="mb-3"><input class="form-control input-login" type="text" name="username" placeholder="Username"></div>
|
||||
<div class="mb-3"><input class="form-control input-login" type="password" name="password" placeholder="Password"></div>
|
||||
<div class="mb-3"><button class="btn btn-primary d-block w-100 btn-login" type="submit">Sign In</button></div>
|
||||
<h2 class="mb-3 h-login">Login</h2>
|
||||
<form class="text-center py-2 bottom-signin" method="post">
|
||||
<p class="p-login">Username</p>
|
||||
<div class="mb-3"><input class="form-control input-login" type="text" name="username" placeholder="Enter your username"></div>
|
||||
<p class="p-login">Password</p>
|
||||
<div class="mb-3"><input class="form-control input-login" type="password" name="password" placeholder="Enter your password"></div>
|
||||
<div class="mb-3 py-2"><button class="btn btn-primary d-block w-100 btn-login" type="submit">Login</button></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -42,13 +42,13 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-2">Description</th>
|
||||
<th class="col-sm-1">Language</th>
|
||||
<th class="col-sm-1">ANN ID</th>
|
||||
<th class="col-sm-1">Type</th>
|
||||
<th class="col-sm-3">Message Details</th>
|
||||
<th class="col-sm-3">Message Tags</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class15">Description</th>
|
||||
<th class="class10">Language</th>
|
||||
<th class="class10">ANN ID</th>
|
||||
<th class="class10">Type</th>
|
||||
<th class="class35">Message Details</th>
|
||||
<th class="class15">Message Tags</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="messagebanktablebody"></tbody>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -19,8 +19,8 @@
|
||||
</div>
|
||||
<div class="accordion" role="tablist" id="accordion-1">
|
||||
<div class="accordion-item pad-accordion">
|
||||
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed bg-heading1" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-1" aria-expanded="false" aria-controls="accordion-1 .item-1">Channel Status</button></h2>
|
||||
<div class="accordion-collapse collapse item-1 bg-accordion" role="tabpanel" data-bs-parent="#accordion-1">
|
||||
<h2 class="accordion-header" role="tab"><button class="accordion-button bg-heading1" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-1" aria-expanded="true" aria-controls="accordion-1 .item-1">Channel Status</button></h2>
|
||||
<div class="accordion-collapse collapse show item-1 bg-accordion" role="tabpanel" data-bs-parent="#accordion-1">
|
||||
<div class="accordion-body">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 pad-card">
|
||||
@@ -102,7 +102,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 pad-card">
|
||||
<div class="card" id="streamercard-4">
|
||||
<div class="card card-channel" id="streamercard-4">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle05">Channel 05</h4>
|
||||
<div class="row">
|
||||
@@ -121,7 +121,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 pad-card">
|
||||
<div class="card" id="streamercard-5">
|
||||
<div class="card card-channel" id="streamercard-5">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle06">Channel 06</h4>
|
||||
<div class="row">
|
||||
@@ -140,7 +140,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 pad-card">
|
||||
<div class="card" id="streamercard-6">
|
||||
<div class="card card-channel" id="streamercard-6">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle07">Channel 07</h4>
|
||||
<div class="row">
|
||||
@@ -159,7 +159,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 pad-card">
|
||||
<div class="card" id="streamercard-7">
|
||||
<div class="card card-channel" id="streamercard-7">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle08">Channel 08</h4>
|
||||
<div class="row">
|
||||
@@ -180,7 +180,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-8">
|
||||
<div class="card card-channel" id="streamercard-8">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle09">Channel 09</h4>
|
||||
<div class="row">
|
||||
@@ -199,7 +199,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-9">
|
||||
<div class="card card-channel" id="streamercard-9">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle10">Channel 10</h4>
|
||||
<div class="row">
|
||||
@@ -218,7 +218,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-10">
|
||||
<div class="card card-channel" id="streamercard-10">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle11">Channel 11</h4>
|
||||
<div class="row">
|
||||
@@ -237,7 +237,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-11">
|
||||
<div class="card card-channel" id="streamercard-11">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle12">Channel 12</h4>
|
||||
<div class="row">
|
||||
@@ -258,7 +258,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-12">
|
||||
<div class="card card-channel" id="streamercard-12">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle13">Channel 13</h4>
|
||||
<div class="row">
|
||||
@@ -277,7 +277,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-13">
|
||||
<div class="card card-channel" id="streamercard-13">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle14">Channel 14</h4>
|
||||
<div class="row">
|
||||
@@ -296,7 +296,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-14">
|
||||
<div class="card card-channel" id="streamercard-14">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle15">Channel 15</h4>
|
||||
<div class="row">
|
||||
@@ -315,7 +315,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-15">
|
||||
<div class="card card-channel" id="streamercard-15">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle16">Channel 16</h4>
|
||||
<div class="row">
|
||||
@@ -336,7 +336,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-16">
|
||||
<div class="card card-channel" id="streamercard-16">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle17">Channel 17</h4>
|
||||
<div class="row">
|
||||
@@ -355,7 +355,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-17">
|
||||
<div class="card card-channel" id="streamercard-17">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle18">Channel 18</h4>
|
||||
<div class="row">
|
||||
@@ -374,7 +374,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-18">
|
||||
<div class="card card-channel" id="streamercard-18">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle19">Channel 19</h4>
|
||||
<div class="row">
|
||||
@@ -393,7 +393,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-19">
|
||||
<div class="card card-channel" id="streamercard-19">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle20">Channel 20</h4>
|
||||
<div class="row">
|
||||
@@ -414,7 +414,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-20">
|
||||
<div class="card card-channel" id="streamercard-20">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle21">Channel 21</h4>
|
||||
<div class="row">
|
||||
@@ -433,7 +433,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-21">
|
||||
<div class="card card-channel" id="streamercard-21">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle22">Channel 22</h4>
|
||||
<div class="row">
|
||||
@@ -452,7 +452,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-22">
|
||||
<div class="card card-channel" id="streamercard-22">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle23">Channel 23</h4>
|
||||
<div class="row">
|
||||
@@ -471,7 +471,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-23">
|
||||
<div class="card card-channel" id="streamercard-23">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle24">Channel 24</h4>
|
||||
<div class="row">
|
||||
@@ -492,7 +492,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-24">
|
||||
<div class="card card-channel" id="streamercard-24">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle25">Channel 25</h4>
|
||||
<div class="row">
|
||||
@@ -511,7 +511,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-25">
|
||||
<div class="card card-channel" id="streamercard-25">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle26">Channel 26</h4>
|
||||
<div class="row">
|
||||
@@ -530,7 +530,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-26">
|
||||
<div class="card card-channel" id="streamercard-26">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle27">Channel 27</h4>
|
||||
<div class="row">
|
||||
@@ -549,7 +549,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-27">
|
||||
<div class="card card-channel" id="streamercard-27">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle28">Channel 28</h4>
|
||||
<div class="row">
|
||||
@@ -570,7 +570,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-28">
|
||||
<div class="card card-channel" id="streamercard-28">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle29">Channel 29</h4>
|
||||
<div class="row">
|
||||
@@ -589,7 +589,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-29">
|
||||
<div class="card card-channel" id="streamercard-29">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle30">Channel 30</h4>
|
||||
<div class="row">
|
||||
@@ -608,7 +608,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-30">
|
||||
<div class="card card-channel" id="streamercard-30">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle31">Channel 31</h4>
|
||||
<div class="row">
|
||||
@@ -627,7 +627,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-31">
|
||||
<div class="card card-channel" id="streamercard-31">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle32">Channel 32</h4>
|
||||
<div class="row">
|
||||
@@ -648,7 +648,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-32">
|
||||
<div class="card card-channel" id="streamercard-32">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle33">Channel 33</h4>
|
||||
<div class="row">
|
||||
@@ -667,7 +667,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-33">
|
||||
<div class="card card-channel" id="streamercard-33">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle34">Channel 34</h4>
|
||||
<div class="row">
|
||||
@@ -686,7 +686,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-34">
|
||||
<div class="card card-channel" id="streamercard-34">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle35">Channel 35</h4>
|
||||
<div class="row">
|
||||
@@ -705,7 +705,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-35">
|
||||
<div class="card card-channel" id="streamercard-35">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle36">Channel 36</h4>
|
||||
<div class="row">
|
||||
@@ -726,7 +726,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-36">
|
||||
<div class="card card-channel" id="streamercard-36">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle37">Channel 37</h4>
|
||||
<div class="row">
|
||||
@@ -745,7 +745,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-37">
|
||||
<div class="card card-channel" id="streamercard-37">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle38">Channel 38</h4>
|
||||
<div class="row">
|
||||
@@ -764,7 +764,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-38">
|
||||
<div class="card card-channel" id="streamercard-38">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle39">Channel 39</h4>
|
||||
<div class="row">
|
||||
@@ -783,7 +783,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-39">
|
||||
<div class="card card-channel" id="streamercard-39">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle40">Channel 40</h4>
|
||||
<div class="row">
|
||||
@@ -804,7 +804,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-40">
|
||||
<div class="card card-channel" id="streamercard-40">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle41">Channel 41</h4>
|
||||
<div class="row">
|
||||
@@ -823,7 +823,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-41">
|
||||
<div class="card card-channel" id="streamercard-41">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle42">Channel 42</h4>
|
||||
<div class="row">
|
||||
@@ -842,7 +842,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-42">
|
||||
<div class="card card-channel" id="streamercard-42">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle43">Channel 43</h4>
|
||||
<div class="row">
|
||||
@@ -861,7 +861,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-43">
|
||||
<div class="card card-channel" id="streamercard-43">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle44">Channel 44</h4>
|
||||
<div class="row">
|
||||
@@ -882,7 +882,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-44">
|
||||
<div class="card card-channel" id="streamercard-44">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle-44">Channel 45</h4>
|
||||
<div class="row">
|
||||
@@ -901,7 +901,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-45">
|
||||
<div class="card card-channel" id="streamercard-45">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle46">Channel 46</h4>
|
||||
<div class="row">
|
||||
@@ -920,7 +920,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-46">
|
||||
<div class="card card-channel" id="streamercard-46">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle47">Channel 47</h4>
|
||||
<div class="row">
|
||||
@@ -939,7 +939,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-47">
|
||||
<div class="card card-channel" id="streamercard-47">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle48">Channel 48</h4>
|
||||
<div class="row">
|
||||
@@ -960,7 +960,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-48">
|
||||
<div class="card card-channel" id="streamercard-48">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle49">Channel 49</h4>
|
||||
<div class="row">
|
||||
@@ -979,7 +979,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-49">
|
||||
<div class="card card-channel" id="streamercard-49">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle50">Channel 50</h4>
|
||||
<div class="row">
|
||||
@@ -998,7 +998,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-50">
|
||||
<div class="card card-channel" id="streamercard-50">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle51">Channel 51</h4>
|
||||
<div class="row">
|
||||
@@ -1017,7 +1017,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-51">
|
||||
<div class="card card-channel" id="streamercard-51">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle52">Channel 52</h4>
|
||||
<div class="row">
|
||||
@@ -1038,7 +1038,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-52">
|
||||
<div class="card card-channel" id="streamercard-52">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle53">Channel 53</h4>
|
||||
<div class="row">
|
||||
@@ -1057,7 +1057,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-53">
|
||||
<div class="card card-channel" id="streamercard-53">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle54">Channel 54</h4>
|
||||
<div class="row">
|
||||
@@ -1076,7 +1076,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-54">
|
||||
<div class="card card-channel" id="streamercard-54">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle55">Channel 55</h4>
|
||||
<div class="row">
|
||||
@@ -1095,7 +1095,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-55">
|
||||
<div class="card card-channel" id="streamercard-55">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle56">Channel 56</h4>
|
||||
<div class="row">
|
||||
@@ -1116,7 +1116,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-56">
|
||||
<div class="card card-channel" id="streamercard-56">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle57">Channel 57</h4>
|
||||
<div class="row">
|
||||
@@ -1135,7 +1135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-57">
|
||||
<div class="card card-channel" id="streamercard-57">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle58">Channel 58</h4>
|
||||
<div class="row">
|
||||
@@ -1154,7 +1154,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-58">
|
||||
<div class="card card-channel" id="streamercard-58">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle59">Channel 59</h4>
|
||||
<div class="row">
|
||||
@@ -1173,7 +1173,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-59">
|
||||
<div class="card card-channel" id="streamercard-59">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle60">Channel 60</h4>
|
||||
<div class="row">
|
||||
@@ -1194,7 +1194,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-60">
|
||||
<div class="card card-channel" id="streamercard-60">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle61">Channel 61</h4>
|
||||
<div class="row">
|
||||
@@ -1213,7 +1213,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-61">
|
||||
<div class="card card-channel" id="streamercard-61">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle62">Channel 62</h4>
|
||||
<div class="row">
|
||||
@@ -1232,7 +1232,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-62">
|
||||
<div class="card card-channel" id="streamercard-62">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle63">Channel 63</h4>
|
||||
<div class="row">
|
||||
@@ -1251,7 +1251,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3 col-xxl-3 pad-card">
|
||||
<div class="card" id="streamercard-63">
|
||||
<div class="card card-channel" id="streamercard-63">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title" id="streamertitle64">Channel 64</h4>
|
||||
<div class="row">
|
||||
@@ -1274,20 +1274,20 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item pad-accordion pad-2">
|
||||
<h2 class="accordion-header" role="tab"><button class="accordion-button bg-heading2" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-2" aria-expanded="true" aria-controls="accordion-1 .item-2">Paging Queue</button></h2>
|
||||
<div class="accordion-collapse collapse show item-2 pad-2" role="tabpanel" data-bs-parent="#accordion-1">
|
||||
<h2 class="accordion-header" role="tab"><button class="accordion-button collapsed bg-heading2" type="button" data-bs-toggle="collapse" data-bs-target="#accordion-1 .item-2" aria-expanded="false" aria-controls="accordion-1 .item-2">Paging Queue</button></h2>
|
||||
<div class="accordion-collapse collapse item-2 pad-2" role="tabpanel" data-bs-parent="#accordion-1">
|
||||
<div class="accordion-body">
|
||||
<div class="row">
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">Index</th>
|
||||
<th class="col-sm-2">Date Time</th>
|
||||
<th class="col-sm-1">Source</th>
|
||||
<th class="col-sm-1">Type</th>
|
||||
<th class="col-sm-3">Message</th>
|
||||
<th class="col-sm-4">Broadcast Zones</th>
|
||||
<th class="class05">Index</th>
|
||||
<th class="class10">Date Time</th>
|
||||
<th class="class15">Source</th>
|
||||
<th class="class10">Type</th>
|
||||
<th class="class30">Message</th>
|
||||
<th class="class30">Broadcast Zones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="pagingqueuetable"></tbody>
|
||||
@@ -1310,12 +1310,12 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">Index</th>
|
||||
<th class="col-sm-2">Date Time</th>
|
||||
<th class="col-sm-1">Source</th>
|
||||
<th class="col-sm-1">Type</th>
|
||||
<th class="col-sm-3">Message</th>
|
||||
<th class="col-sm-4">Broadcast Zones</th>
|
||||
<th class="class05">Index</th>
|
||||
<th class="class10">Date Time</th>
|
||||
<th class="class15">Source</th>
|
||||
<th class="class10">Type</th>
|
||||
<th class="class30">Message</th>
|
||||
<th class="class30">Broadcast Zones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="automaticqueuetable"></tbody>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -17,8 +17,70 @@
|
||||
<h2 style="text-align: center;">Setting</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card card-setting">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title"><strong>Upload Soundbank</strong></h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">Path</label></div>
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4"><input class="w-100 form-control" type="text" id="setting_path"></div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" id="save_directory" type="button">Save Directory</button></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">Category</label></div>
|
||||
<div class="col-6 col-sm-10 col-md-2 col-lg-2 col-xl-2"><select id="setting_category" class="input-add form-select"></select></div>
|
||||
<div class="col-6 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">Language</label></div>
|
||||
<div class="col-6 col-sm-10 col-md-2 col-lg-2 col-xl-2"><select id="setting_language" class="input-add form-select"></select></div>
|
||||
<div class="col-6 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">Voice</label></div>
|
||||
<div class="col-6 col-sm-10 col-md-2 col-lg-2 col-xl-2"><select id="setting_voice" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
|
||||
<div class="bg-white w-100" id="drop-area" multiple=""><input type="file" id="file-input"><label class="form-label d">Drop files here or click to select</label></div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
|
||||
<div class="row"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row py-5">
|
||||
<div class="col">
|
||||
<div class="card card-setting">
|
||||
<div class="card-body pad-accordion">
|
||||
<h4 class="card-title"><strong>FIS CODE</strong></h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">GOP</label></div>
|
||||
<div class="col-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"><select id="input_GOP" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">GBP</label></div>
|
||||
<div class="col-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"><select id="input_GBP" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">GFC</label></div>
|
||||
<div class="col-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"><select id="input_GFC" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label">FLD</label></div>
|
||||
<div class="col-10 col-sm-10 col-md-10 col-lg-10 col-xl-10"><select id="input_FLD" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2"><label class="col-form-label"></label></div>
|
||||
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-2"><button class="btn w-100 pad-button btn-round-basic color-add" type="button">Save</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="assets/js/bs-init.js"></script>
|
||||
<script src="assets/js/dragdrop.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -42,13 +42,13 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th>Description</th>
|
||||
<th class="col-sm-1">TAG</th>
|
||||
<th class="col-sm-1">Category</th>
|
||||
<th class="col-sm-1">Language</th>
|
||||
<th class="col-sm-1">Type</th>
|
||||
<th class="col-sm-3">Filename</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class20">Description</th>
|
||||
<th class="class10">TAG</th>
|
||||
<th class="class15">Category</th>
|
||||
<th class="class15">Language</th>
|
||||
<th class="class10">Type</th>
|
||||
<th class="class25">Filename</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="soundbanktablebody"></tbody>
|
||||
@@ -102,7 +102,7 @@
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||
<p class="text-add">Path</p>
|
||||
</div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8"><select id="modalpath" class="input-add form-select" name="modalpath" data-control="select2"></select></div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8"><select id="modalpath" class="input-add form-select cw-100" name="modalpath" data-control="select2"></select></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-round-basic color-edit class25" id="soundbankclose" type="button" data-bs-dismiss="modal">Close</button><button class="btn btn-round-basic color-add class25" id="soundbanksave" type="button">Save</button></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -42,14 +42,15 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-2">Description</th>
|
||||
<th class="col-sm-1">Day</th>
|
||||
<th class="col-sm-1">Time</th>
|
||||
<th class="col-sm-2">Sound Path</th>
|
||||
<th class="col-sm-1">Repeat</th>
|
||||
<th class="col-sm-1">Enable</th>
|
||||
<th>Broadcast Zones</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class15">Description</th>
|
||||
<th class="class15">Day</th>
|
||||
<th class="class10">Time</th>
|
||||
<th class="class15">Sound Path</th>
|
||||
<th class="class10">Repeat</th>
|
||||
<th class="class05">Enable</th>
|
||||
<th class="class15">Broadcast Zones</th>
|
||||
<th class="class10">Language</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="schedulebanktablebody"></tbody>
|
||||
@@ -87,37 +88,13 @@
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulesunday" name="dayselection" value="Sunday"><label class="form-check-label" for="formCheck-8">Sunday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulemonday" name="dayselection" value="Monday"><label class="form-check-label" for="formCheck-7">Monday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="scheduletuesday" name="dayselection" value="Tuesday"><label class="form-check-label" for="formCheck-6">Tuesday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulewednesday" name="dayselection" value="Wednesday"><label class="form-check-label" for="formCheck-5">Wednesday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulethursday" name="dayselection" value="Thursday"><label class="form-check-label" for="formCheck-4">Thursday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulefriday" name="dayselection" value="Friday"><label class="form-check-label" for="formCheck-3">Friday</label></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pad-day">
|
||||
<div class="col">
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="schedulesaturday" name="dayselection" value="Saturday"><label class="form-check-label" for="formCheck-2">Saturday</label></div>
|
||||
<div class="form-check"><input class="form-check-input" type="radio" id="scheduleweekly"><label class="form-check-label" for="formCheck-1">Weekly</label></div><select class="w-100 input-add form-select" id="weeklyselect">
|
||||
<optgroup label="This is a group">
|
||||
<option value="12" selected="">This is item 1</option>
|
||||
<option value="13">This is item 2</option>
|
||||
<option value="14">This is item 3</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -134,12 +111,12 @@
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row w-100 h-100">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-3 col-xl-3"><input type="number" id="schedulehour" class="input-add form-control class100" value="0" min="0" max="23" step="1"></div>
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-3 col-xl-3">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4"><input type="number" id="schedulehour" class="input-add form-control class100" value="0" min="0" max="23" step="1"></div>
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2">
|
||||
<p class="pad-time">(H)</p>
|
||||
</div>
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-3 col-xl-3"><input class="w-100 input-add form-control" type="number" id="scheduleminute" value="0" min="0" max="59" step="1"></div>
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-3 col-xl-3">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4"><input class="w-100 input-add form-control" type="number" id="scheduleminute" value="0" min="0" max="59" step="1"></div>
|
||||
<div class="col-2 col-sm-2 col-md-2 col-lg-2 col-xl-2">
|
||||
<p class="pad-time">(M)</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,9 +124,25 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||
<p class="text-add">Sound Path</p>
|
||||
<p class="text-add">Message</p>
|
||||
</div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8"><select id="schedulemessage" class="input-add form-select"></select></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||
<p class="text-add">Language</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="row pad-day">
|
||||
<div class="col"><select class="w-100 input-add form-select" id="languageselect">
|
||||
<optgroup label="This is a group">
|
||||
<option value="12" selected="">This is item 1</option>
|
||||
<option value="13">This is item 2</option>
|
||||
<option value="14">This is item 3</option>
|
||||
</optgroup>
|
||||
</select></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8"><input type="text" id="schedulesoundpath" class="input-add form-control"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||
@@ -167,7 +160,13 @@
|
||||
<div class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4">
|
||||
<p class="text-add">Broadcast Zones</p>
|
||||
</div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-8 border" id="schedulezones"></div>
|
||||
<div class="col-8 col-sm-8 col-md-8 col-lg-9 col-xl-8 border"><select class="w-100 input-add form-select" id="schedulezones">
|
||||
<optgroup label="This is a group">
|
||||
<option value="12" selected="">This is item 1</option>
|
||||
<option value="13">This is item 2</option>
|
||||
<option value="14">This is item 3</option>
|
||||
</optgroup>
|
||||
</select></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-round-basic color-edit class25" id="scheduleclose" type="button" data-bs-dismiss="modal">Close</button><button class="btn btn-round-basic class25 color-add" id="schedulesave" type="button">Save</button></div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
|
||||
<title>AAS_NewGen_08OKT25</title>
|
||||
<title>AAS_NewGen_17OKT25</title>
|
||||
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="assets/css/bss-overrides.css">
|
||||
<link rel="stylesheet" href="assets/css/Login-Form-Basic-icons.css">
|
||||
@@ -42,13 +42,13 @@
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-sm-1">No</th>
|
||||
<th class="col-sm-1">Username</th>
|
||||
<th class="col-sm-1">Location</th>
|
||||
<th class="col-sm-2">Airline</th>
|
||||
<th class="col-sm-2">City</th>
|
||||
<th class="col-sm-2">Messagebank</th>
|
||||
<th class="col">Broadcast Zones</th>
|
||||
<th class="class05">No</th>
|
||||
<th class="class10">Username</th>
|
||||
<th class="class15">Location</th>
|
||||
<th class="class15">Airline</th>
|
||||
<th class="class15">City</th>
|
||||
<th class="class20">Messagebank</th>
|
||||
<th class="class20">Broadcast Zones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="usertablebody"></tbody>
|
||||
|
||||
@@ -16,6 +16,8 @@ import oshi.SystemInfo
|
||||
import oshi.hardware.CentralProcessor
|
||||
import oshi.hardware.GlobalMemory
|
||||
import oshi.hardware.NetworkIF
|
||||
import oshi.hardware.Sensors
|
||||
import oshi.software.os.OperatingSystem
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.time.LocalDateTime
|
||||
@@ -37,6 +39,8 @@ class Somecodes {
|
||||
val processor: CentralProcessor = si.hardware.processor
|
||||
val memory : GlobalMemory = si.hardware.memory
|
||||
val NetworkInfoMap = mutableMapOf<String, NetworkInformation>()
|
||||
val sensor : Sensors = si.hardware.sensors
|
||||
val os : OperatingSystem = si.operatingSystem
|
||||
|
||||
val datetimeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
|
||||
val dateformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
|
||||
@@ -492,6 +496,35 @@ class Somecodes {
|
||||
sb.append(".wav")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sensors information using OSHI library.
|
||||
* @return A string representing the CPU temperature, fan speeds, and CPU voltage, or an empty string if not available.
|
||||
*/
|
||||
fun GetSensorsInfo() : String {
|
||||
val cputemp = sensor.cpuTemperature
|
||||
val cpuvolt = sensor.cpuVoltage
|
||||
val fanspeed = sensor.fanSpeeds
|
||||
return if (cpuvolt>0 && cputemp > 0 && fanspeed.isNotEmpty()){
|
||||
String.format("CPU Temp: %.1f °C\nFan Speeds: %s RPM\nCPU Voltage: %.2f V",
|
||||
sensor.cpuTemperature,
|
||||
sensor.fanSpeeds.joinToString("/"),
|
||||
sensor.cpuVoltage
|
||||
)
|
||||
} else ""
|
||||
|
||||
}
|
||||
|
||||
fun GetUptime() : String {
|
||||
val value = os.systemUptime
|
||||
return if (value>0){
|
||||
// number of seconds since system boot
|
||||
val hours = value / 3600
|
||||
val minutes = (value % 3600) / 60
|
||||
val seconds = value % 60
|
||||
String.format("%02d:%02d:%02d", hours, minutes, seconds)
|
||||
} else ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
266
src/toa/Vx3K.kt
Normal file
266
src/toa/Vx3K.kt
Normal file
@@ -0,0 +1,266 @@
|
||||
package toa
|
||||
|
||||
import codes.Somecodes
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.tinylog.Logger
|
||||
import java.net.Inet4Address
|
||||
import java.net.InetSocketAddress
|
||||
import java.net.Socket
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
/**
|
||||
* VX3K Protocol
|
||||
* @param ipaddress IP address of the VX3K device, default to 192.168.14.1
|
||||
* @param port Port number of the VX3K device, from 50050-50053 default to 50053
|
||||
*/
|
||||
class Vx3K(val ipaddress : String = "192.168.14.1", val port : Int = 50053) {
|
||||
private val remotesocket : InetSocketAddress
|
||||
init{
|
||||
if (port !in 50050..50053){
|
||||
throw IllegalArgumentException("Port number must be between 50050 and 50053")
|
||||
}
|
||||
try{
|
||||
val inet = Inet4Address.getByName(ipaddress)
|
||||
remotesocket = InetSocketAddress(inet, port)
|
||||
} catch (_ : Exception){
|
||||
throw IllegalArgumentException("Invalid IP address: $ipaddress")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the VX3K device
|
||||
* @param timeout Connection timeout in milliseconds, default to 30000 ms
|
||||
*/
|
||||
fun Connect(timeout: Int = 30000){
|
||||
try{
|
||||
val socket = Socket()
|
||||
// read timeout 5 seconds
|
||||
socket.soTimeout = 5000
|
||||
socket.connect(remotesocket, timeout)
|
||||
} catch (e : Exception){
|
||||
Logger.error { "Failed to connect with ${remotesocket.hostName}:${remotesocket.port}, Message: ${e.message}" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual Contact Input (Commmand 0x1001)
|
||||
* @param ID : Device ID for VX3K, range 0 - 31
|
||||
* @param CIN : Contact Input Number, range 0 - 15 for normal terminal, 16 for emergency contact input1, 17 for emergency contact input2
|
||||
* @param isON : true for ON, false for OFF
|
||||
* @param cb : Callback function with parameters (success: Boolean, message: String)
|
||||
*/
|
||||
fun VirtualCIN(ID: Short, CIN: Short, isON: Boolean, cb : BiConsumer<Boolean, String>){
|
||||
val commandID = 0x1001.toShort()
|
||||
if (ID !in 0..31){
|
||||
cb.accept(false, "ID must be between 0 and 31")
|
||||
return
|
||||
}
|
||||
if (CIN !in 0..17){
|
||||
cb.accept(false, "CIN must be between 0 and 17")
|
||||
return
|
||||
}
|
||||
val payload = ByteBuffer.allocate(6).order(ByteOrder.BIG_ENDIAN)
|
||||
payload.putShort(ID)
|
||||
payload.putShort(CIN)
|
||||
payload.putShort(if (isON) 1 else 0)
|
||||
val command = Make_Request_Command(commandID, payload.array())
|
||||
Send_Receive(command,8){
|
||||
success, reply ->
|
||||
if (success){
|
||||
val bb = ByteBuffer.wrap(reply).order(ByteOrder.BIG_ENDIAN)
|
||||
val resp_commandID = bb.short
|
||||
val resp_code = bb.short
|
||||
if (resp_commandID==commandID){
|
||||
if (resp_code.toInt() == 0){
|
||||
cb.accept(true, "Virtual CIN command sent successfully to ${remotesocket.hostName}:${remotesocket.port}")
|
||||
} else {
|
||||
cb.accept(false, "Virtual CIN command failed with response code $resp_code from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Invalid response command ID $resp_commandID from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Failed to send Virtual CIN command to ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open / Close Audio Input in Broadcast Pattern (Command 0x1003 for old firmware, 0x1101 for new firmware)
|
||||
* @param NewFirmware Set to true if using new firmware version
|
||||
* @param ID Device ID for VX3K, range 0 - 39 for new firmware, 0 - 31 for old firmware
|
||||
* @param Channel Audio Input Channel, range 0 - 3
|
||||
* @param BroadcastZones Vx3K_BroadcastZone object with selected broadcast zones
|
||||
* @param cb Callback function with parameters (success: Boolean, message: String)
|
||||
*/
|
||||
fun AudioInput_BroadcastPattern(NewFirmware : Boolean, ID: Short, Channel: Short, BroadcastZones: Vx3K_BroadcastZone, cb: BiConsumer<Boolean, String>){
|
||||
val CommandID = if (NewFirmware) 0x1101.toShort() else 0x1003.toShort()
|
||||
if (NewFirmware){
|
||||
if (ID !in 0..39){
|
||||
cb.accept(false, "ID must be between 0 and 39")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (ID !in 0..31){
|
||||
cb.accept(false, "ID must be between 0 and 31")
|
||||
return
|
||||
}
|
||||
}
|
||||
if (Channel !in 0..3){
|
||||
cb.accept(false, "Channel must be between 0 and 3")
|
||||
return
|
||||
}
|
||||
|
||||
val payload = ByteBuffer.allocate(if (NewFirmware) 86 else 70).order(ByteOrder.BIG_ENDIAN)
|
||||
// Audio Input = 1
|
||||
payload.putShort(1)
|
||||
// VX3K ID
|
||||
payload.putShort(ID)
|
||||
// Audio Input Channel
|
||||
payload.putShort(Channel)
|
||||
// Broadcast Pattern Zones
|
||||
payload.put(BroadcastZones.payload)
|
||||
val command = Make_Request_Command(CommandID, payload.array())
|
||||
Send_Receive(command,8){
|
||||
success, reply ->
|
||||
if (success){
|
||||
val bb = ByteBuffer.wrap(reply).order(ByteOrder.BIG_ENDIAN)
|
||||
val resp_commandID = bb.short
|
||||
val resp_code = bb.short
|
||||
if (resp_commandID==CommandID){
|
||||
if (resp_code.toInt() == 0){
|
||||
cb.accept(true, "Open Audio Input Broadcast command sent successfully to ${remotesocket.hostName}:${remotesocket.port}")
|
||||
} else {
|
||||
cb.accept(false, "Open Audio Input Broadcast command failed with response code $resp_code from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Invalid response command ID $resp_commandID from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Failed to send Open Audio Input Broadcast command to ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open / Close Network Broadcast Pattern (Command 0x1102 for old firmware, 0x1104 for new firmware)
|
||||
* @param NewFirmware Set to true if using new firmware version
|
||||
* @param multicastIP Multicast IP address in string format, from 224.0.0.0 ~ 239.255.255.255, default to 224.0.0.1
|
||||
* @param port UDP Port number, port 5000-5255 is invalid, default to 5300
|
||||
* @param priority Broadcast Priority value, range 1 - 1024, default to 512 (to be checked later)
|
||||
* @param isBGM true for BGM, false for Paging
|
||||
* @param SSRC SSRC value, range 1 - 65535, default to 1 (to be checked later)
|
||||
* @param payloadType RTP Payload Type, range 0 - 127, default to 0 (to be checked later)
|
||||
* @param payloadSize RTP Payload Size, range 0 - 1500, default to 1000 (to be checked later)
|
||||
* @param BroadcastZones Vx3K_BroadcastZone object with selected broadcast zones
|
||||
* @param cb Callback function with parameters (success: Boolean, message: String)
|
||||
*/
|
||||
fun Network_BroadcastPattern(NewFirmware: Boolean,multicastIP: String = "224.0.0.1", port: Int = 5300, priority: Int = 512, isBGM: Boolean, SSRC: UShort = 1u, payloadType: Short = 0, payloadSize: Short = 1000, BroadcastZones: Vx3K_BroadcastZone, cb:BiConsumer<Boolean, String>){
|
||||
val CommandID = if (NewFirmware) 0x1104.toShort() else 0x1102.toShort()
|
||||
if (Somecodes.ValidIPV4(multicastIP)){
|
||||
val inet = Inet4Address.getByName(multicastIP)
|
||||
if (inet.isMulticastAddress){
|
||||
if (port in 5256..65535){
|
||||
if (priority in 1..1024){
|
||||
if (SSRC in 1u..65535u){
|
||||
if (payloadType in 0..127){
|
||||
if (payloadSize in 0..1500){
|
||||
val jitterbuffer = 1000 //TODO 32 signed integer, to be checked later
|
||||
val payload = ByteBuffer.allocate(if (NewFirmware) 100 else 84)
|
||||
payload.put(inet.address)
|
||||
payload.putShort(port.toShort())
|
||||
payload.putShort(priority.toShort())
|
||||
payload.putShort(if (isBGM) 1 else 0)
|
||||
payload.putShort(SSRC.toShort())
|
||||
payload.putShort(payloadType)
|
||||
payload.putShort(payloadSize)
|
||||
payload.putInt(jitterbuffer)
|
||||
payload.put(BroadcastZones.payload)
|
||||
val command = Make_Request_Command(CommandID, payload.array())
|
||||
Send_Receive(command,10){
|
||||
success, reply ->
|
||||
if (success){
|
||||
val bb = ByteBuffer.wrap(reply).order(ByteOrder.BIG_ENDIAN)
|
||||
val resp_commandID = bb.short
|
||||
val resp_code = bb.short
|
||||
// buang 2 short
|
||||
bb.short
|
||||
bb.short
|
||||
val sound_source_number = bb.short
|
||||
if (resp_commandID==CommandID){
|
||||
if (resp_code.toInt() == 0){
|
||||
cb.accept(true, "Open Network Broadcast command sent successfully to ${remotesocket.hostName}:${remotesocket.port}, Sound Source Number: $sound_source_number")
|
||||
} else {
|
||||
cb.accept(false, "Open Network Broadcast command failed with response code $resp_code from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Invalid response command ID $resp_commandID from ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
} else {
|
||||
cb.accept(false, "Failed to send Open Network Broadcast command to ${remotesocket.hostName}:${remotesocket.port}")
|
||||
}
|
||||
}
|
||||
} else cb.accept(false, "Payload Size must be between 0 and 1500")
|
||||
} else cb.accept(false, "Payload Type must be between 0 and 127")
|
||||
} else cb.accept(false, "SSRC must be between 1 and 65535")
|
||||
} else cb.accept(false, "Priority must be between 1 and 1024")
|
||||
} else cb.accept(false, "Port must be greater than 5255 and less than 65536")
|
||||
} else cb.accept(false, "multicastIP must between 224.0.0.0 ~ 239.255.255.255")
|
||||
} else cb.accept(false, "Multicast IP address invalid")
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Send command and receive reply from VX3K device
|
||||
* @param command Command byte array to send
|
||||
* @param expectedlength Expected length of the reply byte array
|
||||
* @param cb Callback function with parameters (success: Boolean, reply: ByteArray)
|
||||
*/
|
||||
private fun Send_Receive(command: ByteArray, expectedlength: Int, cb : BiConsumer<Boolean, ByteArray>){
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try{
|
||||
val tcp = Socket()
|
||||
tcp.soTimeout = 5000
|
||||
tcp.connect(remotesocket, 30000)
|
||||
val outstream = tcp.getOutputStream()
|
||||
val instream = tcp.getInputStream()
|
||||
outstream.write(command)
|
||||
outstream.flush()
|
||||
val reply = ByteArray(expectedlength)
|
||||
instream.read(reply)
|
||||
outstream.close()
|
||||
instream.close()
|
||||
tcp.close()
|
||||
cb.accept(true, reply)
|
||||
} catch (_: Exception){
|
||||
cb.accept(false, ByteArray(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap payload into VX3K Request Command format
|
||||
* @param commandID Command ID
|
||||
* @param Payload Payload data
|
||||
* @return ByteArray of the complete command
|
||||
*/
|
||||
private fun Make_Request_Command(commandID: Short, Payload: ByteArray) : ByteArray {
|
||||
val result = ByteBuffer.allocate(8+Payload.size).order(ByteOrder.BIG_ENDIAN)
|
||||
// command ID (2 bytes)
|
||||
result.putShort(commandID)
|
||||
// Response code (2 bytes), set 0 for Request
|
||||
result.putShort(0)
|
||||
// command length = command header (8 bytes) + payload size
|
||||
result.putShort((Payload.size+8).toShort())
|
||||
// flag and reserver = 0 (2 bytes)
|
||||
result.putShort(0)
|
||||
result.put(Payload)
|
||||
// read to byte array
|
||||
return result.array()
|
||||
}
|
||||
}
|
||||
67
src/toa/Vx3K_BroadcastZone.kt
Normal file
67
src/toa/Vx3K_BroadcastZone.kt
Normal file
@@ -0,0 +1,67 @@
|
||||
package toa
|
||||
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.or
|
||||
|
||||
/**
|
||||
* VX3K Broadcast Zone Configuration
|
||||
* Old Firmware: Broadcast Zone 1 - 512
|
||||
* New Firmware: Broadcast Zone 1 - 640
|
||||
* @param NewFirmware Set to true if using new firmware version
|
||||
*/
|
||||
@Suppress("unused")
|
||||
class Vx3K_BroadcastZone(val NewFirmware: Boolean = false) {
|
||||
val payload: ByteArray = if (NewFirmware) ByteArray(80) else ByteArray(64)
|
||||
|
||||
/**
|
||||
* Set a zone as active
|
||||
* @param zonenumber Zone number to set (1 to 512 for old firmware, 1 to 640 for new firmware)
|
||||
*/
|
||||
fun SetZone(zonenumber: Int){
|
||||
if (zonenumber<1) throw Exception("Minimum zone number is 1")
|
||||
if (NewFirmware){
|
||||
if (zonenumber>640) throw Exception("Maximum zone number is 640 for new firmware")
|
||||
} else {
|
||||
if (zonenumber>512) throw Exception("Maximum zone number is 512 for old firmware")
|
||||
}
|
||||
|
||||
val byteIndex = (zonenumber - 1) / 8
|
||||
val bitIndex = (zonenumber - 1) % 8
|
||||
payload[byteIndex] = payload[byteIndex] or (1 shl bitIndex).toByte()
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a zone (set as inactive)
|
||||
* @param zonenumber Zone number to clear (1 to 512 for old firmware, 1 to 640 for new firmware)
|
||||
*/
|
||||
fun ClearZone(zonenumber: Int){
|
||||
if (zonenumber<1) throw Exception("Minimum zone number is 1")
|
||||
if (NewFirmware){
|
||||
if (zonenumber>640) throw Exception("Maximum zone number is 640 for new firmware")
|
||||
} else {
|
||||
if (zonenumber>512) throw Exception("Maximum zone number is 512 for old firmware")
|
||||
}
|
||||
|
||||
val byteIndex = (zonenumber - 1) / 8
|
||||
val bitIndex = (zonenumber - 1) % 8
|
||||
payload[byteIndex] = payload[byteIndex] and ((1 shl bitIndex).inv().toByte())
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all zones as active
|
||||
*/
|
||||
fun SetAllZones(){
|
||||
for (i in payload.indices){
|
||||
payload[i] = 0xFF.toByte()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all zones (set all as inactive)
|
||||
*/
|
||||
fun ClearAllZones(){
|
||||
for (i in payload.indices){
|
||||
payload[i] = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package web
|
||||
|
||||
import StreamerOutputs
|
||||
import codes.Somecodes
|
||||
import codes.Somecodes.Companion.GetSensorsInfo
|
||||
import codes.Somecodes.Companion.GetUptime
|
||||
import codes.Somecodes.Companion.ListAudioFiles
|
||||
import codes.Somecodes.Companion.ValiDateForLogHtml
|
||||
import codes.Somecodes.Companion.ValidFile
|
||||
@@ -104,18 +106,25 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
objectmapper.readValue(wsMessageContext.message(), WebsocketCommand::class.java)
|
||||
when (cmd.command) {
|
||||
"getSystemTime" -> {
|
||||
val systemtime = LocalDateTime.now().format(Somecodes.datetimeformat1)
|
||||
val uptime = GetUptime()
|
||||
SendReply(
|
||||
wsMessageContext,
|
||||
cmd.command,
|
||||
LocalDateTime.now().format(Somecodes.datetimeformat1)
|
||||
if (uptime.isNotEmpty()) "Date & Time : $systemtime\nSystem Uptime : $uptime" else "Date & Time : $systemtime"
|
||||
)
|
||||
}
|
||||
|
||||
"getCPUStatus" -> {
|
||||
Somecodes.getCPUUsage { vv ->
|
||||
val sv = GetSensorsInfo()
|
||||
if (sv.isNotEmpty()){
|
||||
SendReply(wsMessageContext, cmd.command, vv+"\n"+sv)
|
||||
} else {
|
||||
SendReply(wsMessageContext, cmd.command, vv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"getMemoryStatus" -> {
|
||||
SendReply(wsMessageContext, cmd.command, Somecodes.getMemoryUsage())
|
||||
@@ -280,6 +289,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.soundDB.Add(addvalue)) {
|
||||
db.soundDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Added Sound Bank: $addvalue")
|
||||
} else it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to add soundbank to database")))
|
||||
} else it.status(400)
|
||||
@@ -297,6 +307,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.soundDB.Clear()) {
|
||||
db.soundDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Sound Bank table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate soundbank table")))
|
||||
}
|
||||
@@ -310,6 +321,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.soundDB.DeleteByIndex(index.toInt())) {
|
||||
db.soundDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Sound Bank with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete soundbank with index $index")))
|
||||
}
|
||||
@@ -379,6 +391,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.soundDB.UpdateByIndex(index.toInt(), sb)) {
|
||||
db.soundDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Soundbank $sb")
|
||||
} else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to update soundbank with index $index")))
|
||||
} else it.status(400)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Nothing has changed for soundbank with index $index")))
|
||||
@@ -455,6 +468,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.messageDB.Add(mb)){
|
||||
db.messageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Added Messagebank: $mb")
|
||||
} else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to add messagebank to database")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid Message_TAGS")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid Message_Detail")))
|
||||
@@ -468,6 +482,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.messageDB.Clear()) {
|
||||
db.messageDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Message Bank table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate messagebank table")))
|
||||
}
|
||||
@@ -481,6 +496,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.messageDB.DeleteByIndex(index.toInt())) {
|
||||
db.messageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Message Bank with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete messagebank with index $index")))
|
||||
}
|
||||
@@ -541,6 +557,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.messageDB.UpdateByIndex(index.toInt(), mb)) {
|
||||
db.messageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Messagebank $mb")
|
||||
} else it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update messagebank with index $index")))
|
||||
} else it.status(400)
|
||||
@@ -601,6 +618,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.languageDB.Add(newvalue)){
|
||||
db.languageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Added Language Link: $newvalue")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to add language link to database")))
|
||||
//println("Failed to add language link to database")
|
||||
@@ -623,6 +641,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.languageDB.Clear()) {
|
||||
db.languageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Language Link table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate language link table")))
|
||||
}
|
||||
@@ -636,6 +655,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.languageDB.DeleteByIndex(index.toInt())) {
|
||||
db.languageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Language Link with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete language link with index $index")))
|
||||
}
|
||||
@@ -670,6 +690,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.languageDB.UpdateByIndex(index.toInt(), ll)) {
|
||||
db.languageDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Language Link $ll")
|
||||
} else it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update language link with index $index")))
|
||||
} else it.status(400)
|
||||
@@ -722,6 +743,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.scheduleDB.Clear()) {
|
||||
db.scheduleDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Schedule Bank table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate schedulebank table")))
|
||||
}
|
||||
@@ -761,6 +783,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.scheduleDB.Add(newvalue)){
|
||||
db.scheduleDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Added Schedule Bank: $newvalue")
|
||||
} else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to add schedule to database")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid Language")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Contains unsupported BroadcastZones")))
|
||||
@@ -780,6 +803,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.scheduleDB.DeleteByIndex(index.toInt())) {
|
||||
db.scheduleDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Schedule Bank with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete schedule with index $index")))
|
||||
}
|
||||
@@ -859,6 +883,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.scheduleDB.UpdateByIndex(index.toInt(), sb)) {
|
||||
db.scheduleDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Schedule : $sb")
|
||||
} else it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update schedule with index $index")))
|
||||
} else it.status(400)
|
||||
@@ -911,6 +936,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.userDB.Clear()) {
|
||||
db.userDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear User Management table")
|
||||
} else {
|
||||
it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to truncate user table")))
|
||||
@@ -962,6 +988,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.userDB.Add(newuser)) {
|
||||
db.userDB.Resort()
|
||||
ctx.result(objectmapper.writeValueAsString(resultMessage("OK") ))
|
||||
db.Add_Log("AAS", "Added User: $newuser")
|
||||
} else ctx.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to add user to database")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Some ANN_ID not found in Messagebank") ))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Some broadcast zone tags not found in soundbank")) )
|
||||
@@ -979,6 +1006,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.userDB.DeleteByIndex(index.toInt())) {
|
||||
db.userDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted User with index $index")
|
||||
} else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete user with index $index")))
|
||||
}
|
||||
}
|
||||
@@ -1019,7 +1047,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.userDB.UpdateByIndex(index.toInt(), editeduser)){
|
||||
db.userDB.Resort()
|
||||
ctx.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
|
||||
db.Add_Log("AAS", "Updated User : $editeduser")
|
||||
} else ctx.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to update user with index $index")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Nothing has changed for user with index $index")))
|
||||
} else ctx.status(400).result(objectmapper.writeValueAsString(resultMessage("Some broadcast zone is not found in Broadcast Zone list")))
|
||||
@@ -1072,13 +1100,23 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
//TODO kirim list message dan broadcast zones untuk ADD/Edit schedule
|
||||
get("GetMessageAndBroadcastZones") {
|
||||
val result = object {
|
||||
//TODO filter message without input variable
|
||||
val messages = db.messageDB.List
|
||||
.filter { mb -> !mb.Message_Detail.contains("[") && !mb.Message_Detail.contains("]")}
|
||||
.map { mb -> "${mb.Description} [${mb.ANN_ID}]" }
|
||||
val broadcastzones = db.broadcastDB.List.map { it.description }
|
||||
|
||||
val broadcastzones = db.broadcastDB.List
|
||||
}
|
||||
it.result(objectmapper.writeValueAsString(result))
|
||||
}
|
||||
|
||||
// Kirim list language dari Messagebank berdasarkan ANN_ID
|
||||
get("GetLanguageList/{ANN_ID}") { get1 ->
|
||||
//kirim list language dari Messagebank
|
||||
val langlist = db.messageDB.List
|
||||
.filter { it.ANN_ID == get1.pathParam("ANN_ID").toInt().toUInt() }
|
||||
.map { it.Language }.distinct()
|
||||
get1.result(objectmapper.writeValueAsString(langlist))
|
||||
}
|
||||
}
|
||||
path("Log") {
|
||||
get("List") { get1 ->
|
||||
@@ -1141,6 +1179,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.broadcastDB.Clear()) {
|
||||
db.broadcastDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Broadcast Zones table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate broadcast zones table")))
|
||||
}
|
||||
@@ -1159,6 +1198,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.broadcastDB.Add(newbp)){
|
||||
db.broadcastDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS","Added Broadcast Zone: $newbp")
|
||||
} else it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to add broadcast zone to database")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid Relay")))
|
||||
} else it.status(400).result(objectmapper.writeValueAsString(resultMessage("Invalid Box")))
|
||||
@@ -1174,6 +1214,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.broadcastDB.DeleteByIndex(index.toInt())) {
|
||||
db.broadcastDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Broadcast Zone with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete broadcast zone with index $index")))
|
||||
}
|
||||
@@ -1218,6 +1259,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.broadcastDB.UpdateByIndex(index.toInt(), bz)) {
|
||||
db.broadcastDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Broadcast Zone : $bz")
|
||||
} else it.status(500)
|
||||
.result(objectmapper.writeValueAsString(resultMessage("Failed to update broadcast zone with index $index")))
|
||||
} else it.status(400)
|
||||
@@ -1274,6 +1316,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.soundchannelDB.Clear()) {
|
||||
db.soundchannelDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Sound Channel table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate sound channel table")))
|
||||
}
|
||||
@@ -1315,8 +1358,10 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
val newsc = SoundChannel(0u, _channel, _ip)
|
||||
if (db.soundchannelDB.UpdateByIndex(index.toInt(), newsc)) {
|
||||
println("Updated sound channel with index $index")
|
||||
|
||||
db.soundchannelDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Updated Sound Channel : $newsc")
|
||||
} else {
|
||||
println("Failed to update sound channel with index $index")
|
||||
it.status(500)
|
||||
@@ -1388,6 +1433,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.queuepagingDB.Clear()) {
|
||||
db.queuepagingDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear queue paging table")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate queue paging table")))
|
||||
}
|
||||
@@ -1401,6 +1447,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.queuepagingDB.DeleteByIndex(index.toInt())) {
|
||||
db.queuepagingDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted queue paging with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue paging with index $index")))
|
||||
}
|
||||
@@ -1420,6 +1467,8 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.queuetableDB.Clear()) {
|
||||
db.queuetableDB.Get()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Clear Automatic Queue Table")
|
||||
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to truncate queue sound table")))
|
||||
}
|
||||
@@ -1433,6 +1482,7 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
||||
if (db.queuetableDB.DeleteByIndex(index.toInt())) {
|
||||
db.queuetableDB.Resort()
|
||||
it.result(objectmapper.writeValueAsString(resultMessage("OK")))
|
||||
db.Add_Log("AAS", "Deleted Automatic Queue Table with index $index")
|
||||
} else {
|
||||
it.status(500).result(objectmapper.writeValueAsString(resultMessage("Failed to delete queue sound with index $index")))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user