From 59dd67acc8e68e8c64aff8432d74386057b4173a Mon Sep 17 00:00:00 2001 From: rdkartono Date: Tue, 23 Sep 2025 16:13:32 +0700 Subject: [PATCH] commit 23/09/2025 --- src/Main.kt | 32 +++++++++++++++++++++++++++ src/barix/BarixConnection.kt | 31 +++++++++++++++++++++++++- src/barix/BarixStatus.kt | 7 ++++++ src/barix/TCP_Barix_Command_Server.kt | 28 ++++++++++++++++------- 4 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 src/barix/BarixStatus.kt diff --git a/src/Main.kt b/src/Main.kt index 008e3f3..bc986a1 100644 --- a/src/Main.kt +++ b/src/Main.kt @@ -1,4 +1,6 @@ import audio.AudioPlayer +import barix.BarixConnection +import barix.TCP_Barix_Command_Server import codes.Somecodes.Companion.dateformat1 import codes.Somecodes.Companion.timeformat2 import com.sun.jna.Platform @@ -20,6 +22,8 @@ import java.time.LocalTime fun main() { val version = "0.0.1 (23/09/2025)" + val StreamerOutputs : MutableMap = HashMap() + if (Platform.isWindows()) { // supaya OSHI bisa mendapatkan CPU usage di Windows seperti di Task Manager GlobalConfig.set(GlobalConfig.OSHI_OS_WINDOWS_CPU_UTILITY, true) @@ -141,5 +145,33 @@ fun main() { ) web.Start() + val barixserver = TCP_Barix_Command_Server () + barixserver.StartTcpServer { cmd -> + Logger.info{cmd} + val _streamer = StreamerOutputs[cmd.ipaddress] + val _sc = db.SoundChannelList.find { it.ip == cmd.ipaddress } + if (_streamer==null){ + // belum create BarixConnection untuk ipaddress ini + Logger.info{"New Streamer Output connection from ${cmd.ipaddress}"} + if (_sc!=null){ + val _bc = BarixConnection(_sc.channel,cmd.ipaddress) + _bc.vu = cmd.vu + _bc.bufferRemain = cmd.buffremain + _bc.statusData = cmd.statusdata + StreamerOutputs[cmd.ipaddress] = _bc + } + + } else { + // sudah ada, update data + if (_sc !=null && !_sc.channel.equals(_streamer.channel)) { + _streamer.channel = _sc.channel + } + _streamer.vu = cmd.vu + _streamer.bufferRemain = cmd.buffremain + _streamer.statusData = cmd.statusdata + } + + } + } diff --git a/src/barix/BarixConnection.kt b/src/barix/BarixConnection.kt index d36f70e..ad0b02d 100644 --- a/src/barix/BarixConnection.kt +++ b/src/barix/BarixConnection.kt @@ -1,4 +1,33 @@ package barix -class BarixConnection { +import org.tinylog.Logger +import java.net.DatagramPacket +import java.net.DatagramSocket +import java.net.InetSocketAddress + +@Suppress("unused") +class BarixConnection(var channel: String, val ipaddress: String, val port: Int = 5002) { + var bufferRemain: Int = 0 + var statusData: Int = 0 + var vu: Int = 0 + private val udp = DatagramSocket(0) + private val inet = InetSocketAddress(ipaddress, port) + + /** + * Send data to Barix device via UDP + * @param data The data to send + * @return true if successful + */ + fun SendData(data: ByteArray): Boolean { + if (data.isNotEmpty()){ + try{ + udp.send(DatagramPacket(data, data.size, inet)) + return true + } catch (e: Exception) { + Logger.error { "SendData to ${ipaddress}:${port} failed, message: ${e.message}" } + } + } + return false + + } } \ No newline at end of file diff --git a/src/barix/BarixStatus.kt b/src/barix/BarixStatus.kt new file mode 100644 index 0000000..5dbbe51 --- /dev/null +++ b/src/barix/BarixStatus.kt @@ -0,0 +1,7 @@ +package barix +@Suppress("unused") +data class BarixStatus(val ipaddress: String, val vu: Int, val buffremain: Int, val statusdata: Int){ + override fun toString(): String { + return "BarixStatus(ipaddress='$ipaddress', vu=$vu, buffremain=$buffremain, statusdata=$statusdata)" + } +} diff --git a/src/barix/TCP_Barix_Command_Server.kt b/src/barix/TCP_Barix_Command_Server.kt index 187f008..7e04029 100644 --- a/src/barix/TCP_Barix_Command_Server.kt +++ b/src/barix/TCP_Barix_Command_Server.kt @@ -1,12 +1,7 @@ package barix import codes.Somecodes.Companion.ValidString -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.isActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.* import org.tinylog.Logger import java.net.ServerSocket import java.net.Socket @@ -18,13 +13,15 @@ class TCP_Barix_Command_Server { private var job: Job? = null private val socketMap = mutableMapOf() + private val regex: String = "\\$\\\"STATUSBARIX;(\\d+);(\\d+);?(\\d)?\\\"\\$" + private val pattern = Regex(regex) /** * Start TCP Command Server * @param port The port number to listen on (default is 5001) * @param cb A callback function that will be called when a valid command is received * @return true if successful */ - fun StartTcpServer(port: Int = 5001, cb: Consumer): Boolean { + fun StartTcpServer(port: Int = 5001, cb: Consumer): Boolean { try { val tcp = ServerSocket(port) tcpserver = tcp @@ -48,7 +45,22 @@ class TCP_Barix_Command_Server { din.read(bb) // B4A format, 4 bytes di depan adalah size val str = String(bb) - if (ValidString(str)) cb.accept(str) + if (ValidString(str)) { + // Valid command from Barix is in format $"STATUSBARIX;VU;BuffRemain;StatusData"$ + pattern.find(str)?.let { matchResult -> + val (vu, buffremain, statusdata) = matchResult.destructured + val status = BarixStatus( + socket.inetAddress.hostAddress, + vu.toInt(), + buffremain.toInt(), + statusdata.toIntOrNull() ?: 0 + ) + Logger.info { "Received valid command from $key : $status" } + cb.accept(status) + } ?: run { + Logger.warn { "Invalid command format from $key : $str" } + } + } } } }