package barix import codes.Somecodes import com.fasterxml.jackson.databind.JsonNode import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.net.DatagramPacket import java.net.DatagramSocket import java.net.InetSocketAddress import java.nio.ByteBuffer import java.util.function.Consumer @Suppress("unused") 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-- } } /** * Check if Barix device is online * @return true if online */ fun isOnline(): Boolean { return _onlinecounter > 0 } /** * Check if Barix device is idle (not playing) * @return true if idle */ fun isIdle() : Boolean{ return statusData == 0 } /** * Check if Barix device is playing * @return true if playing */ fun isPlaying() : Boolean{ return statusData == 1 } /** * Send data to Barix device via UDP * @param data The data to send */ fun SendData(data: ByteArray, cbOK: Consumer, cbFail: Consumer) { if (data.isNotEmpty()) { CoroutineScope(Dispatchers.IO).launch { val bb = ByteBuffer.wrap(data) while(bb.hasRemaining()){ try { val chunk = ByteArray(if (bb.remaining() > 1400) 1400 else bb.remaining()) bb.get(chunk) udp.send(DatagramPacket(chunk, chunk.size, inet)) delay(5) } catch (e: Exception) { cbFail.accept("SendData to $ipaddress:$port failed, message: ${e.message}") return@launch } } cbOK.accept("SendData to $channel ($ipaddress:$port) succeeded, ${data.size} bytes sent") } } } /** * 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()) } }