commit 18/06/2025

This commit is contained in:
2025-06-18 12:42:28 +07:00
parent c617157a0b
commit 3ed1123d1a
12 changed files with 191 additions and 46 deletions

View File

@@ -39,8 +39,24 @@ public class Main {
mailsender = new SMTPSender(config.getEmail_SMTPServer(), config.getEmail_SMTPPort(), true, config.getEmail_SMTPUsername(), config.getEmail_SMTPPassword()); mailsender = new SMTPSender(config.getEmail_SMTPServer(), config.getEmail_SMTPPort(), true, config.getEmail_SMTPUsername(), config.getEmail_SMTPPassword());
// initialize Modbus TCP Server // initialize Modbus TCP Server
modbusServer = new ModbusTCPServer(config.getModbus_MasterIP(), config.getModbus_Port(), 1000); modbusServer = new ModbusTCPServer("0.0.0.0", config.getModbus_Port(), 1000);
modbusServer.Start(); modbusServer.Start();
// try changing modbus register several times
/*Thread xx = new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
modbusServer.SetRegister(0, i);
modbusServer.SetRegister(1, i);
modbusServer.SetRegister(2, i);
modbusServer.SetRegister(3, i);
Thread.sleep(1000); // sleep for 1 second
}
} catch (InterruptedException e) {
Logger.error("Thread interrupted: {}", e.getMessage());
}
});
xx.setName("Modbus tester");
xx.start();*/
// Initialize the web server // Initialize the web server
webServer = new WebServer(); webServer = new WebServer();
@@ -106,14 +122,14 @@ public class Main {
}, },
new gpio.PinInfo(11, "Relay 1"), new gpio.PinInfo(11, db.GetContactInputDataDescription(1,"Relay 1")),
new gpio.PinInfo(12, "Relay 2"), new gpio.PinInfo(12, db.GetContactInputDataDescription(2,"Relay 2")),
new gpio.PinInfo(13, "Relay 3"), new gpio.PinInfo(13, db.GetContactInputDataDescription(3,"Relay 3")),
new gpio.PinInfo(14, "Relay 4"), new gpio.PinInfo(14, db.GetContactInputDataDescription(4,"Relay 4")),
new gpio.PinInfo(16, "Relay 5"), new gpio.PinInfo(16, db.GetContactInputDataDescription(5,"Relay 5")),
new gpio.PinInfo(15, "Relay 6"), new gpio.PinInfo(15, db.GetContactInputDataDescription(6,"Relay 6")),
new gpio.PinInfo(199, "Relay 7"), new gpio.PinInfo(199, db.GetContactInputDataDescription(7,"Relay 7")),
new gpio.PinInfo(198, "Relay 8") new gpio.PinInfo(198, db.GetContactInputDataDescription(8,"Relay 8"))
); );
// initialize the MQTT client // initialize the MQTT client

View File

