diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
deleted file mode 100644
index 04d44cb..0000000
--- a/.idea/jsLibraryMappings.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Html/html/index.html b/Html/html/index.html
index 09ddc22..834bd2a 100644
--- a/Html/html/index.html
+++ b/Html/html/index.html
@@ -55,7 +55,6 @@
No Status
diff --git a/Html/html/index.js b/Html/html/index.js
index 9719dd3..4a4ea2e 100644
--- a/Html/html/index.js
+++ b/Html/html/index.js
@@ -76,9 +76,9 @@ function initialize_socketio(){
console.log("Socket.io Connection error "+error);
});
+
socketio.on("message",(data)=>{
let dx = JSON.parse(data);
- //console.log("Received data from server: "+data);
process_command(dx);
});
}
@@ -291,7 +291,6 @@ function send_get_max_zoom(){
} else if (socketio){
if (socketio.connected){
socketio.emit("message",cmd);
- console.log("get_max_zoom sent using socketio")
} else console.log("Socket.io is not connected");
}
@@ -552,7 +551,6 @@ function set_volumeoutput(value){
function set_pan_speed(value){
pan_speed = value;
- console.log("set_pan_speed "+value);
clearpan();
let classvalue = "btn btn-dark btn-sm";
switch(pan_speed){
@@ -574,7 +572,6 @@ function set_pan_speed(value){
function set_tilt_speed(value){
tilt_speed = value;
- console.log("set_tilt_speed "+value);
cleartilt();
let classvalue = "btn btn-dark btn-sm";
switch (tilt_speed){
@@ -631,10 +628,10 @@ function process_command(dx){
}
break;
case "SET VOLUME":
- console.log("Set Volume: "+dx.data);
+ //console.log("Set Volume: "+dx.data);
break;
case "GET VOLUME":
- console.log("Get Volume: "+dx.data);
+ //console.log("Get Volume: "+dx.data);
$('#customRange').val(dx.data);
break;
case "GET MAX ZOOM":
@@ -646,46 +643,46 @@ function process_command(dx){
$zoom.val(dx.data);
break;
case "GET RESOLUTION":
- console.log("Get Resolution: "+dx.data);
+ //console.log("Get Resolution: "+dx.data);
break;
case "PAN LEFT":
- console.log("Pan Left");
+ //console.log("Pan Left");
break;
case "PAN RIGHT":
- console.log("Pan Right");
+ //console.log("Pan Right");
break;
case "TILT UP":
- console.log("Tilt Up");
+ //console.log("Tilt Up");
break;
case "TILT DOWN":
- console.log("Tilt Down");
+ //console.log("Tilt Down");
break;
case "STOP MOVEMENT":
- console.log("Stop Movement");
+ //console.log("Stop Movement");
break;
case "SET ZOOM":
- console.log("Set Zoom: "+dx.data);
+ //console.log("Set Zoom: "+dx.data);
break;
case "PLAY AUDIO":
- console.log("Play Audio: "+dx.data);
+ //console.log("Play Audio: "+dx.data);
if (dx.data.startsWith("Failed")){
alert(dx.data);
} else $('#status_player').html("Playing Audio "+dx.data);
break;
case "STOP AUDIO":
- console.log("Stop Audio");
+ //console.log("Stop Audio");
document.getElementById("status_player").innerHTML = "Stop Playback";
break;
case 'SET VIDEO QUALITY':
- console.log("Set Video Quality: "+dx.data);
+ //console.log("Set Video Quality: "+dx.data);
break;
case "MUTE":
- console.log("Mute");
+ //console.log("Mute");
$mute.prop("className", "btn-mute hide");
$unmute.prop("className", "btn-mute show");
break;
case "UNMUTE":
- console.log("Unmute");
+ //console.log("Unmute");
$mute.prop("className", "btn-mute show");
$unmute.prop("className", "btn-mute hide");
break;
@@ -698,9 +695,11 @@ function process_command(dx){
if (systeminfo.cpu_temperature && systeminfo.cpu_temperature.length>0) $('#cpu_temperature').html(`${systeminfo.cpu_temperature} °C`);
if (systeminfo.cpu && systeminfo.cpu.length>0) $('#cpu_usage').html(`${systeminfo.cpu} %`);
if (systeminfo.ram_usage && systeminfo.ram_usage.length>0) $('#ram_usage').html(`${systeminfo.ram_usage} %`);
+ if (systeminfo.end0_TX && systeminfo.end0_TX.length>0) $('#ethernet_TX').html(systeminfo.end0_TX);
+ if (systeminfo.end0_RX && systeminfo.end0_RX.length>0) $('#ethernet_RX').html(systeminfo.end0_RX);
break;
case "GET AUDIOFILES":
- console.log("Get Audio Files: "+dx.data);
+ //console.log("Get Audio Files: "+dx.data);
let audiofiles = JSON.parse(dx.data);
if (audiofiles.preset1 && audiofiles.preset1.length>0 && audiofiles.preset1!== "null") {
files[0] = audiofiles.preset1;
diff --git a/pom.xml b/pom.xml
index 5eb114f..db1e03e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,13 @@
id.co.gtc
BirdStrikeSoetta
1.0-SNAPSHOT
+
+
+ Maven Repository
+ mvnrepository
+ https://mvnrepository.com/
+
+
@@ -111,6 +118,14 @@
org.bytedeco
ffmpeg-platform
+
+ org.bytedeco
+ flandmark
+
+
+ org.bytedeco
+ flandmark-platform
+
@@ -189,20 +204,11 @@
linux-x86_64
-->
-
-
com.corundumstudio.socketio
netty-socketio
- 2.0.11
+ 2.0.12
-
-
- org.slf4j
- slf4j-simple
- 2.0.16
-
-
io.javalin
javalin
diff --git a/src/main/java/Camera/PanTiltController.java b/src/main/java/Camera/PanTiltController.java
index bfae9c5..a286155 100644
--- a/src/main/java/Camera/PanTiltController.java
+++ b/src/main/java/Camera/PanTiltController.java
@@ -1,6 +1,7 @@
package Camera;
import com.fazecast.jSerialComm.SerialPort;
+import id.co.gtc.Main;
import org.tinylog.Logger;
@@ -40,9 +41,6 @@ public class PanTiltController {
} else Logger.info("Serial Port {} not found", portname);
} else Logger.info("No Serial Port found");
-
-
-
}
/**
@@ -53,6 +51,14 @@ public class PanTiltController {
Logger.info("Serial Port closed");
}
+ /**
+ * Check if Serial Port is open
+ * @return true if open, false otherwise
+ */
+ public boolean isOpen(){
+ return serialPort != null && serialPort.isOpen();
+ }
+
/**
* Stop Pan Tilt Movement
*/
@@ -60,7 +66,12 @@ public class PanTiltController {
byte[] command = new byte[]{0, cameraid, 0, 0, 0, 0, 0};
command[6] = Checksum(command); // add checksum
command[0] = (byte) 0xFF; // add synchronization byte
- if (serialPort!=null && serialPort.isOpen()) serialPort.writeBytes(command, command.length);
+ if (isOpen()) {
+ Main.Max485Direction(true);
+ serialPort.writeBytes(command, command.length);
+ Main.Max485Direction(false);
+ Main.Blink_LedPanTilt();
+ }
}
/**
@@ -74,7 +85,12 @@ public class PanTiltController {
byte[] command = new byte[]{0, cameraid, 0, 4, speed, 0, 0};
command[6] = Checksum(command); // add checksum
command[0] = (byte) 0xFF; // add synchronization byte
- if (serialPort!=null && serialPort.isOpen()) serialPort.writeBytes(command, command.length);
+ if (isOpen()) {
+ Main.Max485Direction(true);
+ serialPort.writeBytes(command, command.length);
+ Main.Max485Direction(false);
+ Main.Blink_LedPanTilt();
+ }
}
/**
@@ -88,7 +104,12 @@ public class PanTiltController {
byte[] command = new byte[]{0, cameraid, 0, 2, speed, 0, 0};
command[6] = Checksum(command); // add checksum
command[0] = (byte) 0xFF; // add synchronization byte
- if (serialPort!=null && serialPort.isOpen()) serialPort.writeBytes(command, command.length);
+ if (isOpen()) {
+ Main.Max485Direction(true);
+ serialPort.writeBytes(command, command.length);
+ Main.Max485Direction(false);
+ Main.Blink_LedPanTilt();
+ }
}
/**
@@ -102,7 +123,12 @@ public class PanTiltController {
byte[] command = new byte[]{0, cameraid, 0, 8, speed, 0, 0};
command[6] = Checksum(command); // add checksum
command[0] = (byte) 0xFF; // add synchronization byte
- if (serialPort!=null && serialPort.isOpen()) serialPort.writeBytes(command, command.length);
+ if (isOpen()) {
+ Main.Max485Direction(true);
+ serialPort.writeBytes(command, command.length);
+ Main.Max485Direction(false);
+ Main.Blink_LedPanTilt();
+ }
}
/**
@@ -116,7 +142,12 @@ public class PanTiltController {
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
command[6] = Checksum(command); // add checksum
command[0] = (byte) 0xFF; // add synchronization byte
- if (serialPort!=null && serialPort.isOpen()) serialPort.writeBytes(command, command.length);
+ if (isOpen()) {
+ Main.Max485Direction(true);
+ serialPort.writeBytes(command, command.length);
+ Main.Max485Direction(false);
+ Main.Blink_LedPanTilt();
+ }
}
/**
diff --git a/src/main/java/Camera/RtspGrabber.java b/src/main/java/Camera/RtspGrabber.java
index c5d62b4..0f25b26 100644
--- a/src/main/java/Camera/RtspGrabber.java
+++ b/src/main/java/Camera/RtspGrabber.java
@@ -111,11 +111,11 @@ public class RtspGrabber {
}
public String LQStreamingStatus(){
- return gson.toJson(new String[]{String.valueOf(LQWidth), String.valueOf(LQHeight) , String.valueOf(grabbingTask.getCaptureFPS())});
+ return gson.toJson(new String[]{String.valueOf(LQWidth), String.valueOf(LQHeight) , String.valueOf(grabbingTask!=null ? grabbingTask.getCaptureFPS():"0")});
}
public String HQStreamingStatus(){
- return gson.toJson(new String[]{String.valueOf(HQWidth), String.valueOf(HQHeight) , String.valueOf(grabbingTask.getCaptureFPS())});
+ return gson.toJson(new String[]{String.valueOf(HQWidth), String.valueOf(HQHeight) , String.valueOf(grabbingTask!=null ? grabbingTask.getCaptureFPS(): "0")});
}
@NotNull
diff --git a/src/main/java/Camera/VapixProtocol.java b/src/main/java/Camera/VapixProtocol.java
index 1aea7e3..d86dd0b 100644
--- a/src/main/java/Camera/VapixProtocol.java
+++ b/src/main/java/Camera/VapixProtocol.java
@@ -1,5 +1,6 @@
package Camera;
+import lombok.Getter;
import org.tinylog.Logger;
import java.net.http.HttpClient;
@@ -27,7 +28,7 @@ public class VapixProtocol {
private String[] ImageResolutions = new String[0];
private String[] ImageFormats = new String[0];
private int CurrentZoomValue = 0;
-
+ @Getter private boolean successQuery = false;
/**
* Create a new VapixProtocol object
* @param ip The IP address of the camera
@@ -83,6 +84,7 @@ public class VapixProtocol {
if (ValidString(value)) ImageFormats = value.split(",");
//Logger.info("Format: "+value);
}
+ successQuery = true;
}
}
diff --git a/src/main/java/Other/SomeCodes.java b/src/main/java/Other/SomeCodes.java
index cb573fd..f778ab6 100644
--- a/src/main/java/Other/SomeCodes.java
+++ b/src/main/java/Other/SomeCodes.java
@@ -44,6 +44,9 @@ public class SomeCodes {
public static boolean useOpenCL;
private static final Base64.Encoder base64encoder = java.util.Base64.getEncoder();
public static final Gson gson = new Gson();
+ public static final double KB_threshold = 1024.0;
+ public static final double MB_threshold = 1024.0 * 1024.0;
+ public static final double GB_threshold = 1024.0 * 1024.0 * 1024.0;
public static String[] GetAudioFiles(){
try{
diff --git a/src/main/java/SBC/GPIO.java b/src/main/java/SBC/GPIO.java
index 1deadd4..62c8b7f 100644
--- a/src/main/java/SBC/GPIO.java
+++ b/src/main/java/SBC/GPIO.java
@@ -1,6 +1,7 @@
package SBC;
import com.sun.jna.Platform;
+import org.jetbrains.annotations.NotNull;
import org.tinylog.Logger;
import java.nio.file.Files;
@@ -8,7 +9,7 @@ import java.nio.file.Path;
public class GPIO {
- private static final Path gpioPath = Path.of("/sys/class/gpio");
+ public static final Path gpioPath = Path.of("/sys/class/gpio");
private static final Path gpioExportPath = Path.of("/sys/class/gpio/export");
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
@@ -31,8 +32,8 @@ public class GPIO {
* @param pin GPIO pin number
* @return true if the pin is already exported
*/
- public static boolean GpioPinExists(int pin){
- Path pinPath = gpioPath.resolve("gpio"+pin);
+ public static boolean GpioPinExists(@NotNull RaspberryPi5BPins pin){
+ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber);
return pinPath.toFile().isDirectory();
}
@@ -41,15 +42,15 @@ public class GPIO {
* @param pin GPIO pin number
* @return true if the pin is successfully exported
*/
- public static boolean ExportPin(int pin){
+ public static boolean ExportPin(@NotNull RaspberryPi5BPins pin){
try{
if (Files.isWritable(gpioExportPath)){
- Files.write(gpioExportPath, String.valueOf(pin).getBytes());
- Logger.info("Pin "+pin+" exported");
+ Files.write(gpioExportPath, String.valueOf(pin.gpionumber).getBytes());
+ Logger.info("Pin "+pin.pin+" exported");
return GpioPinExists(pin);
} else Logger.error("GPIO export path is not writable");
} catch (Exception e){
- Logger.error("Failed to export pin: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to export pin: "+pin.pin+", Message: "+e.getMessage());
}
return false;
}
@@ -59,14 +60,14 @@ public class GPIO {
* @param pin GPIO pin number
* @return true if the pin is successfully unexported
*/
- public static boolean UnexportPin(int pin){
+ public static boolean UnexportPin(@NotNull RaspberryPi5BPins pin){
if (Files.isWritable(gpioUnexportPath)){
try{
- Files.write(gpioUnexportPath, String.valueOf(pin).getBytes());
- Logger.info("Pin "+pin+" unexported");
+ Files.write(gpioUnexportPath, String.valueOf(pin.gpionumber).getBytes());
+ Logger.info("Pin "+pin.pin+" unexported");
return true;
} catch (Exception e){
- Logger.error("Failed to unexport pin: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to unexport pin: "+pin.pin+", Message: "+e.getMessage());
}
} else Logger.error("GPIO unexport path is not writable");
@@ -78,17 +79,17 @@ public class GPIO {
* @param pin GPIO pin number
* @return "in" if the pin is input, "out" if the pin is output, "unknown" if the direction is unknown
*/
- public static String GetPinDirection(int pin){
- Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
+ public static String GetPinDirection(@NotNull RaspberryPi5BPins pin){
+ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction");
if (pinPath.toFile().isFile()){
if (Files.isReadable(pinPath)){
try{
return Files.readString(pinPath).trim();
} catch (Exception e){
- Logger.error("Failed to read pin direction: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to read pin direction: "+pin.pin+", Message: "+e.getMessage());
}
- } else Logger.error("Pin direction file is not readable: "+pin);
- } else Logger.error("Pin direction file not found: "+pin);
+ } else Logger.error("Pin direction file is not readable: "+pin.pin);
+ } else Logger.error("Pin direction file not found: "+pin.pin);
return "unknown";
}
@@ -98,22 +99,22 @@ public class GPIO {
* @param direction "in" for input, "out" for output
* @return true if the direction is successfully set
*/
- public static boolean SetPinDirection(int pin, String direction){
- Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
+ public static boolean SetPinDirection(@NotNull RaspberryPi5BPins pin, String direction){
+ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction");
if (pinPath.toFile().isFile()){
if (Files.isWritable(pinPath)){
direction = direction.trim().toLowerCase();
if ("in".equals(direction) || "out".equals(direction)){
try{
Files.write(pinPath, direction.getBytes());
- Logger.info("Pin "+pin+" direction set to "+direction);
+ Logger.info("Pin "+pin.pin+" direction set to "+direction);
return true;
} catch (Exception e){
- Logger.error("Failed to set pin direction: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to set pin direction: "+pin.pin+", Message: "+e.getMessage());
}
} else Logger.error("Invalid direction: "+direction);
- } else Logger.error("Pin direction file is not writable: "+pin);
- } else Logger.error("Pin direction file not found: "+pin);
+ } else Logger.error("Pin direction file is not writable: "+pin.pin);
+ } else Logger.error("Pin direction file not found: "+pin.pin);
return false;
}
@@ -123,19 +124,19 @@ public class GPIO {
* @param isON true to set the pin value to 1, false to set the pin value to 0
* @return true if the value is successfully set
*/
- public static boolean SetValue(int pin, boolean isON){
- Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
+ public static boolean SetValue(@NotNull RaspberryPi5BPins pin, boolean isON){
+ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value");
if (pinPath.toFile().isFile()){
if (Files.isWritable(pinPath)){
try{
Files.write(pinPath, isON?"1".getBytes():"0".getBytes());
- Logger.info("Pin "+pin+" value set to "+(isON?"1":"0"));
+ Logger.info("Pin "+pin.pin+" value set to "+(isON?"1":"0"));
return true;
} catch (Exception e){
- Logger.error("Failed to set pin value: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to set pin value: "+pin.pin+", Message: "+e.getMessage());
}
- } else Logger.error("Pin value file is not writable: "+pin);
- } else Logger.error("Pin value file not found: "+pin);
+ } else Logger.error("Pin value file is not writable: "+pin.pin);
+ } else Logger.error("Pin value file not found: "+pin.pin);
return false;
}
@@ -144,17 +145,17 @@ public class GPIO {
* @param pin GPIO pin number
* @return "1" if the pin value is 1, "0" if the pin value is 0, "unknown" if the value is unknown
*/
- public static String GetValue(int pin){
- Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
+ public static String GetValue(@NotNull RaspberryPi5BPins pin){
+ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value");
if (pinPath.toFile().isFile()){
if (Files.isReadable(pinPath)){
try{
return Files.readString(pinPath).trim();
} catch (Exception e){
- Logger.error("Failed to read pin value: "+pin+", Message: "+e.getMessage());
+ Logger.error("Failed to read pin value: "+pin.pin+", Message: "+e.getMessage());
}
- } else Logger.error("Pin value file is not readable: "+pin);
- } else Logger.error("Pin value file not found: "+pin);
+ } else Logger.error("Pin value file is not readable: "+pin.pin);
+ } else Logger.error("Pin value file not found: "+pin.pin);
return "unknown";
}
}
diff --git a/src/main/java/SBC/RaspberryPi5BPins.java b/src/main/java/SBC/RaspberryPi5BPins.java
new file mode 100644
index 0000000..3400379
--- /dev/null
+++ b/src/main/java/SBC/RaspberryPi5BPins.java
@@ -0,0 +1,42 @@
+package SBC;
+
+public enum RaspberryPi5BPins {
+ Pin03(3,"GPIO2/SDA", 573),
+ Pin05(5,"GPIO3/SCL", 574),
+ Pin07(7,"GPIO4/GPCLK0", 575),
+ Pin08(8,"GPIO14/TXD", 585),
+ Pin10(10,"GPIO15/RXD", 586),
+ Pin11(11,"GPIO17", 588),
+ Pin12(12,"GPIO18/PCMCLK", 589),
+ Pin13(13,"GPIO27", 598),
+ Pin15(15,"GPIO22", 593),
+ Pin16(16,"GPIO23", 594),
+ Pin18(18,"GPIO24", 595),
+ Pin19(19,"GPIO10/MOSI", 581),
+ Pin21(21,"GPIO9/MISO", 580),
+ Pin22(22,"GPIO25", 596),
+ Pin23(23,"GPIO11/SCLK", 582),
+ Pin24(24,"GPIO8/CE0", 579),
+ Pin26(26,"GPIO7/CE1", 578),
+ Pin27(27,"GPIO0/IDSD", 587),
+ Pin28(28,"GPIO1/IDSC", 587),
+ Pin29(29,"GPIO5", 576),
+ Pin31(31,"GPIO6", 577),
+ Pin32(32,"GPIO12/PWM0", 583),
+ Pin33(33,"GPIO13/PWM1", 584),
+ Pin35(35,"GPIO19/PCMFS", 590),
+ Pin36(36,"GPIO16", 587),
+ Pin37(37,"GPIO26", 597),
+ Pin38(38,"GPIO20/PCMDIN", 591),
+ Pin40(40,"GPIO21/PCMDOUT", 592);
+
+ public final int pin;
+ public final String name;
+ public final int gpionumber;
+
+ RaspberryPi5BPins(int pin, String name, int gpionumber){
+ this.pin = pin;
+ this.name = name;
+ this.gpionumber = gpionumber;
+ }
+}
diff --git a/src/main/java/Web/WebServer.java b/src/main/java/Web/WebServer.java
index e738663..f4f9306 100644
--- a/src/main/java/Web/WebServer.java
+++ b/src/main/java/Web/WebServer.java
@@ -2,7 +2,10 @@ package Web;
import Other.SomeCodes;
import com.corundumstudio.socketio.Configuration;
+import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
+import com.corundumstudio.socketio.listener.ConnectListener;
+import com.corundumstudio.socketio.listener.DisconnectListener;
import io.javalin.Javalin;
import io.javalin.http.UploadedFile;
import io.javalin.util.FileUtil;
@@ -12,10 +15,7 @@ import lombok.Getter;
import lombok.Setter;
import org.tinylog.Logger;
-import java.util.List;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static Other.SomeCodes.*;
@@ -30,6 +30,8 @@ public class WebServer {
private final Set connectedWebsocketClients = ConcurrentHashMap.newKeySet();
private final SocketIOServer socketServer;
private final Configuration socketConfig;
+ private final HashMap socketIOClients = new HashMap<>();
+
public WebServer(WebsocketEvent event, String webusername, String webpassword){
this.webusername = webusername;
this.webpassword = webpassword;
@@ -178,10 +180,13 @@ public class WebServer {
ctx.redirect("/login.html");
});
+ /*
+ WebSocket Communication
+ This is temporary, later must choose either WebSocket or SocketIO
+ */
app.ws("/ws", ws -> {
ws.onConnect(connectws);
ws.onClose(closews);
- //ws.onError(errorws);
ws.onMessage(ctx -> {
try{
//Logger.info("WebSocket message {}", ctx.message());
@@ -200,16 +205,16 @@ public class WebServer {
});
+ /*
+ SocketIO Communication
+ This is temporary, later must choose either WebSocket or SocketIO
+ */
socketConfig = new Configuration();
socketConfig.setHostname("0.0.0.0");
socketConfig.setPort(3001);
socketServer = new SocketIOServer(socketConfig);
- socketServer.addConnectListener(client -> {
- Logger.info("SocketIO connected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
- });
- socketServer.addDisconnectListener(client -> {
- Logger.info("SocketIO disconnected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
- });
+ socketServer.addConnectListener(connectListener);
+ socketServer.addDisconnectListener(disconnectListener);
socketServer.addNamespace("/socketio").addEventListener("message", String.class, (client, data, ackSender) -> {
//Logger.info("SocketIO message from namespace /socketio from {}: {}", client.getRemoteAddress(), data);
WebsocketCommand command = gson.fromJson(data, WebsocketCommand.class);
@@ -232,6 +237,7 @@ public class WebServer {
.stream()
.filter(ws -> ws.session.isOpen())
.forEach(ws -> ws.send(obj));
+ socketIOClients.forEach((key, client) -> client.sendEvent("message", gson.toJson(obj)));
}
/**
@@ -241,7 +247,6 @@ public class WebServer {
*/
public void Start(String localip, int port){
try{
- connectedWebsocketClients.forEach(WsContext::closeSession);
app.start(localip, port);
Logger.info("Web server started at {}:{}", localip, port);
socketServer.start();
@@ -256,8 +261,12 @@ public class WebServer {
*/
public void Stop(){
try{
+ connectedWebsocketClients.forEach(WsContext::closeSession);
+ connectedWebsocketClients.clear();
app.stop();
Logger.info("Web server stopped");
+ socketIOClients.forEach((key, client) -> client.disconnect());
+ socketIOClients.clear();
socketServer.stop();
Logger.info("SocketIO server stopped");
} catch (JavalinException e){
@@ -276,7 +285,16 @@ public class WebServer {
connectedWebsocketClients.remove(ws);
};
- //WsErrorHandler errorws = ws -> Logger.error("WebSocket error from {}, error {}", ws.host(), ws.error());
+ ConnectListener connectListener = client -> {
+ Logger.info("SocketIO connected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
+ socketIOClients.put(client.getSessionId().toString(), client);
+ };
+
+ DisconnectListener disconnectListener = client -> {
+ Logger.info("SocketIO disconnected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
+ socketIOClients.remove(client.getSessionId().toString());
+ };
+
diff --git a/src/main/java/id/co/gtc/Main.java b/src/main/java/id/co/gtc/Main.java
index f14ed88..909b13d 100644
--- a/src/main/java/id/co/gtc/Main.java
+++ b/src/main/java/id/co/gtc/Main.java
@@ -8,9 +8,7 @@ import Camera.PanTiltController;
import Camera.RtspGrabber;
import Camera.VapixProtocol;
import Other.SomeCodes;
-import SBC.ProcessorStatus;
-import SBC.RamInformation;
-import SBC.SystemInformation;
+import SBC.*;
import Web.*;
import com.google.gson.JsonObject;
import org.bytedeco.opencv.global.opencv_core;
@@ -19,6 +17,8 @@ import org.tinylog.Logger;
import java.io.File;
import java.nio.file.Path;
import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import static Other.SomeCodes.*;
@@ -34,6 +34,16 @@ public class Main {
private static RamInformation ramInformation;
private static ProcessorStatus[] previousCpuInfo;
private static final Map cpuUsage = new HashMap<>();
+ private static NetworkTransmitReceiveInfo[] previousNetworkInfo;
+ private static final Map networkTX = new HashMap<>();
+ private static final Map networkRX = new HashMap<>();
+ private static RaspberryPi5BPins AmplifierPower = null;
+ private static RaspberryPi5BPins LedWeb = null;
+ private static RaspberryPi5BPins LedIpCamera = null;
+ private static RaspberryPi5BPins LedPanTilt = null;
+ private static RaspberryPi5BPins Max485Direction = null;
+
+ private static ExecutorService gpioExecutor = null;
// Application start from here
public static void main(String[] args) {
@@ -44,8 +54,10 @@ public class Main {
if (panTiltController!=null) panTiltController.Close();
if (vapixProtocol!=null) vapixProtocol.Close();
if (timer!=null) timer.cancel();
+ if (gpioExecutor!=null) gpioExecutor.shutdown();
}));
+ init_gpio();
init_system_monitoring();
init_properties();
@@ -58,6 +70,70 @@ public class Main {
init_rtspgrabber();
}
+ private static void init_gpio(){
+ if (GPIO.HaveGPIO()){
+ gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
+ AmplifierPower = InitializePin(RaspberryPi5BPins.Pin13, true);
+ LedWeb = InitializePin(RaspberryPi5BPins.Pin15, true);
+ LedIpCamera = InitializePin(RaspberryPi5BPins.Pin19, true);
+ LedPanTilt = InitializePin(RaspberryPi5BPins.Pin21, true);
+ Max485Direction = InitializePin(RaspberryPi5BPins.Pin23, true);
+ }
+ }
+
+
+ @SuppressWarnings("SameParameterValue")
+ private static RaspberryPi5BPins InitializePin(RaspberryPi5BPins pin, boolean isOutput){
+ boolean exported = false;
+ if (GPIO.GpioPinExists(pin)){
+ exported = true;
+ } else {
+ if (GPIO.ExportPin(pin)){
+ exported = true;
+ }
+ }
+
+ if (exported){
+ if (GPIO.SetPinDirection(pin, isOutput?"out":"in")){
+ return pin;
+ }
+ }
+ return null;
+ }
+
+ // dipanggil di PanTiltController, maka perlu public dan static
+ public static void Max485Direction(boolean isTransmit){
+ if (Max485Direction!=null){
+ GPIO.SetValue(Max485Direction, isTransmit);
+ }
+ }
+
+ // dipanggil di PanTiltController, maka perlu public dan static
+ public static void Blink_LedPanTilt(){
+ Blink(LedPanTilt);
+ }
+
+ private static void AmplifierControl(boolean isON){
+ if (AmplifierPower!=null){
+ GPIO.SetValue(AmplifierPower, isON);
+ }
+ }
+
+ private static void Blink(RaspberryPi5BPins pin){
+ if (pin!=null){
+ if (gpioExecutor!=null){
+ gpioExecutor.submit(()->{
+ GPIO.SetValue(pin, true);
+ try {
+ Thread.sleep(20);
+ } catch (InterruptedException ignored) {
+ }
+ GPIO.SetValue(pin, false);
+ });
+ }
+ }
+ }
+
private static void init_system_monitoring(){
TimerTask tt = new TimerTask() {
@Override
@@ -72,6 +148,41 @@ public class Main {
for(int ii=0;ii0){
+ if (previousNetworkInfo==null || !Objects.equals(previousNetworkInfo.length, ntri.length)){
+ previousNetworkInfo = ntri;
+ } else {
+ for(int ii=0;iivapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
if (vapixProtocol.Zoom(1, zoom)){
+ Blink(LedIpCamera);
return new WebsocketReply("ZOOM", String.valueOf(zoom));
} else return new WebsocketReply("ZOOM", "Failed to zoom");
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
@@ -326,6 +443,18 @@ public class Main {
data.addProperty(key, String.valueOf(cpuUsage.get(key)));
}
}
+ if (!networkTX.isEmpty()) {
+ for(String key : networkTX.keySet()){
+ if (key.equals("lo")) continue;
+ data.addProperty(key+"_TX", networkTX.get(key));
+ }
+ }
+ if (!networkRX.isEmpty()) {
+ for(String key : networkRX.keySet()){
+ if (key.equals("lo")) continue;
+ data.addProperty(key+"_RX", networkRX.get(key));
+ }
+ }
return new WebsocketReply("GET SYSTEM INFO", data.toString());
default:
return new WebsocketReply("UNKNOWN COMMAND", command.command);