From abed46d2284dcdc63d87b08efef5ca760caba890 Mon Sep 17 00:00:00 2001 From: rdkartono Date: Fri, 4 Jul 2025 15:58:06 +0700 Subject: [PATCH] commit 04/07/2025 --- src/additional/Somecodes.java | 18 +++- src/web/SetContactDescriptionargs.java | 24 +++++ src/web/SetContactEmailargs.java | 27 ++++++ src/web/SetContactModbusargs.java | 43 +++++++++ src/web/SetContactMqttargs.java | 25 +++++ src/web/SetContactVX3Kargs.java | 73 +++++++++++++++ src/web/WebServer.java | 123 +++++++++++++++++++++++++ 7 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 src/web/SetContactDescriptionargs.java create mode 100644 src/web/SetContactEmailargs.java create mode 100644 src/web/SetContactModbusargs.java create mode 100644 src/web/SetContactMqttargs.java create mode 100644 src/web/SetContactVX3Kargs.java diff --git a/src/additional/Somecodes.java b/src/additional/Somecodes.java index 4e5296c..034fea0 100644 --- a/src/additional/Somecodes.java +++ b/src/additional/Somecodes.java @@ -8,14 +8,30 @@ public class Somecodes { public static String currentdirectory = System.getProperty("user.dir"); public static Gson gson = new Gson(); + public static final int MinModbusRegister = 0; + public static final int MaxModbusRegister = 1999; + public static final int MinVX3kFrameID = 0; + public static final int MaxVX3kFrameID = 39; + public static final int MinVX3kRelayID = 0; + public static final int MaxVX3kRelayID = 15; + public static boolean ValidString(String string) { return string != null && !string.isBlank(); } + public static boolean ValidEmail(String email) { + if (ValidString(email)){ + // simple regex to check if email is valid + String emailRegex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$"; + return email.matches(emailRegex); + } + return false; + + } + - } diff --git a/src/web/SetContactDescriptionargs.java b/src/web/SetContactDescriptionargs.java new file mode 100644 index 0000000..2745ab5 --- /dev/null +++ b/src/web/SetContactDescriptionargs.java @@ -0,0 +1,24 @@ +package web; + +import additional.Somecodes; + +public record SetContactDescriptionargs(String contact, String description) { + + public int getContactID(){ + // contact is string like c1, c2, c3, etc. + // regex it to extract the number + if (Somecodes.ValidString(contact)){ + var matcher = java.util.regex.Pattern.compile("c(\\d+)").matcher(contact); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException ignored) { + + } + } + } + return -1; // Invalid contact ID + + + } +} diff --git a/src/web/SetContactEmailargs.java b/src/web/SetContactEmailargs.java new file mode 100644 index 0000000..54f36e8 --- /dev/null +++ b/src/web/SetContactEmailargs.java @@ -0,0 +1,27 @@ +package web; + +import additional.Somecodes; + +public record SetContactEmailargs(String contact, String email) { + + public int getContactID() { + // contact is string like c1, c2, c3, etc. + // regex it to extract the number + if (Somecodes.ValidString(contact)) { + var matcher = java.util.regex.Pattern.compile("c(\\d+)").matcher(contact); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException ignored) { + } + } + } + return -1; // Invalid contact ID + } + + public boolean getEnabled() { + // check if email is in valid format, then enabled. + // otherwise disabled. + return Somecodes.ValidEmail(email); + } +} diff --git a/src/web/SetContactModbusargs.java b/src/web/SetContactModbusargs.java new file mode 100644 index 0000000..05cd310 --- /dev/null +++ b/src/web/SetContactModbusargs.java @@ -0,0 +1,43 @@ +package web; + + +import static additional.Somecodes.*; + +public record SetContactModbusargs(String contact, String register) { + + public int getContactID() { + // contact is string like c1, c2, c3, etc. + // regex it to extract the number + if (ValidString(contact)) { + var matcher = java.util.regex.Pattern.compile("c(\\d+)").matcher(contact); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException ignored) { + } + } + } + return -1; // Invalid contact ID + } + + public boolean getEnabled(){ + // if register is number between Somecodes.MinModbusRegister ~ Somecodes.MaxModbusRegister then enabled is true + if (ValidString(register)) { + try { + int reg = Integer.parseInt(register); + return reg >= MinModbusRegister && reg < MaxModbusRegister; // Assuming valid registers are between 0 and 1999 + } catch (NumberFormatException ignored) {} + } + return false; + } + + public int getRegisterID() { + + if (ValidString(register)) { + try{ + return Integer.parseInt(register); + } catch (Exception ignored) {} + } + return -1; // Invalid register ID + } +} diff --git a/src/web/SetContactMqttargs.java b/src/web/SetContactMqttargs.java new file mode 100644 index 0000000..9024693 --- /dev/null +++ b/src/web/SetContactMqttargs.java @@ -0,0 +1,25 @@ +package web; + +import additional.Somecodes; + +public record SetContactMqttargs(String contact, String mqtt) { + + public int getContactID() { + // contact is string like c1, c2, c3, etc. + // regex it to extract the number + if (Somecodes.ValidString(contact)) { + var matcher = java.util.regex.Pattern.compile("c(\\d+)").matcher(contact); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException ignored) { + } + } + } + return -1; // Invalid contact ID + } + + public boolean getEnabled() { + return "Enabled".equalsIgnoreCase(mqtt) || "true".equalsIgnoreCase(mqtt) || "1".equalsIgnoreCase(mqtt); + } +} diff --git a/src/web/SetContactVX3Kargs.java b/src/web/SetContactVX3Kargs.java new file mode 100644 index 0000000..02ef998 --- /dev/null +++ b/src/web/SetContactVX3Kargs.java @@ -0,0 +1,73 @@ +package web; + +import additional.Somecodes; + +public record SetContactVX3Kargs(String contact, String value) { + + public int getContactID() { + // contact is string like c1, c2, c3, etc. + // regex it to extract the number + if (Somecodes.ValidString(contact)) { + var matcher = java.util.regex.Pattern.compile("c(\\d+)").matcher(contact); + if (matcher.find()) { + try { + return Integer.parseInt(matcher.group(1)); + } catch (NumberFormatException ignored) { + // Ignore and return -1 + } + } + } + return -1; // Invalid contact ID + } + + public boolean getEnabled(){ + // if value is in format "FrameID:RelayID" then return true + // with FrameID is between Somecodes.MinVX3kFrameID and Somecodes.MaxVX3kFrameID + // and RelayID is between Somecodes.MinVX3kRelayID and Somecodes.MaxVX3kRelayID + // otherwise return false + if (Somecodes.ValidString(value)) { + var parts = value.split(":"); + if (parts.length == 2) { + try { + int frameID = Integer.parseInt(parts[0]); + int relayID = Integer.parseInt(parts[1]); + return frameID >= Somecodes.MinVX3kFrameID && frameID <= Somecodes.MaxVX3kFrameID && + relayID >= Somecodes.MinVX3kRelayID && relayID <= Somecodes.MaxVX3kRelayID; + } catch (NumberFormatException ignored) { + // Ignore and return false + } + } + } + return false; + } + + public int getFrameID(){ + // from value with format "FrameID:RelayID" get the FrameID + if (Somecodes.ValidString(value)) { + var parts = value.split(":"); + if (parts.length > 0) { + try { + return Integer.parseInt(parts[0]); + } catch (NumberFormatException ignored) { + // Ignore and return -1 + } + } + } + return -1; // Invalid frame ID + } + + public int getRelayID(){ + // from value with format "FrameID:RelayID" get the RelayID + if (Somecodes.ValidString(value)) { + var parts = value.split(":"); + if (parts.length > 1) { + try { + return Integer.parseInt(parts[1]); + } catch (NumberFormatException ignored) { + // Ignore and return -1 + } + } + } + return -1; // Invalid relay ID + } +} diff --git a/src/web/WebServer.java b/src/web/WebServer.java index cc31e5a..ebd5ab1 100644 --- a/src/web/WebServer.java +++ b/src/web/WebServer.java @@ -43,6 +43,10 @@ public class WebServer { return; } + // https://javalin.io/tutorials/auth-example + // https://github.com/javalin/javalin-samples/blob/main/javalin6/javalin-auth-example/src/main/java/Main.java + //TODO implement authentication and authorization + app.ws("/ws", ws->{ ws.onConnect(ctx -> { Logger.info("WebSocket connected: {}", ctx.session.getRemoteAddress()); @@ -92,6 +96,125 @@ public class WebServer { case "GET_CONTACT_STATUS": // ambil dari Nanopi Gpio, kirim balik break; + case "SET_CONTACT_DESCRIPTION": + // ganti Deskripsi kontak input + SetContactDescriptionargs value = gson.fromJson(req.args(), SetContactDescriptionargs.class); + if (value.getContactID()>=0){ + ContactInputData contactInput = Main.db.GetContactInputData(value.getContactID()); + if (contactInput != null) { + contactInput.Description = value.description(); + Main.db.Update_ContactInputData(contactInput); + ctx.send(new webResponse("SET_CONTACT_DESCRIPTION", "Contact description updated successfully.")); + } else { + Logger.error("Contact input not found for ID: {}", value.getContactID()); + ctx.send(new webResponse("ERROR", "Contact input not found")); + } + + } else { + Logger.error("Invalid contact ID: {}", value.contact()); + ctx.send(new webResponse("ERROR", "Invalid contact ID")); + } + + break; + case "SET_CONTACT_EMAIL": + // ganti Email untuk kontak input + SetContactEmailargs emailArgs = gson.fromJson(req.args(), SetContactEmailargs.class); + if (emailArgs.getContactID()>=0){ + ContactInputData contactInput = Main.db.GetContactInputData(emailArgs.getContactID()); + if (contactInput != null) { + if (emailArgs.getEnabled()){ + contactInput.EnableEmail = true; + contactInput.EmailRecipient = emailArgs.email(); + } else { + // jika email tidak valid, set EnableEmail ke false + contactInput.EnableEmail = false; + contactInput.EmailRecipient = ""; + } + Main.db.Update_ContactInputData(contactInput); + ctx.send(new webResponse("SET_CONTACT_EMAIL", "Contact email updated successfully.")); + } else { + Logger.error("Contact input not found for ID: {}", emailArgs.getContactID()); + ctx.send(new webResponse("ERROR", "Contact input not found")); + } + } else { + Logger.error("Invalid contact ID: {}", emailArgs.contact()); + ctx.send(new webResponse("ERROR", "Invalid contact ID")); + } + break; + case "SET_CONTACT_MODBUS": + // ganti Modbus register untuk kontak input + SetContactModbusargs modbusArgs = gson.fromJson(req.args(), SetContactModbusargs.class); + if (modbusArgs.getContactID()>=0){ + ContactInputData contactInput = Main.db.GetContactInputData(modbusArgs.getContactID()); + if (contactInput != null) { + if (modbusArgs.getEnabled()){ + contactInput.EnableModbus = true; + contactInput.ModbusRegister = modbusArgs.getRegisterID(); + } else { + // jika register tidak valid, set EnableModbus ke false + contactInput.EnableModbus = false; + contactInput.ModbusRegister = -1; // atau nilai yang sesuai untuk menandakan tidak ada register + } + + Main.db.Update_ContactInputData(contactInput); + ctx.send(new webResponse("SET_CONTACT_MODBUS", "Contact Modbus register updated successfully.")); + } else { + Logger.error("Contact input not found for ID: {}", modbusArgs.getContactID()); + ctx.send(new webResponse("ERROR", "Contact input not found")); + } + } else { + Logger.error("Invalid contact ID: {}", modbusArgs.contact()); + ctx.send(new webResponse("ERROR", "Invalid contact ID")); + } + + + break; + case "SET_CONTACT_VX3K": + // ganti VX3K register untuk kontak input + SetContactVX3Kargs vx3kArgs = gson.fromJson(req.args(), SetContactVX3Kargs.class); + if (vx3kArgs.getContactID()>=0){ + ContactInputData contactInput = Main.db.GetContactInputData(vx3kArgs.getContactID()); + if (contactInput != null) { + if (vx3kArgs.getEnabled()){ + contactInput.EnableVX3K = true; + contactInput.VX3KFrameID = vx3kArgs.getFrameID(); + contactInput.VX3KContactID = vx3kArgs.getRelayID(); + } else { + // jika FrameID atau RelayID tidak valid, set EnableVX3K ke false + contactInput.EnableVX3K = false; + contactInput.VX3KFrameID = -1; // atau nilai + contactInput.VX3KContactID = -1; // yang sesuai untuk menandakan tidak ada VX3K + } + + Main.db.Update_ContactInputData(contactInput); + ctx.send(new webResponse("SET_CONTACT_VX3K", "Contact VX3K settings updated successfully.")); + } else { + Logger.error("Contact input not found for ID: {}", vx3kArgs.getContactID()); + ctx.send(new webResponse("ERROR", "Contact input not found")); + } + } else { + Logger.error("Invalid contact ID: {}", vx3kArgs.contact()); + ctx.send(new webResponse("ERROR", "Invalid contact ID")); + } + break; + case "SET_CONTACT_MQTT": + // ganti MQTT untuk kontak input + SetContactMqttargs mqttArgs = gson.fromJson(req.args(), SetContactMqttargs.class); + if (mqttArgs.getContactID()>=0){ + ContactInputData contactInput = Main.db.GetContactInputData(mqttArgs.getContactID()); + if (contactInput != null) { + contactInput.EnableMQTT = mqttArgs.getEnabled(); + Main.db.Update_ContactInputData(contactInput); + ctx.send(new webResponse("SET_CONTACT_MQTT", "Contact MQTT settings updated successfully.")); + } else { + Logger.error("Contact input not found for ID: {}", mqttArgs.getContactID()); + ctx.send(new webResponse("ERROR", "Contact input not found")); + } + } else { + Logger.error("Invalid contact ID: {}", mqttArgs.contact()); + ctx.send(new webResponse("ERROR", "Invalid contact ID")); + } + break; } } } catch (Exception e){