GPIO control.
Bug fix.
This commit is contained in:
6
.idea/jsLibraryMappings.xml
generated
6
.idea/jsLibraryMappings.xml
generated
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="JavaScriptLibraryMappings">
|
|
||||||
<file url="file://$PROJECT_DIR$" libraries="{jquery.dataTables}" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -55,7 +55,6 @@
|
|||||||
<p id="streaming_status">No Status</p>
|
<p id="streaming_status">No Status</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-4 col-md-5 col-lg-5 col-xl-5">
|
<div class="col-12 col-sm-4 col-md-5 col-lg-5 col-xl-5">
|
||||||
<!-- <p id="system_information"> System Information </p>-->
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@@ -76,6 +75,18 @@
|
|||||||
<p id="ram_usage" class="padleft">0 %</p>
|
<p id="ram_usage" class="padleft">0 %</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fa-solid fa-upload icon-system"></span>
|
||||||
|
<p id="ethernet_TX" class="padleft">0 B/s</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<span class="fa-solid fa-download icon-system"></span>
|
||||||
|
<p id="ethernet_RX" class="padleft">0 B/s</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ function initialize_socketio(){
|
|||||||
console.log("Socket.io Connection error "+error);
|
console.log("Socket.io Connection error "+error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
socketio.on("message",(data)=>{
|
socketio.on("message",(data)=>{
|
||||||
let dx = JSON.parse(data);
|
let dx = JSON.parse(data);
|
||||||
//console.log("Received data from server: "+data);
|
|
||||||
process_command(dx);
|
process_command(dx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -291,7 +291,6 @@ function send_get_max_zoom(){
|
|||||||
} else if (socketio){
|
} else if (socketio){
|
||||||
if (socketio.connected){
|
if (socketio.connected){
|
||||||
socketio.emit("message",cmd);
|
socketio.emit("message",cmd);
|
||||||
console.log("get_max_zoom sent using socketio")
|
|
||||||
} else console.log("Socket.io is not connected");
|
} else console.log("Socket.io is not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +551,6 @@ function set_volumeoutput(value){
|
|||||||
|
|
||||||
function set_pan_speed(value){
|
function set_pan_speed(value){
|
||||||
pan_speed = value;
|
pan_speed = value;
|
||||||
console.log("set_pan_speed "+value);
|
|
||||||
clearpan();
|
clearpan();
|
||||||
let classvalue = "btn btn-dark btn-sm";
|
let classvalue = "btn btn-dark btn-sm";
|
||||||
switch(pan_speed){
|
switch(pan_speed){
|
||||||
@@ -574,7 +572,6 @@ function set_pan_speed(value){
|
|||||||
|
|
||||||
function set_tilt_speed(value){
|
function set_tilt_speed(value){
|
||||||
tilt_speed = value;
|
tilt_speed = value;
|
||||||
console.log("set_tilt_speed "+value);
|
|
||||||
cleartilt();
|
cleartilt();
|
||||||
let classvalue = "btn btn-dark btn-sm";
|
let classvalue = "btn btn-dark btn-sm";
|
||||||
switch (tilt_speed){
|
switch (tilt_speed){
|
||||||
@@ -631,10 +628,10 @@ function process_command(dx){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "SET VOLUME":
|
case "SET VOLUME":
|
||||||
console.log("Set Volume: "+dx.data);
|
//console.log("Set Volume: "+dx.data);
|
||||||
break;
|
break;
|
||||||
case "GET VOLUME":
|
case "GET VOLUME":
|
||||||
console.log("Get Volume: "+dx.data);
|
//console.log("Get Volume: "+dx.data);
|
||||||
$('#customRange').val(dx.data);
|
$('#customRange').val(dx.data);
|
||||||
break;
|
break;
|
||||||
case "GET MAX ZOOM":
|
case "GET MAX ZOOM":
|
||||||
@@ -646,46 +643,46 @@ function process_command(dx){
|
|||||||
$zoom.val(dx.data);
|
$zoom.val(dx.data);
|
||||||
break;
|
break;
|
||||||
case "GET RESOLUTION":
|
case "GET RESOLUTION":
|
||||||
console.log("Get Resolution: "+dx.data);
|
//console.log("Get Resolution: "+dx.data);
|
||||||
break;
|
break;
|
||||||
case "PAN LEFT":
|
case "PAN LEFT":
|
||||||
console.log("Pan Left");
|
//console.log("Pan Left");
|
||||||
break;
|
break;
|
||||||
case "PAN RIGHT":
|
case "PAN RIGHT":
|
||||||
console.log("Pan Right");
|
//console.log("Pan Right");
|
||||||
break;
|
break;
|
||||||
case "TILT UP":
|
case "TILT UP":
|
||||||
console.log("Tilt Up");
|
//console.log("Tilt Up");
|
||||||
break;
|
break;
|
||||||
case "TILT DOWN":
|
case "TILT DOWN":
|
||||||
console.log("Tilt Down");
|
//console.log("Tilt Down");
|
||||||
break;
|
break;
|
||||||
case "STOP MOVEMENT":
|
case "STOP MOVEMENT":
|
||||||
console.log("Stop Movement");
|
//console.log("Stop Movement");
|
||||||
break;
|
break;
|
||||||
case "SET ZOOM":
|
case "SET ZOOM":
|
||||||
console.log("Set Zoom: "+dx.data);
|
//console.log("Set Zoom: "+dx.data);
|
||||||
break;
|
break;
|
||||||
case "PLAY AUDIO":
|
case "PLAY AUDIO":
|
||||||
console.log("Play Audio: "+dx.data);
|
//console.log("Play Audio: "+dx.data);
|
||||||
if (dx.data.startsWith("Failed")){
|
if (dx.data.startsWith("Failed")){
|
||||||
alert(dx.data);
|
alert(dx.data);
|
||||||
} else $('#status_player').html("Playing Audio "+dx.data);
|
} else $('#status_player').html("Playing Audio "+dx.data);
|
||||||
break;
|
break;
|
||||||
case "STOP AUDIO":
|
case "STOP AUDIO":
|
||||||
console.log("Stop Audio");
|
//console.log("Stop Audio");
|
||||||
document.getElementById("status_player").innerHTML = "Stop Playback";
|
document.getElementById("status_player").innerHTML = "Stop Playback";
|
||||||
break;
|
break;
|
||||||
case 'SET VIDEO QUALITY':
|
case 'SET VIDEO QUALITY':
|
||||||
console.log("Set Video Quality: "+dx.data);
|
//console.log("Set Video Quality: "+dx.data);
|
||||||
break;
|
break;
|
||||||
case "MUTE":
|
case "MUTE":
|
||||||
console.log("Mute");
|
//console.log("Mute");
|
||||||
$mute.prop("className", "btn-mute hide");
|
$mute.prop("className", "btn-mute hide");
|
||||||
$unmute.prop("className", "btn-mute show");
|
$unmute.prop("className", "btn-mute show");
|
||||||
break;
|
break;
|
||||||
case "UNMUTE":
|
case "UNMUTE":
|
||||||
console.log("Unmute");
|
//console.log("Unmute");
|
||||||
$mute.prop("className", "btn-mute show");
|
$mute.prop("className", "btn-mute show");
|
||||||
$unmute.prop("className", "btn-mute hide");
|
$unmute.prop("className", "btn-mute hide");
|
||||||
break;
|
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_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.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.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;
|
break;
|
||||||
case "GET AUDIOFILES":
|
case "GET AUDIOFILES":
|
||||||
console.log("Get Audio Files: "+dx.data);
|
//console.log("Get Audio Files: "+dx.data);
|
||||||
let audiofiles = JSON.parse(dx.data);
|
let audiofiles = JSON.parse(dx.data);
|
||||||
if (audiofiles.preset1 && audiofiles.preset1.length>0 && audiofiles.preset1!== "null") {
|
if (audiofiles.preset1 && audiofiles.preset1.length>0 && audiofiles.preset1!== "null") {
|
||||||
files[0] = audiofiles.preset1;
|
files[0] = audiofiles.preset1;
|
||||||
|
|||||||
26
pom.xml
26
pom.xml
@@ -7,6 +7,13 @@
|
|||||||
<groupId>id.co.gtc</groupId>
|
<groupId>id.co.gtc</groupId>
|
||||||
<artifactId>BirdStrikeSoetta</artifactId>
|
<artifactId>BirdStrikeSoetta</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<name>Maven Repository</name>
|
||||||
|
<id>mvnrepository</id>
|
||||||
|
<url>https://mvnrepository.com/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -111,6 +118,14 @@
|
|||||||
<groupId>org.bytedeco</groupId>
|
<groupId>org.bytedeco</groupId>
|
||||||
<artifactId>ffmpeg-platform</artifactId>
|
<artifactId>ffmpeg-platform</artifactId>
|
||||||
</exclusion>
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>flandmark</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>flandmark-platform</artifactId>
|
||||||
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- manual tambah untuk platform windows-x86_64 -->
|
<!-- manual tambah untuk platform windows-x86_64 -->
|
||||||
@@ -189,20 +204,11 @@
|
|||||||
<classifier>linux-x86_64</classifier>
|
<classifier>linux-x86_64</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/com.corundumstudio.socketio/netty-socketio -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.corundumstudio.socketio</groupId>
|
<groupId>com.corundumstudio.socketio</groupId>
|
||||||
<artifactId>netty-socketio</artifactId>
|
<artifactId>netty-socketio</artifactId>
|
||||||
<version>2.0.11</version>
|
<version>2.0.12</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>2.0.16</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.javalin</groupId>
|
<groupId>io.javalin</groupId>
|
||||||
<artifactId>javalin</artifactId>
|
<artifactId>javalin</artifactId>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package Camera;
|
package Camera;
|
||||||
|
|
||||||
import com.fazecast.jSerialComm.SerialPort;
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import id.co.gtc.Main;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
|
||||||
@@ -40,9 +41,6 @@ public class PanTiltController {
|
|||||||
} else Logger.info("Serial Port {} not found", portname);
|
} else Logger.info("Serial Port {} not found", portname);
|
||||||
} else Logger.info("No Serial Port found");
|
} else Logger.info("No Serial Port found");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,6 +51,14 @@ public class PanTiltController {
|
|||||||
Logger.info("Serial Port closed");
|
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
|
* Stop Pan Tilt Movement
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +66,12 @@ public class PanTiltController {
|
|||||||
byte[] command = new byte[]{0, cameraid, 0, 0, 0, 0, 0};
|
byte[] command = new byte[]{0, cameraid, 0, 0, 0, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
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};
|
byte[] command = new byte[]{0, cameraid, 0, 4, speed, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
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};
|
byte[] command = new byte[]{0, cameraid, 0, 2, speed, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
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};
|
byte[] command = new byte[]{0, cameraid, 0, 8, speed, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
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};
|
byte[] command = new byte[]{0, cameraid, 0, 16, speed, 0, 0};
|
||||||
command[6] = Checksum(command); // add checksum
|
command[6] = Checksum(command); // add checksum
|
||||||
command[0] = (byte) 0xFF; // add synchronization byte
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -111,11 +111,11 @@ public class RtspGrabber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String LQStreamingStatus(){
|
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(){
|
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
|
@NotNull
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package Camera;
|
package Camera;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
@@ -27,7 +28,7 @@ public class VapixProtocol {
|
|||||||
private String[] ImageResolutions = new String[0];
|
private String[] ImageResolutions = new String[0];
|
||||||
private String[] ImageFormats = new String[0];
|
private String[] ImageFormats = new String[0];
|
||||||
private int CurrentZoomValue = 0;
|
private int CurrentZoomValue = 0;
|
||||||
|
@Getter private boolean successQuery = false;
|
||||||
/**
|
/**
|
||||||
* Create a new VapixProtocol object
|
* Create a new VapixProtocol object
|
||||||
* @param ip The IP address of the camera
|
* @param ip The IP address of the camera
|
||||||
@@ -83,6 +84,7 @@ public class VapixProtocol {
|
|||||||
if (ValidString(value)) ImageFormats = value.split(",");
|
if (ValidString(value)) ImageFormats = value.split(",");
|
||||||
//Logger.info("Format: "+value);
|
//Logger.info("Format: "+value);
|
||||||
}
|
}
|
||||||
|
successQuery = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public class SomeCodes {
|
|||||||
public static boolean useOpenCL;
|
public static boolean useOpenCL;
|
||||||
private static final Base64.Encoder base64encoder = java.util.Base64.getEncoder();
|
private static final Base64.Encoder base64encoder = java.util.Base64.getEncoder();
|
||||||
public static final Gson gson = new Gson();
|
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(){
|
public static String[] GetAudioFiles(){
|
||||||
try{
|
try{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package SBC;
|
package SBC;
|
||||||
|
|
||||||
import com.sun.jna.Platform;
|
import com.sun.jna.Platform;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@@ -8,7 +9,7 @@ import java.nio.file.Path;
|
|||||||
|
|
||||||
public class GPIO {
|
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 gpioExportPath = Path.of("/sys/class/gpio/export");
|
||||||
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
|
private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport");
|
||||||
|
|
||||||
@@ -31,8 +32,8 @@ public class GPIO {
|
|||||||
* @param pin GPIO pin number
|
* @param pin GPIO pin number
|
||||||
* @return true if the pin is already exported
|
* @return true if the pin is already exported
|
||||||
*/
|
*/
|
||||||
public static boolean GpioPinExists(int pin){
|
public static boolean GpioPinExists(@NotNull RaspberryPi5BPins pin){
|
||||||
Path pinPath = gpioPath.resolve("gpio"+pin);
|
Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber);
|
||||||
return pinPath.toFile().isDirectory();
|
return pinPath.toFile().isDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +42,15 @@ public class GPIO {
|
|||||||
* @param pin GPIO pin number
|
* @param pin GPIO pin number
|
||||||
* @return true if the pin is successfully exported
|
* @return true if the pin is successfully exported
|
||||||
*/
|
*/
|
||||||
public static boolean ExportPin(int pin){
|
public static boolean ExportPin(@NotNull RaspberryPi5BPins pin){
|
||||||
try{
|
try{
|
||||||
if (Files.isWritable(gpioExportPath)){
|
if (Files.isWritable(gpioExportPath)){
|
||||||
Files.write(gpioExportPath, String.valueOf(pin).getBytes());
|
Files.write(gpioExportPath, String.valueOf(pin.gpionumber).getBytes());
|
||||||
Logger.info("Pin "+pin+" exported");
|
Logger.info("Pin "+pin.pin+" exported");
|
||||||
return GpioPinExists(pin);
|
return GpioPinExists(pin);
|
||||||
} else Logger.error("GPIO export path is not writable");
|
} else Logger.error("GPIO export path is not writable");
|
||||||
} catch (Exception e){
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -59,14 +60,14 @@ public class GPIO {
|
|||||||
* @param pin GPIO pin number
|
* @param pin GPIO pin number
|
||||||
* @return true if the pin is successfully unexported
|
* @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)){
|
if (Files.isWritable(gpioUnexportPath)){
|
||||||
try{
|
try{
|
||||||
Files.write(gpioUnexportPath, String.valueOf(pin).getBytes());
|
Files.write(gpioUnexportPath, String.valueOf(pin.gpionumber).getBytes());
|
||||||
Logger.info("Pin "+pin+" unexported");
|
Logger.info("Pin "+pin.pin+" unexported");
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e){
|
} 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");
|
} else Logger.error("GPIO unexport path is not writable");
|
||||||
|
|
||||||
@@ -78,17 +79,17 @@ public class GPIO {
|
|||||||
* @param pin GPIO pin number
|
* @param pin GPIO pin number
|
||||||
* @return "in" if the pin is input, "out" if the pin is output, "unknown" if the direction is unknown
|
* @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){
|
public static String GetPinDirection(@NotNull RaspberryPi5BPins pin){
|
||||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
|
Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction");
|
||||||
if (pinPath.toFile().isFile()){
|
if (pinPath.toFile().isFile()){
|
||||||
if (Files.isReadable(pinPath)){
|
if (Files.isReadable(pinPath)){
|
||||||
try{
|
try{
|
||||||
return Files.readString(pinPath).trim();
|
return Files.readString(pinPath).trim();
|
||||||
} catch (Exception e){
|
} 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 is not readable: "+pin.pin);
|
||||||
} else Logger.error("Pin direction file not found: "+pin);
|
} else Logger.error("Pin direction file not found: "+pin.pin);
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,22 +99,22 @@ public class GPIO {
|
|||||||
* @param direction "in" for input, "out" for output
|
* @param direction "in" for input, "out" for output
|
||||||
* @return true if the direction is successfully set
|
* @return true if the direction is successfully set
|
||||||
*/
|
*/
|
||||||
public static boolean SetPinDirection(int pin, String direction){
|
public static boolean SetPinDirection(@NotNull RaspberryPi5BPins pin, String direction){
|
||||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("direction");
|
Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction");
|
||||||
if (pinPath.toFile().isFile()){
|
if (pinPath.toFile().isFile()){
|
||||||
if (Files.isWritable(pinPath)){
|
if (Files.isWritable(pinPath)){
|
||||||
direction = direction.trim().toLowerCase();
|
direction = direction.trim().toLowerCase();
|
||||||
if ("in".equals(direction) || "out".equals(direction)){
|
if ("in".equals(direction) || "out".equals(direction)){
|
||||||
try{
|
try{
|
||||||
Files.write(pinPath, direction.getBytes());
|
Files.write(pinPath, direction.getBytes());
|
||||||
Logger.info("Pin "+pin+" direction set to "+direction);
|
Logger.info("Pin "+pin.pin+" direction set to "+direction);
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e){
|
} 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("Invalid direction: "+direction);
|
||||||
} else Logger.error("Pin direction file is not writable: "+pin);
|
} else Logger.error("Pin direction file is not writable: "+pin.pin);
|
||||||
} else Logger.error("Pin direction file not found: "+pin);
|
} else Logger.error("Pin direction file not found: "+pin.pin);
|
||||||
return false;
|
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
|
* @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
|
* @return true if the value is successfully set
|
||||||
*/
|
*/
|
||||||
public static boolean SetValue(int pin, boolean isON){
|
public static boolean SetValue(@NotNull RaspberryPi5BPins pin, boolean isON){
|
||||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
|
Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value");
|
||||||
if (pinPath.toFile().isFile()){
|
if (pinPath.toFile().isFile()){
|
||||||
if (Files.isWritable(pinPath)){
|
if (Files.isWritable(pinPath)){
|
||||||
try{
|
try{
|
||||||
Files.write(pinPath, isON?"1".getBytes():"0".getBytes());
|
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;
|
return true;
|
||||||
} catch (Exception e){
|
} 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 is not writable: "+pin.pin);
|
||||||
} else Logger.error("Pin value file not found: "+pin);
|
} else Logger.error("Pin value file not found: "+pin.pin);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,17 +145,17 @@ public class GPIO {
|
|||||||
* @param pin GPIO pin number
|
* @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
|
* @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){
|
public static String GetValue(@NotNull RaspberryPi5BPins pin){
|
||||||
Path pinPath = gpioPath.resolve("gpio"+pin).resolve("value");
|
Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value");
|
||||||
if (pinPath.toFile().isFile()){
|
if (pinPath.toFile().isFile()){
|
||||||
if (Files.isReadable(pinPath)){
|
if (Files.isReadable(pinPath)){
|
||||||
try{
|
try{
|
||||||
return Files.readString(pinPath).trim();
|
return Files.readString(pinPath).trim();
|
||||||
} catch (Exception e){
|
} 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 is not readable: "+pin.pin);
|
||||||
} else Logger.error("Pin value file not found: "+pin);
|
} else Logger.error("Pin value file not found: "+pin.pin);
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/main/java/SBC/RaspberryPi5BPins.java
Normal file
42
src/main/java/SBC/RaspberryPi5BPins.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,10 @@ package Web;
|
|||||||
|
|
||||||
import Other.SomeCodes;
|
import Other.SomeCodes;
|
||||||
import com.corundumstudio.socketio.Configuration;
|
import com.corundumstudio.socketio.Configuration;
|
||||||
|
import com.corundumstudio.socketio.SocketIOClient;
|
||||||
import com.corundumstudio.socketio.SocketIOServer;
|
import com.corundumstudio.socketio.SocketIOServer;
|
||||||
|
import com.corundumstudio.socketio.listener.ConnectListener;
|
||||||
|
import com.corundumstudio.socketio.listener.DisconnectListener;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import io.javalin.http.UploadedFile;
|
import io.javalin.http.UploadedFile;
|
||||||
import io.javalin.util.FileUtil;
|
import io.javalin.util.FileUtil;
|
||||||
@@ -12,10 +15,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import static Other.SomeCodes.*;
|
import static Other.SomeCodes.*;
|
||||||
@@ -30,6 +30,8 @@ public class WebServer {
|
|||||||
private final Set<WsContext> connectedWebsocketClients = ConcurrentHashMap.newKeySet();
|
private final Set<WsContext> connectedWebsocketClients = ConcurrentHashMap.newKeySet();
|
||||||
private final SocketIOServer socketServer;
|
private final SocketIOServer socketServer;
|
||||||
private final Configuration socketConfig;
|
private final Configuration socketConfig;
|
||||||
|
private final HashMap<String, SocketIOClient> socketIOClients = new HashMap<>();
|
||||||
|
|
||||||
public WebServer(WebsocketEvent event, String webusername, String webpassword){
|
public WebServer(WebsocketEvent event, String webusername, String webpassword){
|
||||||
this.webusername = webusername;
|
this.webusername = webusername;
|
||||||
this.webpassword = webpassword;
|
this.webpassword = webpassword;
|
||||||
@@ -178,10 +180,13 @@ public class WebServer {
|
|||||||
ctx.redirect("/login.html");
|
ctx.redirect("/login.html");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
WebSocket Communication
|
||||||
|
This is temporary, later must choose either WebSocket or SocketIO
|
||||||
|
*/
|
||||||
app.ws("/ws", ws -> {
|
app.ws("/ws", ws -> {
|
||||||
ws.onConnect(connectws);
|
ws.onConnect(connectws);
|
||||||
ws.onClose(closews);
|
ws.onClose(closews);
|
||||||
//ws.onError(errorws);
|
|
||||||
ws.onMessage(ctx -> {
|
ws.onMessage(ctx -> {
|
||||||
try{
|
try{
|
||||||
//Logger.info("WebSocket message {}", ctx.message());
|
//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 = new Configuration();
|
||||||
socketConfig.setHostname("0.0.0.0");
|
socketConfig.setHostname("0.0.0.0");
|
||||||
socketConfig.setPort(3001);
|
socketConfig.setPort(3001);
|
||||||
socketServer = new SocketIOServer(socketConfig);
|
socketServer = new SocketIOServer(socketConfig);
|
||||||
socketServer.addConnectListener(client -> {
|
socketServer.addConnectListener(connectListener);
|
||||||
Logger.info("SocketIO connected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
|
socketServer.addDisconnectListener(disconnectListener);
|
||||||
});
|
|
||||||
socketServer.addDisconnectListener(client -> {
|
|
||||||
Logger.info("SocketIO disconnected, id {} from {}", client.getSessionId(), client.getRemoteAddress());
|
|
||||||
});
|
|
||||||
socketServer.addNamespace("/socketio").addEventListener("message", String.class, (client, data, ackSender) -> {
|
socketServer.addNamespace("/socketio").addEventListener("message", String.class, (client, data, ackSender) -> {
|
||||||
//Logger.info("SocketIO message from namespace /socketio from {}: {}", client.getRemoteAddress(), data);
|
//Logger.info("SocketIO message from namespace /socketio from {}: {}", client.getRemoteAddress(), data);
|
||||||
WebsocketCommand command = gson.fromJson(data, WebsocketCommand.class);
|
WebsocketCommand command = gson.fromJson(data, WebsocketCommand.class);
|
||||||
@@ -232,6 +237,7 @@ public class WebServer {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(ws -> ws.session.isOpen())
|
.filter(ws -> ws.session.isOpen())
|
||||||
.forEach(ws -> ws.send(obj));
|
.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){
|
public void Start(String localip, int port){
|
||||||
try{
|
try{
|
||||||
connectedWebsocketClients.forEach(WsContext::closeSession);
|
|
||||||
app.start(localip, port);
|
app.start(localip, port);
|
||||||
Logger.info("Web server started at {}:{}", localip, port);
|
Logger.info("Web server started at {}:{}", localip, port);
|
||||||
socketServer.start();
|
socketServer.start();
|
||||||
@@ -256,8 +261,12 @@ public class WebServer {
|
|||||||
*/
|
*/
|
||||||
public void Stop(){
|
public void Stop(){
|
||||||
try{
|
try{
|
||||||
|
connectedWebsocketClients.forEach(WsContext::closeSession);
|
||||||
|
connectedWebsocketClients.clear();
|
||||||
app.stop();
|
app.stop();
|
||||||
Logger.info("Web server stopped");
|
Logger.info("Web server stopped");
|
||||||
|
socketIOClients.forEach((key, client) -> client.disconnect());
|
||||||
|
socketIOClients.clear();
|
||||||
socketServer.stop();
|
socketServer.stop();
|
||||||
Logger.info("SocketIO server stopped");
|
Logger.info("SocketIO server stopped");
|
||||||
} catch (JavalinException e){
|
} catch (JavalinException e){
|
||||||
@@ -276,7 +285,16 @@ public class WebServer {
|
|||||||
connectedWebsocketClients.remove(ws);
|
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());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import Camera.PanTiltController;
|
|||||||
import Camera.RtspGrabber;
|
import Camera.RtspGrabber;
|
||||||
import Camera.VapixProtocol;
|
import Camera.VapixProtocol;
|
||||||
import Other.SomeCodes;
|
import Other.SomeCodes;
|
||||||
import SBC.ProcessorStatus;
|
import SBC.*;
|
||||||
import SBC.RamInformation;
|
|
||||||
import SBC.SystemInformation;
|
|
||||||
import Web.*;
|
import Web.*;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import org.bytedeco.opencv.global.opencv_core;
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
@@ -19,6 +17,8 @@ import org.tinylog.Logger;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import static Other.SomeCodes.*;
|
import static Other.SomeCodes.*;
|
||||||
|
|
||||||
@@ -34,6 +34,16 @@ public class Main {
|
|||||||
private static RamInformation ramInformation;
|
private static RamInformation ramInformation;
|
||||||
private static ProcessorStatus[] previousCpuInfo;
|
private static ProcessorStatus[] previousCpuInfo;
|
||||||
private static final Map<String, Integer> cpuUsage = new HashMap<>();
|
private static final Map<String, Integer> cpuUsage = new HashMap<>();
|
||||||
|
private static NetworkTransmitReceiveInfo[] previousNetworkInfo;
|
||||||
|
private static final Map<String, String> networkTX = new HashMap<>();
|
||||||
|
private static final Map<String, String> 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
|
// Application start from here
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@@ -44,8 +54,10 @@ public class Main {
|
|||||||
if (panTiltController!=null) panTiltController.Close();
|
if (panTiltController!=null) panTiltController.Close();
|
||||||
if (vapixProtocol!=null) vapixProtocol.Close();
|
if (vapixProtocol!=null) vapixProtocol.Close();
|
||||||
if (timer!=null) timer.cancel();
|
if (timer!=null) timer.cancel();
|
||||||
|
if (gpioExecutor!=null) gpioExecutor.shutdown();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
init_gpio();
|
||||||
init_system_monitoring();
|
init_system_monitoring();
|
||||||
|
|
||||||
init_properties();
|
init_properties();
|
||||||
@@ -58,6 +70,70 @@ public class Main {
|
|||||||
init_rtspgrabber();
|
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(){
|
private static void init_system_monitoring(){
|
||||||
TimerTask tt = new TimerTask() {
|
TimerTask tt = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
@@ -72,6 +148,41 @@ public class Main {
|
|||||||
for(int ii=0;ii<previousCpuInfo.length;ii++){
|
for(int ii=0;ii<previousCpuInfo.length;ii++){
|
||||||
cpuUsage.put(cpuinfo[ii].name, cpuinfo[ii].cpu_usage(previousCpuInfo[ii]));
|
cpuUsage.put(cpuinfo[ii].name, cpuinfo[ii].cpu_usage(previousCpuInfo[ii]));
|
||||||
}
|
}
|
||||||
|
previousCpuInfo = cpuinfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NetworkTransmitReceiveInfo[] ntri = SystemInformation.getNetworkTransmitReceiveInfo();
|
||||||
|
if (ntri.length>0){
|
||||||
|
if (previousNetworkInfo==null || !Objects.equals(previousNetworkInfo.length, ntri.length)){
|
||||||
|
previousNetworkInfo = ntri;
|
||||||
|
} else {
|
||||||
|
for(int ii=0;ii<previousNetworkInfo.length;ii++){
|
||||||
|
double txspeed = ntri[ii].TxSpeed(previousNetworkInfo[ii], "B");
|
||||||
|
String txspeedstr;
|
||||||
|
if (txspeed < KB_threshold){
|
||||||
|
txspeedstr = String.format("%.0f B/s", txspeed);
|
||||||
|
} else if (txspeed < MB_threshold){
|
||||||
|
txspeedstr = String.format("%.1f KB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "KB"));
|
||||||
|
} else if (txspeed < GB_threshold){
|
||||||
|
txspeedstr = String.format("%.1f MB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "MB"));
|
||||||
|
} else {
|
||||||
|
txspeedstr = String.format("%.1f GB/s", ntri[ii].TxSpeed(previousNetworkInfo[ii], "GB"));
|
||||||
|
}
|
||||||
|
double rxspeed = ntri[ii].RxSpeed(previousNetworkInfo[ii], "B");
|
||||||
|
String rxspeedstr;
|
||||||
|
if (rxspeed < KB_threshold){
|
||||||
|
rxspeedstr = String.format("%.0f B/s", rxspeed);
|
||||||
|
} else if (rxspeed < MB_threshold){
|
||||||
|
rxspeedstr = String.format("%.1f KB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "KB"));
|
||||||
|
} else if (rxspeed < GB_threshold){
|
||||||
|
rxspeedstr = String.format("%.1f MB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "MB"));
|
||||||
|
} else {
|
||||||
|
rxspeedstr = String.format("%.1f GB/s", ntri[ii].RxSpeed(previousNetworkInfo[ii], "GB"));
|
||||||
|
}
|
||||||
|
networkTX.put(ntri[ii].name, txspeedstr);
|
||||||
|
networkRX.put(ntri[ii].name, rxspeedstr);
|
||||||
|
}
|
||||||
|
previousNetworkInfo = ntri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,13 +222,16 @@ public class Main {
|
|||||||
if (IpIsReachable(ip)){
|
if (IpIsReachable(ip)){
|
||||||
Logger.info("Camera IP is reachable");
|
Logger.info("Camera IP is reachable");
|
||||||
vapixProtocol = new VapixProtocol(ip, Integer.parseInt(port), username, password);
|
vapixProtocol = new VapixProtocol(ip, Integer.parseInt(port), username, password);
|
||||||
Logger.info("Camera Product Number: "+vapixProtocol.GetProductNumber());
|
if (vapixProtocol.isSuccessQuery()){
|
||||||
Logger.info("Camera Serial Number: "+vapixProtocol.GetSerialNumber());
|
Logger.info("Camera Product Number: "+vapixProtocol.GetProductNumber());
|
||||||
if (vapixProtocol.PTZEnabled()){
|
Logger.info("Camera Serial Number: "+vapixProtocol.GetSerialNumber());
|
||||||
Logger.info("PTZ Enabled");
|
if (vapixProtocol.PTZEnabled()){
|
||||||
} else Logger.error("PTZ Disabled");
|
Logger.info("PTZ Enabled");
|
||||||
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
} else Logger.error("PTZ Disabled");
|
||||||
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
|
||||||
|
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
|
||||||
|
Blink(LedIpCamera);
|
||||||
|
} else Logger.error("Failed to query camera");
|
||||||
} else Logger.error("Camera IP is not reachable");
|
} else Logger.error("Camera IP is not reachable");
|
||||||
} else Logger.error("Camera Password is not valid string");
|
} else Logger.error("Camera Password is not valid string");
|
||||||
} else Logger.error("Camera Username is not valid string");
|
} else Logger.error("Camera Username is not valid string");
|
||||||
@@ -205,7 +319,7 @@ public class Main {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
|
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
|
||||||
|
Blink(LedWeb);
|
||||||
byte speed;
|
byte speed;
|
||||||
String cmd = command.command.toUpperCase().trim();
|
String cmd = command.command.toUpperCase().trim();
|
||||||
switch (cmd){
|
switch (cmd){
|
||||||
@@ -261,6 +375,7 @@ public class Main {
|
|||||||
if (afp!=null){
|
if (afp!=null){
|
||||||
audioFileProperties = afp;
|
audioFileProperties = afp;
|
||||||
audioPlayer.PlayAudioFile(afp, true, pe);
|
audioPlayer.PlayAudioFile(afp, true, pe);
|
||||||
|
AmplifierControl(true);
|
||||||
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
return new WebsocketReply("PLAY AUDIO", afp.filename);
|
||||||
|
|
||||||
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
|
||||||
@@ -272,6 +387,7 @@ public class Main {
|
|||||||
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
|
||||||
String filename = audioFileProperties.filename;
|
String filename = audioFileProperties.filename;
|
||||||
audioFileProperties = null;
|
audioFileProperties = null;
|
||||||
|
AmplifierControl(false);
|
||||||
return new WebsocketReply("STOP AUDIO", filename);
|
return new WebsocketReply("STOP AUDIO", filename);
|
||||||
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
|
||||||
// ZOOM Related Commands
|
// ZOOM Related Commands
|
||||||
@@ -290,6 +406,7 @@ public class Main {
|
|||||||
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
if (zoom<vapixProtocol.GetPTZMinZoom()) zoom = vapixProtocol.GetPTZMinZoom();
|
||||||
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
if (zoom>vapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
|
||||||
if (vapixProtocol.Zoom(1, zoom)){
|
if (vapixProtocol.Zoom(1, zoom)){
|
||||||
|
Blink(LedIpCamera);
|
||||||
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
return new WebsocketReply("ZOOM", String.valueOf(zoom));
|
||||||
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
} else return new WebsocketReply("ZOOM", "Failed to zoom");
|
||||||
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
} else return new WebsocketReply("ZOOM", "Invalid Zoom Value");
|
||||||
@@ -326,6 +443,18 @@ public class Main {
|
|||||||
data.addProperty(key, String.valueOf(cpuUsage.get(key)));
|
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());
|
return new WebsocketReply("GET SYSTEM INFO", data.toString());
|
||||||
default:
|
default:
|
||||||
return new WebsocketReply("UNKNOWN COMMAND", command.command);
|
return new WebsocketReply("UNKNOWN COMMAND", command.command);
|
||||||
|
|||||||
Reference in New Issue
Block a user