commit 15/10/2025
Network monitoring beres
This commit is contained in:
@@ -339,7 +339,17 @@ $(document).ready(function () {
|
|||||||
$('#diskstatus').text("Disk : " + data)
|
$('#diskstatus').text("Disk : " + data)
|
||||||
break;
|
break;
|
||||||
case "getNetworkStatus":
|
case "getNetworkStatus":
|
||||||
$('#networkstatus').text("Network : " + data)
|
//console.log("Network status: ", data);
|
||||||
|
let result = "";
|
||||||
|
let json = JSON.parse(data);
|
||||||
|
if (Array.isArray(json) && json.length> 0){
|
||||||
|
json.forEach((net)=>{
|
||||||
|
//console.log("Network interface: ", net);
|
||||||
|
if (result.length>0) result+="\n"
|
||||||
|
result+=`${net.displayName} (${net.ipV4addr.join(";")}) TX:${(net.txSpeed/1024).toFixed(1)} KB/s RX:${(net.rxSpeed/1024).toFixed(1)} KB/s; `
|
||||||
|
})
|
||||||
|
} else result = "N/A";
|
||||||
|
$('#networkstatus').text(result)
|
||||||
break;
|
break;
|
||||||
case "getSystemTime":
|
case "getSystemTime":
|
||||||
$('#datetimetext').text(data)
|
$('#datetimetext').text(data)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ lateinit var audioPlayer: AudioPlayer
|
|||||||
val StreamerOutputs: MutableMap<String, BarixConnection> = HashMap()
|
val StreamerOutputs: MutableMap<String, BarixConnection> = HashMap()
|
||||||
lateinit var udpreceiver: UDPReceiver
|
lateinit var udpreceiver: UDPReceiver
|
||||||
lateinit var tcpreceiver: TCPReceiver
|
lateinit var tcpreceiver: TCPReceiver
|
||||||
const val version = "0.0.6 (14/10/2025)"
|
const val version = "0.0.7 (15/10/2025)"
|
||||||
// AAS 64 channels
|
// AAS 64 channels
|
||||||
const val max_channel = 64
|
const val max_channel = 64
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode
|
|||||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||||
import content.Category
|
import content.Category
|
||||||
import content.Language
|
import content.Language
|
||||||
|
import content.NetworkInformation
|
||||||
import content.ScheduleDay
|
import content.ScheduleDay
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -35,6 +36,7 @@ class Somecodes {
|
|||||||
val si = SystemInfo()
|
val si = SystemInfo()
|
||||||
val processor: CentralProcessor = si.hardware.processor
|
val processor: CentralProcessor = si.hardware.processor
|
||||||
val memory : GlobalMemory = si.hardware.memory
|
val memory : GlobalMemory = si.hardware.memory
|
||||||
|
val NetworkInfoMap = mutableMapOf<String, NetworkInformation>()
|
||||||
|
|
||||||
val datetimeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
|
val datetimeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
|
||||||
val dateformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
|
val dateformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
|
||||||
@@ -278,16 +280,43 @@ class Somecodes {
|
|||||||
, (usedMemory.toDouble() / totalMemory * 100))
|
, (usedMemory.toDouble() / totalMemory * 100))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GetNetworkStatus(networkname: String) : String{
|
fun GetNetworkStatus(cb : Consumer<List<NetworkInformation>>) {
|
||||||
val networks: List<NetworkIF> = si.hardware.networkIFs.toList()
|
val networks: List<NetworkIF> = si.hardware.networkIFs.toList()
|
||||||
//TODO cari network yang sesuai dengan networkname
|
networks.forEach { net ->
|
||||||
// networks.forEach { net ->
|
|
||||||
//
|
if (net.ifOperStatus==NetworkIF.IfOperStatus.UP){
|
||||||
// println(net.name+" "+net.displayName+" ")
|
if (net.iPv4addr.size>0 || net.iPv6addr.size>0){
|
||||||
// net.updateAttributes()
|
var ni = NetworkInfoMap[net.name]
|
||||||
// println("upload: ${SizetoHuman(net.bytesSent)} sent, download: ${SizetoHuman(net.bytesRecv)} received")
|
if (ni == null){
|
||||||
// }
|
ni = NetworkInformation(net.name, net.displayName, net.macaddr)
|
||||||
return ""
|
NetworkInfoMap[net.name] = ni
|
||||||
|
}
|
||||||
|
ni.ipV4addr = net.iPv4addr.toMutableList()
|
||||||
|
ni.ipV6addr = net.iPv6addr.toMutableList()
|
||||||
|
ni.speed = net.speed
|
||||||
|
ni.packetsSent = net.packetsSent
|
||||||
|
ni.packetsRecv = net.packetsRecv
|
||||||
|
if (ni.updateStamp==0L){
|
||||||
|
ni.bytesSent = net.bytesSent
|
||||||
|
ni.bytesRecv = net.bytesRecv
|
||||||
|
ni.txSpeed = 0
|
||||||
|
ni.rxSpeed = 0
|
||||||
|
ni.updateStamp = System.currentTimeMillis()
|
||||||
|
} else {
|
||||||
|
// tx speed = (current bytesSent - previous bytesSent) / (current time - previous time) * 1000
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
ni.txSpeed = ((net.bytesSent - ni.bytesSent) * 1000 / (currentTime - ni.updateStamp))
|
||||||
|
ni.rxSpeed = ((net.bytesRecv - ni.bytesRecv) * 1000 / (currentTime - ni.updateStamp))
|
||||||
|
ni.bytesSent = net.bytesSent
|
||||||
|
ni.bytesRecv = net.bytesRecv
|
||||||
|
ni.updateStamp = currentTime
|
||||||
|
}
|
||||||
|
} else if (NetworkInfoMap.contains(net.name)) NetworkInfoMap.remove(net.name)
|
||||||
|
} else if (NetworkInfoMap.contains(net.name)) NetworkInfoMap.remove(net.name)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
cb.accept(NetworkInfoMap.values.toList())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
15
src/content/NetworkInformation.kt
Normal file
15
src/content/NetworkInformation.kt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package content
|
||||||
|
|
||||||
|
class NetworkInformation(val name: String, val displayName: String, val macAddress: String) {
|
||||||
|
var ipV4addr: MutableList<String> = mutableListOf()
|
||||||
|
var ipV6addr: MutableList<String> = mutableListOf()
|
||||||
|
var bytesSent: Long = 0
|
||||||
|
var bytesRecv: Long = 0
|
||||||
|
var packetsSent: Long = 0
|
||||||
|
var packetsRecv: Long = 0
|
||||||
|
var speed: Long = 0 // in bits per second
|
||||||
|
var updateStamp : Long = 0 // epoch time in milliseconds, buat hitung speed
|
||||||
|
var txSpeed: Long = 0
|
||||||
|
var rxSpeed: Long = 0
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,28 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class BroadcastZones(var index: UInt, var description: String, var SoundChannel: String, var id: String, var bp: String)
|
data class BroadcastZones(var index: UInt, var description: String, var SoundChannel: String, var id: String, var bp: String){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all fields are not empty
|
||||||
|
*/
|
||||||
|
fun isNotEmpty(): Boolean{
|
||||||
|
if (description.isNotEmpty()){
|
||||||
|
if (SoundChannel.isNotEmpty()){
|
||||||
|
if (id.isNotEmpty()){
|
||||||
|
if (bp.isNotEmpty()){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string representation of the BroadcastZones object.
|
||||||
|
*/
|
||||||
|
override fun toString(): String {
|
||||||
|
return "BroadcastZones(index=$index, description='$description', SoundChannel='$SoundChannel', id='$id', bp='$bp')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
data class BroadcastZonesHtml(var index: UInt, var description: String, var SoundChannel: String, var Box: String, var Relay: String)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
data class IpZones(var index:UInt, var description: String, var ip: String)
|
|
||||||
@@ -1,4 +1,22 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
@Suppress("unused")
|
data class LanguageLink(var index: UInt, var TAG: String, var Language: String){
|
||||||
data class LanguageLink(var index: UInt, var TAG: String, var Language: String)
|
|
||||||
|
/**
|
||||||
|
* Check if the LanguageLink object has non-empty TAG and Language fields.
|
||||||
|
* @return true if both TAG and Language are not empty, false otherwise.
|
||||||
|
*/
|
||||||
|
fun isNotEmpty() : Boolean {
|
||||||
|
return TAG.isNotEmpty() && Language.isNotEmpty()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the LanguageLink object.
|
||||||
|
* @return A string in the format "LanguageLink(index=..., TAG='...', Language='...')".
|
||||||
|
*/
|
||||||
|
override fun toString(): String {
|
||||||
|
return "LanguageLink(index=$index, TAG='$TAG', Language='$Language')"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
@Suppress("unused")
|
data class LogSemiauto(val index: UInt, val date: String, val time: String, val source: String, val description: String){
|
||||||
data class LogSemiauto(val index: UInt, val date: String, val time: String, val source: String, val description: String)
|
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "$date $time [$source] $description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,4 +8,27 @@ data class Messagebank(
|
|||||||
var Voice_Type: String,
|
var Voice_Type: String,
|
||||||
var Message_Detail: String,
|
var Message_Detail: String,
|
||||||
var Message_TAGS: String
|
var Message_TAGS: String
|
||||||
)
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all fields are not empty and ANN_ID > 0
|
||||||
|
*/
|
||||||
|
fun isNotEmpty(): Boolean{
|
||||||
|
if (Description.isNotEmpty()){
|
||||||
|
if (Language.isNotEmpty()){
|
||||||
|
if (Voice_Type.isNotEmpty()){
|
||||||
|
if (Message_Detail.isNotEmpty()){
|
||||||
|
if (Message_TAGS.isNotEmpty()){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Messagebank(index=$index, Description='$Description', Language='$Language', ANN_ID=$ANN_ID, Voice_Type='$Voice_Type', Message_Detail='$Message_Detail', Message_TAGS='$Message_TAGS')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
data class QueueFids(var index: UInt, var ALCODE: String, var FLNUM: String, var ORIGIN: String, var ETAD: String, var FREMARK: String)
|
data class QueueFids(var index: UInt, var ALCODE: String, var FLNUM: String, var ORIGIN: String, var ETAD: String, var FREMARK: String){
|
||||||
|
|
||||||
|
fun isNotEmpty(): Boolean {
|
||||||
|
return ALCODE.isNotEmpty() && FLNUM.isNotEmpty() && ORIGIN.isNotEmpty() && ETAD.isNotEmpty() && FREMARK.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "QueueFids(index=$index, ALCODE='$ALCODE', FLNUM='$FLNUM', ORIGIN='$ORIGIN', ETAD='$ETAD', FREMARK='$FREMARK')"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
data class QueuePaging(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var BroadcastZones: String){
|
data class QueuePaging(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var BroadcastZones: String){
|
||||||
|
fun isNotEmpty(): Boolean {
|
||||||
|
return Date_Time.isNotEmpty() && Source.isNotEmpty() && Type.isNotEmpty() && Message.isNotEmpty() && BroadcastZones.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "QueuePaging(index=$index, Date_Time='$Date_Time', Source='$Source', Type='$Type', Message='$Message', BroadcastZones='$BroadcastZones')"
|
return "QueuePaging(index=$index, Date_Time='$Date_Time', Source='$Source', Type='$Type', Message='$Message', BroadcastZones='$BroadcastZones')"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ package database
|
|||||||
|
|
||||||
data class QueueTable(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var SB_TAGS: String, var BroadcastZones: String, var Repeat: UInt, var Language: String){
|
data class QueueTable(var index: UInt, var Date_Time: String, var Source: String, var Type: String, var Message: String, var SB_TAGS: String, var BroadcastZones: String, var Repeat: UInt, var Language: String){
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all fields are not empty
|
||||||
|
*/
|
||||||
|
fun isNotEmpty(): Boolean {
|
||||||
|
return Date_Time.isNotEmpty() && Source.isNotEmpty() && Type.isNotEmpty() && Message.isNotEmpty() && SB_TAGS.isNotEmpty() && BroadcastZones.isNotEmpty() && Language.isNotEmpty()
|
||||||
|
}
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "QueueTable(index=$index, Date_Time='$Date_Time', Source='$Source', Type='$Type', Message='$Message', SB_TAGS='$SB_TAGS', BroadcastZones='$BroadcastZones', Repeat=$Repeat, Language='$Language')"
|
return "QueueTable(index=$index, Date_Time='$Date_Time', Source='$Source', Type='$Type', Message='$Message', SB_TAGS='$SB_TAGS', BroadcastZones='$BroadcastZones', Repeat=$Repeat, Language='$Language')"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,4 +10,13 @@ data class ScheduleBank(
|
|||||||
var Repeat: UByte,
|
var Repeat: UByte,
|
||||||
var Enable: Boolean,
|
var Enable: Boolean,
|
||||||
var BroadcastZones: String,
|
var BroadcastZones: String,
|
||||||
var Language: String)
|
var Language: String) {
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "ScheduleBank(index=$index, Description='$Description', Day='$Day', Time='$Time', Soundpath='$Soundpath', Repeat=$Repeat, Enable=$Enable, BroadcastZones='$BroadcastZones', Language='$Language')"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNotEmpty() : Boolean{
|
||||||
|
return Description.isNotEmpty() && Day.isNotEmpty() && Time.isNotEmpty() && Soundpath.isNotEmpty() && BroadcastZones.isNotEmpty() && Language.isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,17 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
@Suppress("unused")
|
data class SoundChannel(val index: UInt, val channel: String, val ip: String) {
|
||||||
data class SoundChannel(val index: UInt, val channel: String, val ip: String)
|
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "SoundChannel(index=$index, channel='$channel', ip='$ip')"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if both channel and ip are not empty
|
||||||
|
* @return true if both channel and ip are not empty, false otherwise
|
||||||
|
*/
|
||||||
|
fun isNotEmpty() : Boolean {
|
||||||
|
return channel.isNotEmpty() && ip.isNotEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package database
|
package database
|
||||||
|
|
||||||
import content.Category
|
|
||||||
|
|
||||||
data class Soundbank(
|
data class Soundbank(
|
||||||
var index: UInt,
|
var index: UInt,
|
||||||
@@ -16,20 +15,7 @@ data class Soundbank(
|
|||||||
* Check if all fields are not empty
|
* Check if all fields are not empty
|
||||||
*/
|
*/
|
||||||
fun isNotEmpty(): Boolean{
|
fun isNotEmpty(): Boolean{
|
||||||
if (Description.isNotEmpty()){
|
return Description.isNotEmpty() && TAG.isNotEmpty() && Category.isNotEmpty() && Language.isNotEmpty() && VoiceType.isNotEmpty() && Path.isNotEmpty()
|
||||||
if (TAG.isNotEmpty()){
|
|
||||||
if (Category.isNotEmpty()){
|
|
||||||
if (Language.isNotEmpty()){
|
|
||||||
if (VoiceType.isNotEmpty()){
|
|
||||||
if (Path.isNotEmpty()){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ data class UserDB(var index: UInt, var username: String, var password: String, v
|
|||||||
return "UserDB(index=$index, username='$username', location='$location', airline_tags='$airline_tags', city_tags='$city_tags', messagebank_ann_id='$messagebank_ann_id', broadcastzones='$broadcastzones')"
|
return "UserDB(index=$index, username='$username', location='$location', airline_tags='$airline_tags', city_tags='$city_tags', messagebank_ann_id='$messagebank_ann_id', broadcastzones='$broadcastzones')"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isNotEmpty() : Boolean {
|
||||||
|
return username.isNotEmpty() && password.isNotEmpty() && location.isNotEmpty() && airline_tags.isNotEmpty() && city_tags.isNotEmpty() && messagebank_ann_id.isNotEmpty() && broadcastzones.isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this UserDB object with another UserDB object for equality.
|
* Compares this UserDB object with another UserDB object for equality.
|
||||||
* Two UserDB objects are considered equal if all their properties are equal, except for the index property.
|
* Two UserDB objects are considered equal if all their properties are equal, except for the index property.
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ import io.javalin.apibuilder.ApiBuilder.path
|
|||||||
import io.javalin.apibuilder.ApiBuilder.post
|
import io.javalin.apibuilder.ApiBuilder.post
|
||||||
import io.javalin.apibuilder.ApiBuilder.ws
|
import io.javalin.apibuilder.ApiBuilder.ws
|
||||||
import io.javalin.http.Context
|
import io.javalin.http.Context
|
||||||
import io.javalin.http.servlet.splitKeyValueStringAndGroupByKey
|
|
||||||
import io.javalin.json.JavalinJackson
|
import io.javalin.json.JavalinJackson
|
||||||
import io.javalin.websocket.WsMessageContext
|
import io.javalin.websocket.WsMessageContext
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||||
@@ -130,9 +129,9 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"getNetworkStatus" -> {
|
"getNetworkStatus" -> {
|
||||||
// TODO Get Network status
|
Somecodes.GetNetworkStatus { nn ->
|
||||||
Somecodes.GetNetworkStatus("")
|
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(nn))
|
||||||
SendReply(wsMessageContext, cmd.command, "OK")
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"getPagingQueue" ->{
|
"getPagingQueue" ->{
|
||||||
|
|||||||
Reference in New Issue
Block a user