@@ -1,3 +1,5 @@
package additional;
import com.google.gson.Gson; import com.google.gson.Gson;
@@ -6,7 +8,9 @@ public class Somecodes {
public static String currentdirectory = System.getProperty("user.dir"); public static String currentdirectory = System.getProperty("user.dir");
public static Gson gson = new Gson(); public static Gson gson = new Gson();
public static boolean ValidString(String string) {
return string != null && !string.isBlank();
}

View File

@@ -1,3 +1,4 @@
import additional.Somecodes;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.tinylog.Logger; import org.tinylog.Logger;

View File

@@ -1,5 +1,6 @@
package database; package database;
import lombok.NonNull;
import org.tinylog.Logger; import org.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -163,6 +164,20 @@ public class Database {
return contactInputDataList.stream().filter(x -> x.getContactID() == contactID).findFirst().orElse(null); return contactInputDataList.stream().filter(x -> x.getContactID() == contactID).findFirst().orElse(null);
} }
/**
* Get ContactInputData description by ID
* @param contactID ID to get
* @param defaultname Default name to return if ContactInputData not found
* @return Description of ContactInputData if exists, or defaultname if not exists
*/
public String GetContactInputDataDescription(int contactID, @NonNull String defaultname){
ContactInputData contactInputData = GetContactInputData(contactID);
if (contactInputData != null) {
return contactInputData.getDescription();
}
return defaultname;
}
/** /**
* Get ContactInputData by description * Get ContactInputData by description
* @param description Description to get * @param description Description to get

View File

@@ -0,0 +1,35 @@
console.log("Initializing websocket");
if (window.socket==null) {
window.socket = new WebSocket("ws://" + location.host + "/ws");
console.log("creating window.socket");
} else {
console.log("window.socket already exists");
}
socket.onopen = () => {
console.log("WebSocket connected");
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Received from server:", data);
};
socket.onerror = (err) => {
console.error("WebSocket error:", err);
};
socket.onclose = () => {
console.log("WebSocket closed");
};
window.send_data = function(value){
if (socket.readyState === WebSocket.OPEN){
socket.send(value);
console.log("Sent data : "+value);
} else {
setTimeout(() => send_data(value),50)
console.log("Failed to send_data, socket readyState = "+socket.readyState);
}
}

View File

@@ -0,0 +1,5 @@
document.addEventListener("DOMContentLoaded", function () {
console.log("Index page loaded");
send_data("Hello from Index.html")
});

View File

@@ -1,22 +1,5 @@
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
const socket = new WebSocket("ws://" + location.host + "/ws"); console.log("Setting page loaded");
send_data("Hello from setting.js");
socket.onopen = () => {
console.log("WebSocket connected");
const message = { type: "hello", value: 123 };
socket.send(JSON.stringify(message));
};
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Received from server:", data);
};
socket.onerror = (err) => {
console.error("WebSocket error:", err);
};
socket.onclose = () => {
console.log("WebSocket closed");
};
}); });

View File

@@ -26,7 +26,8 @@
</div> </div>
</nav> </nav>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/setting.js"></script> <script src="assets/js/connection.js"></script>
<script src="assets/js/index.js"></script>
</body> </body>
</html> </html>

View File

@@ -26,22 +26,89 @@
</div> </div>
</nav> </nav>
<div class="vstack"> <div class="vstack">
<div class="container"> <div class="card">
<div class="row"> <div class="card-body">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Server</label></div> <h4 class="card-title">SMTP Setting</h4>
<div class="col-md-6"><input class="w-100 h-100" type="text"></div> <div class="container">
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Server</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="smtpServer" placeholder="SMTP Server Address"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Port</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="smtpPort" placeholder="SMTP Port"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Username</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="smtpUsername" placeholder="SMTP Username"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Password</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="password" id="smtpPassword" placeholder="SMTP Password"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Use SSL ?</label></div>
<div class="col-md-6"><input class="h-100" type="checkbox" id="smtpSSL"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Sender Address</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="smtpSenderAddress" placeholder="Sender Email Address"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Sender Name</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="smtpSenderName" placeholder="Sender Name"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Subject</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="smtpSubject" placeholder="Email Subject"></div>
</div>
</div>
</div> </div>
<div class="row"> </div>
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Port</label></div> <div class="card">
<div class="col-md-6"><input class="w-100 h-100" type="text"></div> <div class="card-body">
<h4 class="card-title">VX-3000 Setting</h4>
<div class="container">
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">VX-3000 IP</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="vx3kIP" placeholder="Default 192.168.14.1"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">VX-3000 Port</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="vx3kPort" placeholder="Default 50050 ~ 50053"></div>
</div>
</div>
</div> </div>
<div class="row"> </div>
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Username</label></div> <div class="card">
<div class="col-md-6"><input class="w-100 h-100" type="text"></div> <div class="card-body">
</div> <h4 class="card-title">MQTT Setting</h4>
<div class="row"> <div class="container">
<div class="col-md-6"><label class="col-form-label w-100 h-100">SMTP Password</label></div> <div class="row">
<div class="col-md-6"><input class="w-100 h-100" type="text"></div> <div class="col-md-6"><label class="col-form-label w-100 h-100">Broker Address</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="text" id="mqttBrokerIP" placeholder="Broker IP"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Broker Port</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="mqttPort" placeholder="Broker Port"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Username</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="mqttUsername" placeholder="for login to Broker"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Password</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="mqttPassword" placeholder="for login to Broker"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Client ID</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="mqttClientID" placeholder="Client ID"></div>
</div>
<div class="row">
<div class="col-md-6"><label class="col-form-label w-100 h-100">Topic</label></div>
<div class="col-md-6"><input class="w-100 mt-1 mb-1" type="number" id="mqttTopic" placeholder="Topic"></div>
</div>
</div>
</div> </div>
</div> </div>
<div class="container"> <div class="container">
@@ -52,6 +119,7 @@
</div> </div>
</div> </div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script> <script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/connection.js"></script>
<script src="assets/js/setting.js"></script> <script src="assets/js/setting.js"></script>
</body> </body>

View File

@@ -33,6 +33,7 @@ public class ModbusTCPServer {
*/ */
public ModbusTCPServer(String bindAddress, int port, int holdingRegisterSize) { public ModbusTCPServer(String bindAddress, int port, int holdingRegisterSize) {
this.holdingregister = new AtomicIntegerArray(holdingRegisterSize); this.holdingregister = new AtomicIntegerArray(holdingRegisterSize);
Logger.info("Creating ModbusTCPServer at {}:{} with holding register size {}", bindAddress, port, holdingRegisterSize);
transport = NettyTcpServerTransport.create(cfg ->{ transport = NettyTcpServerTransport.create(cfg ->{
cfg.bindAddress = bindAddress; cfg.bindAddress = bindAddress;
cfg.port = port; cfg.port = port;

View File

@@ -4,6 +4,9 @@ import io.javalin.Javalin;
import lombok.Getter; import lombok.Getter;
import org.tinylog.Logger; import org.tinylog.Logger;
import static additional.Somecodes.ValidString;
import static additional.Somecodes.gson;
public class WebServer { public class WebServer {
private Javalin app; private Javalin app;
private @Getter boolean isRunning = false; private @Getter boolean isRunning = false;
@@ -44,7 +47,16 @@ public class WebServer {
ws.onMessage(ctx -> { ws.onMessage(ctx -> {
Logger.info("WebSocket message received: {}", ctx.message()); Logger.info("WebSocket message received: {}", ctx.message());
// Handle incoming messages here webRequest req = gson.fromJson(ctx.message(), webRequest.class);
if (ValidString(req.request())){
String cmd = req.request().trim().toUpperCase();
switch(cmd){
case "GET_SETTING" :
break;
}
}
}); });
ws.onClose(ctx -> { ws.onClose(ctx -> {

4
src/web/webRequest.java Normal file
View File

@@ -0,0 +1,4 @@
package web;
public record webRequest(String request, String[] args) {
}