Commit 25/09/2025
This commit is contained in:
505
src/Main.kt
505
src/Main.kt
@@ -1,21 +1,24 @@
|
|||||||
|
import audio.AudioFileInfo
|
||||||
import audio.AudioPlayer
|
import audio.AudioPlayer
|
||||||
import barix.BarixConnection
|
import barix.BarixConnection
|
||||||
import barix.TCP_Barix_Command_Server
|
import barix.TCP_Barix_Command_Server
|
||||||
import codes.Somecodes.Companion.Get_ANN_ID
|
import codes.Somecodes.Companion.Get_ANN_ID
|
||||||
import codes.Somecodes.Companion.IsAlphabethic
|
import codes.Somecodes.Companion.IsAlphabethic
|
||||||
import codes.Somecodes.Companion.IsNumber
|
import codes.Somecodes.Companion.IsNumber
|
||||||
|
import codes.Somecodes.Companion.Make_WAV_FileName
|
||||||
|
import codes.Somecodes.Companion.SoundbankResult_directory
|
||||||
import codes.Somecodes.Companion.ValidFile
|
import codes.Somecodes.Companion.ValidFile
|
||||||
import codes.Somecodes.Companion.ValidString
|
import codes.Somecodes.Companion.ValidString
|
||||||
import codes.Somecodes.Companion.dateformat1
|
import codes.Somecodes.Companion.dateformat1
|
||||||
import codes.Somecodes.Companion.timeformat2
|
import codes.Somecodes.Companion.timeformat2
|
||||||
import com.sun.jna.Platform
|
import com.sun.jna.Platform
|
||||||
import content.Category
|
import content.Category
|
||||||
import content.ContentCache
|
|
||||||
import content.Language
|
import content.Language
|
||||||
import content.ScheduleDay
|
import content.ScheduleDay
|
||||||
import content.VoiceType
|
import content.VoiceType
|
||||||
import database.MariaDB
|
import database.MariaDB
|
||||||
import database.Messagebank
|
import database.Messagebank
|
||||||
|
import database.Soundbank
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@@ -42,7 +45,6 @@ fun main() {
|
|||||||
Logger.info { "Starting AAS New Generation version $version" }
|
Logger.info { "Starting AAS New Generation version $version" }
|
||||||
val audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
|
val audioPlayer = AudioPlayer(44100) // 44100 Hz sampling rate
|
||||||
audioPlayer.InitAudio(1)
|
audioPlayer.InitAudio(1)
|
||||||
val content = ContentCache()
|
|
||||||
val db = MariaDB()
|
val db = MariaDB()
|
||||||
|
|
||||||
// Coroutine untuk cek Paging Queue dan AAS Queue setiap detik
|
// Coroutine untuk cek Paging Queue dan AAS Queue setiap detik
|
||||||
@@ -114,12 +116,79 @@ fun main() {
|
|||||||
return mb_list
|
return mb_list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Soundbank path for AlphabetNumeric category based on value
|
||||||
|
* @param sb List of Soundbank to search
|
||||||
|
* @param value String value to search, can be combination of letters and numbers, e.g. A1, B2, 3C, 12, etc.
|
||||||
|
* @return Soundbank path if found and valid, null if not found or invalid
|
||||||
|
*/
|
||||||
|
fun Get_Soundbank_AlpabethNumeric(sb: List<Soundbank>, value: String): List<String>? {
|
||||||
|
val result = mutableListOf<String>()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
if (sb.isNotEmpty()) {
|
||||||
|
val regex = Regex("([A-Z])?(\\d+)([A-Z])?")
|
||||||
|
val match = regex.find(value)
|
||||||
|
match?.groupValues?.forEach {
|
||||||
|
if (IsNumber(it)) {
|
||||||
|
val num =
|
||||||
|
sb.firstOrNull { s1 -> s1.Category == Category.AlphabetNumeric.name && s1.TAG == "N$it" }
|
||||||
|
if (num != null) {
|
||||||
|
if (ValidFile(num.Path)) {
|
||||||
|
result.add(num.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (IsAlphabethic(it)) {
|
||||||
|
val alp =
|
||||||
|
sb.firstOrNull { s1 -> s1.Category == Category.AlphabetNumeric.name && s1.TAG == it }
|
||||||
|
if (alp != null) {
|
||||||
|
if (ValidFile(alp.Path)) {
|
||||||
|
result.add(alp.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.isNotEmpty()) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val SoundbankKeywords = listOf("ANN_ID","AL","FLNUM","A_D","I_D","ORIGIN","CITY","SHALAT","PLACES","DESTINATION","ETAD","STANDCODE","GATECODE","REMARK","BCB","PLATNOMOR","REASON","PROCEDURE")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse soundbank data from string value in format "KEY:VALUE KEY:VALUE ..."
|
||||||
|
* @param value String value to parse
|
||||||
|
* @return Map of key-value pairs if valid, null if invalid
|
||||||
|
*/
|
||||||
|
fun Get_Soundbank_Data(value: String) : Map<String, String>? {
|
||||||
|
if (ValidString(value)){
|
||||||
|
val values = value.split(" ").map { it.trim() }.filter { ValidString(it) }
|
||||||
|
if (values.isNotEmpty()){
|
||||||
|
val result = mutableMapOf<String, String>()
|
||||||
|
values.forEach {
|
||||||
|
val kv = it.split(":")
|
||||||
|
if (kv.size==2){
|
||||||
|
val key = kv[0].trim().uppercase()
|
||||||
|
val val1 = kv[1].trim().uppercase()
|
||||||
|
if (ValidString(key) && ValidString(val1)){
|
||||||
|
if (SoundbankKeywords.contains(key)) result[key] = val1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.isNotEmpty()) return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find soundbank files from messagebank tags, filtered by VoiceType and Language
|
* Find soundbank files from messagebank tags, filtered by VoiceType and Language
|
||||||
* @param mb Messagebank object
|
* @param mb Messagebank object
|
||||||
* @param variables Map of variables to replace in tags.
|
* @param variables Map of variables to replace in tags.
|
||||||
* @param cbOK Callback function if success, returns List of soundbank file names
|
* @param cbOK Callback function if success, returns List of soundbank file names
|
||||||
* @param cbFail Callback function if fail, returns error message
|
* @param cbFail Callback function if failed, returns error message
|
||||||
*/
|
*/
|
||||||
fun Get_Soundbank_Files(
|
fun Get_Soundbank_Files(
|
||||||
mb: Messagebank,
|
mb: Messagebank,
|
||||||
@@ -144,38 +213,204 @@ fun main() {
|
|||||||
val files = mutableListOf<String>()
|
val files = mutableListOf<String>()
|
||||||
|
|
||||||
tags.forEach { tag ->
|
tags.forEach { tag ->
|
||||||
val _tag = tag.trim()
|
when (val _tag = tag.trim()) {
|
||||||
when (_tag) {
|
|
||||||
"[AIRPLANE_NAME]" -> {
|
"[AIRPLANE_NAME]" -> {
|
||||||
|
val value = variables["AIRPLANE_NAME"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val airplane =
|
||||||
|
sb.firstOrNull { it.Category == Category.Airplane_Name.name && it.TAG == value }
|
||||||
|
if (airplane != null) {
|
||||||
|
if (ValidFile(airplane.Path)) {
|
||||||
|
files.add(airplane.Path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("Invalid soundbank file ${airplane.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No Airplane_Name found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("AIRPLANE_NAME variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[FLIGHT_NUMBER]" -> {
|
"[FLIGHT_NUMBER]" -> {
|
||||||
|
val alcode = variables["AIRPLANE_NAME"].orEmpty()
|
||||||
|
val fncode = variables["FLIGHT_NUMBER"].orEmpty()
|
||||||
|
if (ValidString(alcode) && ValidString(fncode)) {
|
||||||
|
val val1 = sb.firstOrNull { it.Category == Category.Airline_Code.name && it.TAG == alcode }
|
||||||
|
val val2 = Get_Soundbank_AlpabethNumeric(sb, fncode)
|
||||||
|
if (val1 != null) {
|
||||||
|
if (ValidFile(val1.Path)) {
|
||||||
|
files.add(val1.Path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("Invalid soundbank file ${val1.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No Airline_Code found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (val2 != null && val2.isNotEmpty()) {
|
||||||
|
files.addAll(val2)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No valid soundbank files found for FLIGHT_NUMBER value '$fncode' for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cbFail.accept("AIRPLANE_NAME or FLIGHT_NUMBER variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[PLATNOMOR]" -> {
|
"[PLATNOMOR]" -> {
|
||||||
|
// plat nomor bisa huruf dan angka, atau huruf angka huruf, misalnya B123CD, AB1234EF, RI1
|
||||||
|
val value = variables["PLATNOMOR"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val regex = Regex("([A-Z]+)(\\d+)([A-Z]*)")
|
||||||
|
val match = regex.find(value)
|
||||||
|
if (match != null) {
|
||||||
|
val depan = match.groups[1]?.value // huruf depan
|
||||||
|
val tengah = match.groups[2]?.value // angka
|
||||||
|
val belakang = match.groups[3]?.value // huruf belakang, bisa kosong
|
||||||
|
// ambilin per huruf
|
||||||
|
depan?.forEach {
|
||||||
|
val dep = Get_Soundbank_AlpabethNumeric(sb, it.toString())
|
||||||
|
if (dep != null) {
|
||||||
|
files.addAll(dep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ambilin per angka
|
||||||
|
tengah?.forEach {
|
||||||
|
val tgh = Get_Soundbank_AlpabethNumeric(sb, it.toString())
|
||||||
|
if (tgh != null) {
|
||||||
|
files.addAll(tgh)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ambilin per huruf
|
||||||
|
belakang?.forEach {
|
||||||
|
val blk = Get_Soundbank_AlpabethNumeric(sb, it.toString())
|
||||||
|
if (blk != null) {
|
||||||
|
files.addAll(blk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("PLATNOMOR variable has invalid format for value '$value' in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("PLATNOMOR variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"[CITY]" -> {
|
"[CITY]" -> {
|
||||||
|
val values = variables["CITY"].orEmpty().split(";").map { it.trim() }.filter { ValidString(it) }
|
||||||
|
if (values.isNotEmpty()) {
|
||||||
|
values.forEach { vv ->
|
||||||
|
val city = sb.firstOrNull { it.Category == Category.City.name && it.TAG == vv }
|
||||||
|
if (city != null) {
|
||||||
|
if (ValidFile(city.Path)) {
|
||||||
|
files.add(city.Path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("Invalid soundbank file ${city.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No City found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("CITY variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"[PLACES]" -> {
|
"[PLACES]" -> {
|
||||||
|
val value = variables["PLACES"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val places = sb.firstOrNull { it.Category == Category.Places.name && it.TAG == value }
|
||||||
|
if (places != null) {
|
||||||
|
if (ValidFile(places.Path)) {
|
||||||
|
files.add(places.Path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("Invalid soundbank file ${places.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No Places found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("PLACES variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[ETAD]" -> {
|
"[ETAD]" -> {
|
||||||
|
val values = variables["ETAD"].orEmpty().split(":").map { it.trim() }.filter { IsNumber(it) }
|
||||||
|
if (values.size == 2) {
|
||||||
|
val hh = Get_Soundbank_AlpabethNumeric(sb, values[0])
|
||||||
|
val mm = Get_Soundbank_AlpabethNumeric(sb, values[1])
|
||||||
|
if (hh != null && mm != null && hh.isNotEmpty() && mm.isNotEmpty()) {
|
||||||
|
if (ValidFile(hh[0]) && ValidFile(mm[0])) {
|
||||||
|
files.add(hh[0])
|
||||||
|
files.add(mm[0])
|
||||||
|
} else {
|
||||||
|
cbFail.accept("ETAD variable has invalid soundbank files for tag $_tag in messagebank id ${mb.ANN_ID}, unable to find valid soundbank files for HH='${values[0]}' or MM='${values[1]}'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("ETAD variable has invalid soundbank for tag $_tag in messagebank id ${mb.ANN_ID}, unable to find soundbank for HH='${values[0]}' or MM='${values[1]}'")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("ETAD variable has invalid format for tag $_tag in messagebank id ${mb.ANN_ID}, expected format HH:MM")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[SHALAT]" -> {
|
"[SHALAT]" -> {
|
||||||
|
val value = variables["SHALAT"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val shalat = sb.firstOrNull { it.Category == Category.Shalat.name && it.TAG == value }
|
||||||
|
if (shalat != null) {
|
||||||
|
if (ValidFile(shalat.Path)) {
|
||||||
|
files.add(shalat.Path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("Invalid soundbank file ${shalat.Path} for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("No Shalat found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("SHALAT variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[BCB]" -> {
|
"[BCB]" -> {
|
||||||
|
// BCB bisa angka saja, misalnya 1,2,3
|
||||||
|
// atau huruf dan angka, misalnya A1, B2, C3, 1A, 2B, 3C
|
||||||
|
val value = variables["BCB"].orEmpty()
|
||||||
|
val path = Get_Soundbank_AlpabethNumeric(sb, value)
|
||||||
|
if (path != null) {
|
||||||
|
files.addAll(path)
|
||||||
|
} else {
|
||||||
|
cbFail.accept("BCB variable is missing, empty, or doesn't have valid soundbank for value '$value' in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"[GATENUMBER]" -> {
|
"[GATENUMBER]" -> {
|
||||||
@@ -184,17 +419,16 @@ fun main() {
|
|||||||
val value = variables["GATENUMBER"].orEmpty()
|
val value = variables["GATENUMBER"].orEmpty()
|
||||||
if (ValidString(value)) {
|
if (ValidString(value)) {
|
||||||
val values = value.split(",").map { it.trim() }.filter { ValidString(it) }
|
val values = value.split(",").map { it.trim() }.filter { ValidString(it) }
|
||||||
if (values.isNotEmpty()){
|
if (values.isNotEmpty()) {
|
||||||
values.forEach {
|
values.forEach { vv ->
|
||||||
if (IsNumber(it)){
|
val path = Get_Soundbank_AlpabethNumeric(sb, vv)
|
||||||
// gate number hanya angka
|
if (path != null) {
|
||||||
|
files.addAll(path)
|
||||||
} else {
|
} else {
|
||||||
// gate number gabungan huruf dan angka
|
cbFail.accept("GATENUMBER variable doesn't have valid soundbank for value '$vv' in messagebank id ${mb.ANN_ID}")
|
||||||
val regex = Regex("([A-Z])?(\\d+)([A-Z])?")
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cbFail.accept("GATENUMBER variable is empty after split for tag $_tag in messagebank id ${mb.ANN_ID}")
|
cbFail.accept("GATENUMBER variable is empty after split for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
return
|
return
|
||||||
@@ -207,7 +441,9 @@ fun main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
"[REASON]" -> {
|
"[REASON]" -> {
|
||||||
val reason = sb.firstOrNull { it.Category == Category.Reason.name && it.TAG == _tag }
|
val value = variables["REASON"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val reason = sb.firstOrNull { it.Category == Category.Reason.name && it.TAG == value }
|
||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
if (ValidFile(reason.Path)) {
|
if (ValidFile(reason.Path)) {
|
||||||
files.add(reason.Path)
|
files.add(reason.Path)
|
||||||
@@ -219,10 +455,17 @@ fun main() {
|
|||||||
cbFail.accept("No Reason found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
cbFail.accept("No Reason found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("REASON variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"[PROCEDURE]" -> {
|
"[PROCEDURE]" -> {
|
||||||
val procedure = sb.firstOrNull { it.Category == Category.Procedure.name && it.TAG == _tag }
|
val value = variables["PROCEDURE"].orEmpty()
|
||||||
|
if (ValidString(value)) {
|
||||||
|
val procedure = sb.firstOrNull { it.Category == Category.Procedure.name && it.TAG == value }
|
||||||
if (procedure != null) {
|
if (procedure != null) {
|
||||||
if (ValidFile(procedure.Path)) {
|
if (ValidFile(procedure.Path)) {
|
||||||
files.add(procedure.Path)
|
files.add(procedure.Path)
|
||||||
@@ -234,6 +477,11 @@ fun main() {
|
|||||||
cbFail.accept("No Procedure found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
cbFail.accept("No Procedure found for tag=$_tag voicetype=${mb.Voice_Type} language=${mb.Language} ANN_ID=${mb.ANN_ID}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cbFail.accept("PROCEDURE variable is missing or empty for tag $_tag in messagebank id ${mb.ANN_ID}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
@@ -255,6 +503,8 @@ fun main() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// all tags processed, return files
|
||||||
|
cbOK.accept(files)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,7 +546,62 @@ fun main() {
|
|||||||
// shalat, ambil messagebank berdasarkan ann_id dengan bahasa Indonesia saja
|
// shalat, ambil messagebank berdasarkan ann_id dengan bahasa Indonesia saja
|
||||||
Get_MessageBank_by_id(ann_id, listOf(Language.INDONESIA.name)).let { mblist ->
|
Get_MessageBank_by_id(ann_id, listOf(Language.INDONESIA.name)).let { mblist ->
|
||||||
if (mblist.isNotEmpty()) {
|
if (mblist.isNotEmpty()) {
|
||||||
//TODO find soundbank
|
Get_Soundbank_Files(
|
||||||
|
mblist[0],
|
||||||
|
emptyMap(),
|
||||||
|
{
|
||||||
|
// dapat list dari files dan sudah dicek valid path
|
||||||
|
listfile ->
|
||||||
|
val listafi = mutableListOf<AudioFileInfo>()
|
||||||
|
listfile.forEach { filenya ->
|
||||||
|
val afi = audioPlayer.LoadAudioFile(filenya)
|
||||||
|
if (afi.isValid()) {
|
||||||
|
listafi.add(afi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val targetfile = SoundbankResult_directory.resolve(
|
||||||
|
Make_WAV_FileName(
|
||||||
|
"Shalat",
|
||||||
|
""
|
||||||
|
)
|
||||||
|
).toString()
|
||||||
|
audioPlayer.WavWriter(
|
||||||
|
listafi,
|
||||||
|
targetfile
|
||||||
|
) { success, message ->
|
||||||
|
db.Add_Log("AAS", message)
|
||||||
|
if (success) {
|
||||||
|
// file siap broadcast
|
||||||
|
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
||||||
|
if (targetafi.isValid()) {
|
||||||
|
zz.forEach { z1 ->
|
||||||
|
StreamerOutputs.values.find { it.channel == z1 }
|
||||||
|
?.SendData(
|
||||||
|
targetafi.bytes,
|
||||||
|
{ db.Add_Log("AAS", it) },
|
||||||
|
{ db.Add_Log("AAS", it) })
|
||||||
|
}
|
||||||
|
val logmsg =
|
||||||
|
"Broadcast started SHALAT message with generated file '$targetfile' to zones: ${qp.BroadcastZones}"
|
||||||
|
Logger.info { logmsg }
|
||||||
|
db.Add_Log("AAS", logmsg)
|
||||||
|
db.Delete_Queue_Paging_by_index(qp.index)
|
||||||
|
} else {
|
||||||
|
db.Add_Log(
|
||||||
|
"AAS",
|
||||||
|
"Failed to load generated Shalat WAV file $targetfile"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
{ err ->
|
||||||
|
db.Delete_Queue_Paging_by_index(qp.index)
|
||||||
|
db.Add_Log("AAS", err)
|
||||||
|
}
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// tidak ada messagebank dengan ann_id ini, delete from queue paging
|
// tidak ada messagebank dengan ann_id ini, delete from queue paging
|
||||||
db.Delete_Queue_Paging_by_index(qp.index)
|
db.Delete_Queue_Paging_by_index(qp.index)
|
||||||
@@ -333,30 +638,174 @@ fun main() {
|
|||||||
|
|
||||||
|
|
||||||
// prioritas 2, habisin queue table
|
// prioritas 2, habisin queue table
|
||||||
db.Read_Queue_Table().forEach {
|
db.Read_Queue_Table().forEach { qa ->
|
||||||
if (it.BroadcastZones.isNotEmpty()) {
|
if (qa.BroadcastZones.isNotEmpty()) {
|
||||||
val zz = it.BroadcastZones.split(";")
|
val zz = qa.BroadcastZones.split(";")
|
||||||
if (AllBroadcastZonesValid(zz)) {
|
if (AllBroadcastZonesValid(zz)) {
|
||||||
if (AllBroadcastZoneIdle(zz)) {
|
if (AllBroadcastZoneIdle(zz)) {
|
||||||
if (it.Type == "SOUNDBANK") {
|
if (qa.Type == "SOUNDBANK") {
|
||||||
|
val variables = Get_Soundbank_Data(qa.SB_TAGS)
|
||||||
|
val languages = qa.Language.split(";")
|
||||||
|
// cek apakah ANN_ID ada di SB_TAGS
|
||||||
|
val ann_id = variables?.get("ANN_ID")?.toIntOrNull() ?: 0
|
||||||
|
if (ann_id==0){
|
||||||
|
// not available from variables, try to get from Message column
|
||||||
|
val remark = variables?.get("REMARK").orEmpty()
|
||||||
|
when(remark){
|
||||||
|
"GOP" -> {
|
||||||
|
//TODO Combobox First_Call_Message_Chooser
|
||||||
|
}
|
||||||
|
"GBD" ->{
|
||||||
|
// TODO Combobox Second_Call_Message_Chooser
|
||||||
|
}
|
||||||
|
"GFC" ->{
|
||||||
|
// TODO Combobox Final_Call_Message_Chooser
|
||||||
|
}
|
||||||
|
"FLD" ->{
|
||||||
|
// TODO Combobox Landed_Message_Chooser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else if (it.Type == "TIMER") {
|
// recheck again
|
||||||
|
if (ann_id == 0) {
|
||||||
|
db.Add_Log(
|
||||||
|
"AAS",
|
||||||
|
"Cancelled SOUNDBANK message with index ${qa.index} due to missing or invalid ANN_ID in SB_TAGS"
|
||||||
|
)
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
// sampe sini punya ann_id valid
|
||||||
|
|
||||||
|
val mblist = Get_MessageBank_by_id(ann_id, languages)
|
||||||
|
if (mblist.isNotEmpty()) {
|
||||||
|
mblist.forEach { mb ->
|
||||||
|
Get_Soundbank_Files(mb, variables ?: emptyMap(), {
|
||||||
|
listfile ->
|
||||||
|
val listafi = mutableListOf<AudioFileInfo>()
|
||||||
|
listfile.forEach { filenya ->
|
||||||
|
val afi = audioPlayer.LoadAudioFile(filenya)
|
||||||
|
if (afi.isValid()) {
|
||||||
|
listafi.add(afi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Soundbank","")).toString()
|
||||||
|
audioPlayer.WavWriter(listafi, targetfile
|
||||||
|
) { success, message ->
|
||||||
|
if (success) {
|
||||||
|
// file siap broadcast
|
||||||
|
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
||||||
|
if (targetafi.isValid()) {
|
||||||
|
zz.forEach { z1 ->
|
||||||
|
StreamerOutputs.values.find { it.channel == z1 }
|
||||||
|
?.SendData(
|
||||||
|
targetafi.bytes,
|
||||||
|
{ db.Add_Log("AAS", it) },
|
||||||
|
{ db.Add_Log("AAS", it) })
|
||||||
|
}
|
||||||
|
val logmsg =
|
||||||
|
"Broadcast started SOUNDBANK message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
||||||
|
Logger.info { logmsg }
|
||||||
|
db.Add_Log("AAS", logmsg)
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.Add_Log("AAS", message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err ->
|
||||||
|
db.Add_Log("AAS", err)
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// tidak ada messagebank dengan ann_id ini, delete from queue table
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
db.Add_Log(
|
||||||
|
"AAS",
|
||||||
|
"Cancelled SOUNDBANK message with index ${qa.index} due to ANN_ID $ann_id not found in Messagebank"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (qa.Type == "TIMER") {
|
||||||
|
val ann_id = Get_ANN_ID(qa.SB_TAGS)
|
||||||
|
if (ann_id > 0) {
|
||||||
|
val mblist = Get_MessageBank_by_id(ann_id, qa.Language.split(";"))
|
||||||
|
if (mblist.isNotEmpty()) {
|
||||||
|
mblist.forEach {
|
||||||
|
mb ->
|
||||||
|
Get_Soundbank_Files(mb, emptyMap(), {
|
||||||
|
listfile ->
|
||||||
|
val listafi = mutableListOf<AudioFileInfo>()
|
||||||
|
listfile.forEach { filenya ->
|
||||||
|
val afi = audioPlayer.LoadAudioFile(filenya)
|
||||||
|
if (afi.isValid()) {
|
||||||
|
listafi.add(afi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val targetfile = SoundbankResult_directory.resolve(Make_WAV_FileName("Timer","")).toString()
|
||||||
|
audioPlayer.WavWriter(listafi, targetfile
|
||||||
|
) { success, message ->
|
||||||
|
if (success) {
|
||||||
|
// file siap broadcast
|
||||||
|
val targetafi = audioPlayer.LoadAudioFile(targetfile)
|
||||||
|
if (targetafi.isValid()) {
|
||||||
|
zz.forEach { z1 ->
|
||||||
|
StreamerOutputs.values.find { it.channel == z1 }
|
||||||
|
?.SendData(
|
||||||
|
targetafi.bytes,
|
||||||
|
{ db.Add_Log("AAS", it) },
|
||||||
|
{ db.Add_Log("AAS", it) })
|
||||||
|
}
|
||||||
|
val logmsg =
|
||||||
|
"Broadcast started TIMER message with generated file '$targetfile' to zones: ${qa.BroadcastZones}"
|
||||||
|
Logger.info { logmsg }
|
||||||
|
db.Add_Log("AAS", logmsg)
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.Add_Log("AAS", message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err ->
|
||||||
|
db.Add_Log("AAS", err)
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// tidak ada messagebank dengan ann_id ini, delete from queue table
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
db.Add_Log(
|
||||||
|
"AAS",
|
||||||
|
"Cancelled TIMER with index ${qa.index} due to ANN_ID $ann_id not found in Messagebank"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// invalid ann_id, delete from queue table
|
||||||
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
|
db.Add_Log(
|
||||||
|
"AAS",
|
||||||
|
"Cancelled TIMER with index ${qa.index} due to invalid ANN_ID"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// ada broadcast zone yang tidak valid, delete from queue table
|
// ada broadcast zone yang tidak valid, delete from queue table
|
||||||
db.Delete_Queue_Table_by_index(it.index)
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
db.Add_Log(
|
db.Add_Log(
|
||||||
"AAS",
|
"AAS",
|
||||||
"Cancelled table message with index ${it.index} due to invalid broadcast zone"
|
"Cancelled table message with index ${qa.index} due to invalid broadcast zone"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// invalid broadcast zone, delete from queue table
|
// invalid broadcast zone, delete from queue table
|
||||||
db.Delete_Queue_Table_by_index(it.index)
|
db.Delete_Queue_Table_by_index(qa.index)
|
||||||
db.Add_Log("AAS", "Cancelled table message with index ${it.index} due to empty broadcast zone")
|
db.Add_Log("AAS", "Cancelled table message with index ${qa.index} due to empty broadcast zone")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import oshi.hardware.CentralProcessor
|
|||||||
import oshi.hardware.GlobalMemory
|
import oshi.hardware.GlobalMemory
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import java.time.LocalDateTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
@@ -21,6 +22,8 @@ import kotlin.io.path.name
|
|||||||
class Somecodes {
|
class Somecodes {
|
||||||
companion object {
|
companion object {
|
||||||
val current_directory : String = System.getProperty("user.dir")
|
val current_directory : String = System.getProperty("user.dir")
|
||||||
|
val SoundbankResult_directory : Path = Path.of(current_directory,"SoundbankResult")
|
||||||
|
val PagingResult_directory : Path = Path.of(current_directory,"PagingResult")
|
||||||
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
|
||||||
@@ -29,6 +32,7 @@ class Somecodes {
|
|||||||
val dateformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
|
val dateformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
|
||||||
val timeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss")
|
val timeformat1: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss")
|
||||||
val timeformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm")
|
val timeformat2: DateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm")
|
||||||
|
val filenameformat: DateTimeFormatter = DateTimeFormatter.ofPattern("ddMMyyyy_HHmmss")
|
||||||
const val KB_threshold = 1024.0
|
const val KB_threshold = 1024.0
|
||||||
const val MB_threshold = KB_threshold * 1024.0
|
const val MB_threshold = KB_threshold * 1024.0
|
||||||
const val GB_threshold = MB_threshold * 1024.0
|
const val GB_threshold = MB_threshold * 1024.0
|
||||||
@@ -354,6 +358,22 @@ class Somecodes {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a WAV file name with the current date and time.
|
||||||
|
* The file name format is: [prefix]_ddMMyyyy_HHmmss_[postfix].wav
|
||||||
|
* @param prefix An optional prefix to add before the date and time.
|
||||||
|
* @param postfix An optional postfix to add after the date and time.
|
||||||
|
* @return A string representing the generated WAV file name.
|
||||||
|
*/
|
||||||
|
fun Make_WAV_FileName(prefix: String, postfix: String) : String{
|
||||||
|
val sb = StringBuilder()
|
||||||
|
if (prefix.isNotEmpty()){sb.append(prefix).append("_")}
|
||||||
|
sb.append(filenameformat.format(LocalDateTime.now()))
|
||||||
|
if (postfix.isNotEmpty()){sb.append("_").append(postfix)}
|
||||||
|
sb.append(".wav")
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user