commit 24/09/2025

This commit is contained in:
2025-09-24 11:48:36 +07:00
parent 59dd67acc8
commit 55f6a24cce
7 changed files with 156 additions and 15 deletions

View File

@@ -18,6 +18,7 @@ import web.WebApp
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime
import kotlin.concurrent.fixedRateTimer
fun main() {
@@ -141,7 +142,7 @@ fun main() {
listOf(
Pair("admin", "password"),
Pair("user", "password")
), db
), db, StreamerOutputs
)
web.Start()
@@ -154,7 +155,7 @@ fun main() {
// 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)
val _bc = BarixConnection(_sc.index,_sc.channel,cmd.ipaddress)
_bc.vu = cmd.vu
_bc.bufferRemain = cmd.buffremain
_bc.statusData = cmd.statusdata
@@ -163,7 +164,7 @@ fun main() {
} else {
// sudah ada, update data
if (_sc !=null && !_sc.channel.equals(_streamer.channel)) {
if (_sc !=null && _sc.channel != _streamer.channel) {
_streamer.channel = _sc.channel
}
_streamer.vu = cmd.vu
@@ -173,5 +174,23 @@ fun main() {
}
val onlinechecker = fixedRateTimer(name="onlinecheck", initialDelay = 1000, period = 1000) {
// cek setiap 1 detik, decrement online counter semua BarixConnection
StreamerOutputs.values.forEach {
it.decrementOnlineCounter()
}
}
// shutdown hook
Runtime.getRuntime().addShutdownHook(Thread {
Logger.info{"Shutdown hook called, stopping services..."}
barixserver.StopTcpCommand()
onlinechecker.cancel()
web.Stop()
audioPlayer.Close()
db.close()
Logger.info{"All services stopped, exiting application."}
} )
}

View File

@@ -75,7 +75,7 @@ class AudioPlayer (var samplingrate: Int) {
/**
* Uninitializes the audio system if it was previously initialized.
*/
fun UnInitAudio(){
fun Close(){
if (initedDevice != -1) {
bass.BASS_SetDevice(initedDevice)
if (bass.BASS_Free()) {

View File

@@ -1,26 +1,74 @@
package barix
import codes.Somecodes
import com.fasterxml.jackson.databind.JsonNode
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
class BarixConnection(val index: UInt, var channel: String, val ipaddress: String, val port: Int = 5002) {
private var _bR: Int = 0
private var _sd: Int = 0
private var _vu: Int = 0
private var _onlinecounter = 0
private val udp = DatagramSocket(0)
private val inet = InetSocketAddress(ipaddress, port)
/**
* Buffer remain in bytes
*/
var bufferRemain: Int
get() = _bR
set(value) {
_bR = value
_onlinecounter = 5
}
/**
* Status data, 0 = playback idle, 1 = playback running
*/
var statusData: Int
get() = _sd
set(value) {
_sd = if (value < 0) 0 else if (value > 1) 1 else value
_onlinecounter = 5
}
/**
* VU level 0-100
*/
var vu: Int
get() = _vu
set(value) {
_vu = if (value < 0) 0 else if (value > 100) 100 else value
_onlinecounter = 5
}
/**
* Decrement online counter, if counter reaches 0, the device is considered offline
*/
fun decrementOnlineCounter() {
if (_onlinecounter > 0) {
_onlinecounter--
}
}
fun isOnline(): Boolean {
return _onlinecounter > 0
}
/**
* 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{
if (data.isNotEmpty()) {
try {
udp.send(DatagramPacket(data, data.size, inet))
return true
} catch (e: Exception) {
@@ -30,4 +78,30 @@ class BarixConnection(var channel: String, val ipaddress: String, val port: Int
return false
}
/**
* Convert BarixConnection to JsonNode
* @return JsonNode representation of BarixConnection
*/
fun toJsonNode(): JsonNode {
// make json node from index, channel, ipaddress, port, bufferRemain, statusData, vu
return Somecodes.objectmapper.createObjectNode().apply {
put("index", index.toInt())
put("channel", channel)
put("ipaddress", ipaddress)
put("port", port)
put("bufferRemain", bufferRemain)
put("statusData", statusData)
put("vu", vu)
put("isOnline", isOnline())
}
}
/**
* Convert BarixConnection to JSON string
* @return JSON string representation of BarixConnection
*/
fun toJsonString(): String {
return Somecodes.toJsonString(toJsonNode())
}
}

View File

@@ -13,8 +13,9 @@ class TCP_Barix_Command_Server {
private var job: Job? = null
private val socketMap = mutableMapOf<String, Socket>()
private val regex: String = "\\$\\\"STATUSBARIX;(\\d+);(\\d+);?(\\d)?\\\"\\$"
private val regex = """\$\\"STATUSBARIX;(\d+);(\d+);?(\d)?\\"$"""
private val pattern = Regex(regex)
/**
* Start TCP Command Server
* @param port The port number to listen on (default is 5001)

View File

@@ -1,5 +1,7 @@
package codes
import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import content.ScheduleDay
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -31,6 +33,47 @@ class Somecodes {
const val MB_threshold = KB_threshold * 1024.0
const val GB_threshold = MB_threshold * 1024.0
const val TB_threshold = GB_threshold * 1024.0
val objectmapper = jacksonObjectMapper()
/**
* Convert an object to a JSON string.
* @param data The object to convert.
* @return A JSON string representation of the object, or "{}" if conversion fails.
*/
fun toJsonString(data: Any) : String {
return try {
objectmapper.writeValueAsString(data)
} catch (e: Exception){
"{}"
}
}
/**
* Convert a JSON string to an object of the specified class.
* @param json The JSON string to convert.
* @param clazz The class of the object to convert to.
* @return An object of the specified class, or null if conversion fails.
*/
fun <T> fromJsonString(json: String, clazz: Class<T>) : T? {
return try {
objectmapper.readValue(json, clazz)
} catch (e: Exception){
null
}
}
/**
* Convert a JSON string to a JsonNode.
* @param data The JSON string to convert.
* @return A JsonNode representation of the JSON string, or empty JsonNode if conversion fails.
*/
fun toJsonNode(data: String) : JsonNode {
return try {
objectmapper.readTree(data)
} catch (e: Exception){
objectmapper.createObjectNode()
}
}
/**
* List all audio files (.mp3 and .wav) in the specified directory and its subdirectories.

View File

@@ -1,7 +1,7 @@
package database
import codes.Somecodes.Companion.ValiDateForLogHtml
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import codes.Somecodes.Companion.toJsonString
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
@@ -50,7 +50,6 @@ class MariaDB(
return regex.matches(time)
}
private val objectMapper = jacksonObjectMapper()
/**
* Convert SoundbankList, MessagebankList, LanguageLinkList, or SchedulebankList to a JSON String.
@@ -59,7 +58,7 @@ class MariaDB(
*/
fun <T> ArrayListtoString(list: ArrayList<T>): String {
return try {
objectMapper.writeValueAsString(list)
toJsonString(list)
} catch (e: Exception) {
Logger.error("Error converting list to JSON: ${e.message}" as Any)
"[]"

View File

@@ -1,5 +1,6 @@
package web
import barix.BarixConnection
import codes.Somecodes
import codes.Somecodes.Companion.ListAudioFiles
import codes.Somecodes.Companion.ValiDateForLogHtml
@@ -35,7 +36,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.time.LocalDateTime
@Suppress("unused")
class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val db: MariaDB) {
class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val db: MariaDB, val StreamerOutputs : MutableMap<String, BarixConnection> ) {
var app: Javalin? = null
val objectmapper = jacksonObjectMapper()
@@ -134,6 +135,10 @@ class WebApp(val listenPort: Int, val userlist: List<Pair<String, String>>, val
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(db.Read_Queue_Table()))
}
"getStreamerOutputs" -> {
SendReply(wsMessageContext, cmd.command, objectmapper.writeValueAsString(StreamerOutputs.values.toList()))
}
else -> {
SendReply(wsMessageContext, cmd.command, "Unknown command")
}