diff --git a/onnx/coco.names b/onnx/coco.names
new file mode 100644
index 0000000..ca76c80
--- /dev/null
+++ b/onnx/coco.names
@@ -0,0 +1,80 @@
+person
+bicycle
+car
+motorbike
+aeroplane
+bus
+train
+truck
+boat
+traffic light
+fire hydrant
+stop sign
+parking meter
+bench
+bird
+cat
+dog
+horse
+sheep
+cow
+elephant
+bear
+zebra
+giraffe
+backpack
+umbrella
+handbag
+tie
+suitcase
+frisbee
+skis
+snowboard
+sports ball
+kite
+baseball bat
+baseball glove
+skateboard
+surfboard
+tennis racket
+bottle
+wine glass
+cup
+fork
+knife
+spoon
+bowl
+banana
+apple
+sandwich
+orange
+broccoli
+carrot
+hot dog
+pizza
+donut
+cake
+chair
+sofa
+pottedplant
+bed
+diningtable
+toilet
+tvmonitor
+laptop
+mouse
+remote
+keyboard
+cell phone
+microwave
+oven
+toaster
+sink
+refrigerator
+book
+clock
+vase
+scissors
+teddy bear
+hair drier
+toothbrush
diff --git a/onnx/yolov8n.onnx b/onnx/yolov8n.onnx
new file mode 100644
index 0000000..ade7079
Binary files /dev/null and b/onnx/yolov8n.onnx differ
diff --git a/pom.xml b/pom.xml
index db1e03e..65fa25d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -178,32 +178,6 @@
5.1.2-1.5.8
linux-arm64
-
com.corundumstudio.socketio
netty-socketio
diff --git a/src/main/java/Camera/GrabbingTask.java b/src/main/java/Camera/GrabbingTask.java
index bf576c7..48d7629 100644
--- a/src/main/java/Camera/GrabbingTask.java
+++ b/src/main/java/Camera/GrabbingTask.java
@@ -9,6 +9,7 @@ import lombok.Getter;
import lombok.Setter;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
+import org.bytedeco.opencv.opencv_core.Mat;
import org.tinylog.Logger;
public class GrabbingTask implements Runnable {
@@ -23,6 +24,8 @@ public class GrabbingTask implements Runnable {
@Setter private Consumer onLQFrameUpdate;
@Setter private Consumer onHQBase64Update;
@Setter private Consumer onLQBase64Update;
+ @Setter private Consumer onYoloUpdate;
+ @Setter private Consumer onYoloBase64Update;
// status of capture fps
@Getter private int CaptureFPS = 0;
@@ -33,6 +36,8 @@ public class GrabbingTask implements Runnable {
// for FPS calculation
private int intendedFps = 10;
+ private final YoloDetector yolo;
+
@SuppressWarnings("SameParameterValue")
private void updateMessage(String message) {
if (onMessageUpdate != null) {
@@ -40,9 +45,17 @@ public class GrabbingTask implements Runnable {
}
}
+ private void updateYoloBase64(String base64) {
+ if (onYoloBase64Update != null) {
+ onYoloBase64Update.accept(base64);
+ }
+ }
-
-
+ private void updateYoloFrame(Frame frame) {
+ if (onYoloUpdate != null) {
+ onYoloUpdate.accept(frame);
+ }
+ }
private void updateHQBase64(String base64) {
if (onHQBase64Update != null) {
@@ -77,6 +90,7 @@ public class GrabbingTask implements Runnable {
this.isGrabbing = isGrabbing;
this.grabber = grabber;
if (fps>0) intendedFps = fps;
+ yolo = new YoloDetector();
}
@@ -94,6 +108,23 @@ public class GrabbingTask implements Runnable {
} else updateMessage("processFrame have null frame");
}
+ //TODO masih trouble di sini
+ private void DetectYolo(Frame frame){
+ if (frame!=null){
+ try{
+ Mat processed = yolo.Detect(frame);
+ Frame yoloFrame = SomeCodes.CoreMatConverter.convert(processed);
+ updateYoloFrame(yoloFrame);
+ updateYoloBase64(SomeCodes.FrameToBase64(yoloFrame));
+ } catch (Exception e){
+ System.out.println("error processing YOLO, Message : "+e.getMessage());
+ updateYoloFrame(null);
+ updateYoloBase64("");
+ }
+ }
+
+ }
+
private void flush_grabber(){
try {
if (grabber!=null) grabber.flush();
@@ -117,9 +148,13 @@ public class GrabbingTask implements Runnable {
Thread.yield();
Frame frame = grabber.grab();
if (framecount0){
+ Logger.info("CUDA enabled devices found: " + cudacount);
+ opencv_core.printCudaDeviceInfo(0);
+ } else {
+ Logger.info("No CUDA enabled devices found");
+ }
this.rtspUrl = "rtsp://" + ip + path;
Logger.info("RtspGrabber created with url: " + rtspUrl);
}
@@ -62,6 +72,22 @@ public class RtspGrabber {
return lastLQBase64;
}
+ private synchronized void setLastYoloBase64(String base64){
+ lastYoloBase64 = base64;
+ }
+
+ public synchronized String getLastYoloBase64(){
+ return lastYoloBase64;
+ }
+
+ private synchronized void setLastYoloFrame(Frame frame){
+ lastYoloFrame = frame;
+ }
+
+ public synchronized Frame getLastYoloFrame(){
+ return lastYoloFrame;
+ }
+
/**
* Start grabbing frames from rtsp
* @param useTcp Use tcp instead of udp
@@ -143,6 +169,8 @@ public class RtspGrabber {
});
tt.setOnHQBase64Update(this::setLastHQBase64);
tt.setOnLQBase64Update(this::setLastLQBase64);
+ tt.setOnYoloUpdate(this::setLastYoloFrame);
+ tt.setOnYoloBase64Update(this::setLastYoloBase64);
return tt;
}
}
diff --git a/src/main/java/Camera/YoloDetector.java b/src/main/java/Camera/YoloDetector.java
new file mode 100644
index 0000000..7bb1130
--- /dev/null
+++ b/src/main/java/Camera/YoloDetector.java
@@ -0,0 +1,167 @@
+package Camera;
+
+import Other.SomeCodes;
+import lombok.Getter;
+import org.bytedeco.javacv.Frame;
+import org.bytedeco.opencv.global.opencv_dnn;
+import org.bytedeco.opencv.global.opencv_imgproc;
+import org.bytedeco.opencv.opencv_core.Mat;
+import org.bytedeco.opencv.opencv_core.Rect;
+import org.bytedeco.opencv.opencv_core.Scalar;
+import org.bytedeco.opencv.opencv_core.Size;
+import org.bytedeco.opencv.opencv_dnn.*;
+import org.opencv.core.MatOfFloat;
+import org.opencv.core.MatOfInt;
+import org.opencv.core.MatOfRect2d;
+import org.opencv.dnn.Dnn;
+
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.bytedeco.opencv.global.opencv_core.CV_32F;
+
+public class YoloDetector {
+ private Net net;
+ private @Getter boolean NetLoaded;
+ private List classes ;
+ // YOLO expect image in 640 x 640
+ private final int input_width = 640;
+ private final int input_height = 640;
+ // minimum confidence for detections
+ private final float confidence_threshold = 0.5f;
+ // Non-maximum suppression threshold
+ private final float nms_threshold = 0.4f;
+
+ public YoloDetector() {
+ NetLoaded = false;
+ net = null;
+ classes = null;
+ String onnxfile = SomeCodes.ExtractResource("/yolov8n.onnx", SomeCodes.currentDirectory);
+ String namesfile = SomeCodes.ExtractResource("/coco.names", SomeCodes.currentDirectory);
+ if (SomeCodes.ValidFile(onnxfile)){
+ if (SomeCodes.ValidFile(namesfile)){
+ net = opencv_dnn.readNetFromONNX(onnxfile);
+ net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
+ net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
+
+ classes = new ArrayList<>();
+ try(BufferedReader br = new BufferedReader(new FileReader(namesfile))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ classes.add(line);
+ }
+ } catch (Exception e){
+ System.out.println("Error: reading names file");
+ }
+
+ if (!net.empty()){
+ if (!classes.isEmpty()){
+ NetLoaded = true;
+ } else System.out.println("Error: names file is empty");
+ } else System.out.println("Error: net is empty");
+ } else System.out.println("Error: names file not found");
+ } else System.out.println("Error: onnx file not found");
+ }
+
+ public Mat Detect(Frame frame){
+ Mat mat = SomeCodes.CoreMatConverter.convertToMat(frame);
+ return Detect(mat);
+
+ }
+
+ public Mat Detect(Mat frame){
+ if (NetLoaded){
+ Mat blob = opencv_dnn.blobFromImage(frame, 1.0/255.0, new Size(input_width, input_height), new Scalar(0) , true, false, CV_32F);
+ net.setInput(blob);
+
+ Mat detections = net.forward();
+ return detections;
+ } else {
+ System.out.println("Error: Net not loaded");
+ return new Mat();
+ }
+ }
+
+ private Mat ProcessDetection(Mat frame, Mat output){
+ int rows = output.rows();
+ int cols = output.cols();
+ List boxes = new ArrayList<>();
+ List confidences = new ArrayList<>();
+ List classIds = new ArrayList<>();
+
+ for(int i=0;i= confidence_threshold){
+ FloatBuffer data = row.getFloatBuffer();
+ int classid = 0;
+ float maxscore = 0;
+ for(int j = 5; j< cols; j++){
+ float score = data.get(j);
+ if (score > maxscore){
+ maxscore = score;
+ classid = j-5;
+ }
+ }
+ if (maxscore>= confidence_threshold){
+ int x = (int)(data.get(0) * frame.cols());
+ int y = (int)(data.get(1) * frame.rows());
+ int width = (int)(data.get(2) * frame.cols());
+ int height = (int)(data.get(3) * frame.rows());
+
+ boxes.add(new Rect(x-width/2, y-height/2, width, height));
+ confidences.add(maxscore);
+ classIds.add(classid);
+ }
+ }
+ }
+
+ Rect[] rr = new Rect[boxes.size()];
+ for(int ii = 0; ii list){
+ org.opencv.core.Rect2d[] arr = new org.opencv.core.Rect2d[list.size()];
+ for(int i=0;i list){
+ float[] arr = new float[list.size()];
+ for(int i=0;i=0){
+ opened = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void Close_Bus(){
+ if (opened){
+ if (i2c_handle>=0){
+ C.close(i2c_handle);
+ i2c_handle = -1;
+ }
+ opened = false;
+ }
+ }
+}
diff --git a/src/main/java/SBC/I2C_Device.java b/src/main/java/SBC/I2C_Device.java
new file mode 100644
index 0000000..9fdd061
--- /dev/null
+++ b/src/main/java/SBC/I2C_Device.java
@@ -0,0 +1,147 @@
+package SBC;
+
+import lombok.Getter;
+
+@SuppressWarnings("unused")
+public class I2C_Device {
+
+
+ Linux_C_lib C = Linux_C_lib.INSTANCE;
+ private @Getter int bus_handle;
+ private @Getter int device_address;
+ private @Getter int dev_handle;
+ private @Getter boolean opened = false;
+
+ /**
+ * Create I2C Device
+ * @param bus_handle I2C Bus Handle, from opening I2C_Bus
+ * @param device_address I2C Device Address
+ */
+ public I2C_Device(int bus_handle, int device_address){
+ opened = false;
+ if (bus_handle<0 || device_address<0) return;
+ this.bus_handle = bus_handle;
+ this.device_address = device_address;
+ }
+
+ /**
+ * Open I2C Device in Slave mode
+ * @return true if successfully opened
+ */
+ public boolean Open_Slave(){
+ boolean sucess = false;
+ dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SLAVE, device_address);
+ if (dev_handle>=0){
+ sucess = true;
+ }
+ opened = sucess;
+ return opened;
+ }
+
+ /**
+ * Open I2C Device in Slave mode with Force
+ * @return true if successfully opened
+ */
+ public boolean Open_SlaveForce(){
+ boolean sucess = false;
+ dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SLAVE_FORCE, device_address);
+ if (dev_handle>=0){
+ C.ioctl(bus_handle,I2C_Flags.I2C_RETRIES, 3);
+ C.ioctl(bus_handle,I2C_Flags.I2C_TIMEOUT, 1000);
+ sucess = true;
+ }
+ opened = sucess;
+ return opened;
+ }
+
+ /**
+ * Open I2C Device in Read Write mode
+ * @return true if successfully opened
+ */
+ public boolean Open_RDWR(){
+ boolean sucess = false;
+ dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_RDWR, device_address);
+ if (dev_handle>=0){
+ sucess = true;
+ }
+ opened = sucess;
+ return opened;
+ }
+
+ /**
+ * Open I2C Device in SMBus mode
+ * @return true if successfully opened
+ */
+ public boolean Open_SMBus(){
+ boolean sucess = false;
+ dev_handle = C.ioctl(bus_handle, I2C_Flags.I2C_SMBUS, device_address);
+ if (dev_handle>=0){
+ sucess = true;
+ }
+ opened = sucess;
+ return opened;
+ }
+
+ /**
+ * Close I2C Device
+ */
+ public void Close(){
+ C.close(dev_handle);
+ opened = false;
+ dev_handle = -1;
+ }
+
+ /**
+ * Write Bytes to I2C Device
+ * @param data bytes to write
+ * @return number of bytes written
+ */
+ public int WriteBytes(byte[] data){
+ if (bus_handle<0 || dev_handle<0 || device_address<0) return -1;
+ return C.write(bus_handle, data, data.length);
+ }
+
+ /**
+ * Write Byte to I2C Device
+ * @param register_address register address
+ * @param data byte to write
+ * @return number of bytes written
+ */
+ public int WriteBytes(int register_address, byte data){
+ byte[] cmd = new byte[2];
+ cmd[0] = (byte) register_address;
+ cmd[1] = data;
+ return WriteBytes(cmd);
+ }
+
+ /**
+ * Write Bytes to I2C Device
+ * @param register_address register address
+ * @param data bytes to write
+ * @return number of bytes written
+ */
+ public int WriteBytes(int register_address, byte[] data){
+ byte[] cmd = new byte[data.length+1];
+ cmd[0] = (byte) register_address;
+ System.arraycopy(data, 0, cmd, 1, data.length);
+ return WriteBytes(cmd);
+ }
+
+ /**
+ * Read Bytes from I2C Device
+ * @param readsize number of bytes to read
+ * @return bytes read
+ */
+ public byte[] ReadBytes(int readsize){
+ if (bus_handle<0 || dev_handle<0 || device_address<0) return null;
+ byte[] data = new byte[readsize];
+ int read = C.read(bus_handle, data, readsize);
+ if (read<0) return null;
+ if (read getFieldOrder() {
+ return Arrays.asList(//
+ "tv_sec",//
+ "tv_usec"//
+ );
+ }
+
+ public timeval(long second, long usecond) {
+ tv_sec = new NativeLong(second);
+ tv_usec = new NativeLong(usecond);
+ }
+ }
+}
diff --git a/src/main/java/SBC/PCF8574.java b/src/main/java/SBC/PCF8574.java
new file mode 100644
index 0000000..9d991c9
--- /dev/null
+++ b/src/main/java/SBC/PCF8574.java
@@ -0,0 +1,159 @@
+package SBC;
+
+import lombok.Getter;
+
+@SuppressWarnings("unused")
+public class PCF8574 extends I2C_Device{
+
+ private byte data = 0x00;
+ private final @Getter String[] pinNames = new String[8];
+
+ /**
+ * Create new PCF8574
+ * @param bus_number I2C Bus Number
+ * @param address PCF8574 Address
+ */
+ public PCF8574(int bus_number, int address){
+ super(bus_number, address);
+ for(int i=0; i<8; i++){
+ pinNames[i] = i+"";
+ }
+ }
+
+ /**
+ * Set new Pin Name
+ * @param pin pin number, 0-7
+ * @param name new name
+ */
+ public void setPinName(int pin, String name){
+ if (pin<0 || pin>7) return;
+ pinNames[pin] = name;
+ }
+
+ /**
+ * Get Pin Name
+ * @param pin pin number, 0-7
+ * @return pin name, or null if not available
+ */
+ public String getPinName(int pin){
+ if (pin<0 || pin>7) return null;
+ return pinNames[pin];
+ }
+
+ /**
+ * Set All Pins High
+ * @return true if successful
+ */
+ public boolean AllOn(){
+ if (super.isOpened()){
+ if (super.WriteBytes(new byte[]{(byte)0xFF})>0){
+ data = (byte)0xFF;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Set all Pins Low
+ * @return true if successful
+ */
+ public boolean AllOff(){
+ if (super.isOpened()){
+ if (super.WriteBytes(new byte[]{(byte)0x00})>0){
+ data = (byte)0x00;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Set Pin by Pin Name
+ * @param pinName pin name
+ * @return true if successful
+ */
+ public boolean SetPin(String pinName){
+ for(int i=0; i<8; i++){
+ if (pinNames[i].equals(pinName)){
+ return SetPin(i);
+ }
+ }
+ return false;
+ }
+
+
+
+ /**
+ * Set Pin High
+ * @param pin pin number 0-7
+ * @return true if successful
+ */
+ public boolean SetPin(int pin){
+ if (pin<0 || pin>7) return false;
+ if (super.isOpened()){
+ byte temp = (byte) (data | (1<0;
+ }
+ return false;
+ }
+
+ /**
+ * Clear Pin by Pin Name
+ * @param pinName pin name
+ * @return true if successful
+ */
+ public boolean ClearPin(String pinName){
+ for(int i=0; i<8; i++){
+ if (pinNames[i].equals(pinName)){
+ return ClearPin(i);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Set Pin Low
+ * @param pin pin number 0-7
+ * @return true if successful
+ */
+ public boolean ClearPin(int pin){
+ if (pin<0 || pin>7) return false;
+ if (super.isOpened()){
+ byte temp = (byte) (data & ~(1<0;
+ }
+ return false;
+ }
+
+
+ /**
+ * Read Pin by Pin Name
+ * @param pinName pin name
+ * @return 1 if high, 0 if low, -1 if error
+ */
+ public int ReadPin(String pinName){
+ for(int i=0; i<8; i++){
+ if (pinNames[i].equals(pinName)){
+ return ReadPin(i);
+ }
+ }
+ return -1;
+ }
+
+
+ /**
+ * Read Pin
+ * @param pin pin to read, 0 - 7
+ * @return 1 if high, 0 if low, -1 if error
+ */
+ public int ReadPin(int pin){
+ if (pin<0 || pin>7) return -1;
+ if (super.isOpened()){
+ byte[] buffer = super.ReadBytes(1);
+ byte masker = (byte) (1< 0 ? 1 : 0;
+ }
+ return -1;
+ }
+}
diff --git a/src/main/java/id/co/gtc/Main.java b/src/main/java/id/co/gtc/Main.java
index 7ce72e1..86c30fb 100644
--- a/src/main/java/id/co/gtc/Main.java
+++ b/src/main/java/id/co/gtc/Main.java
@@ -11,6 +11,7 @@ import Other.SomeCodes;
import SBC.*;
import Web.*;
import com.google.gson.JsonObject;
+import com.sun.jna.Platform;
import org.bytedeco.opencv.global.opencv_core;
import org.tinylog.Logger;
@@ -45,6 +46,9 @@ public class Main {
private static ExecutorService gpioExecutor = null;
+ private static I2C_BUS i2c_bus = null;
+ private static PCF8574 pcf8574 = null;
+
// Application start from here
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
@@ -70,10 +74,16 @@ public class Main {
if (Max485Direction!=null) {
Logger.info("GPIO pin {} unexport : {}", Max485Direction.pin, GPIO.UnexportPin(Max485Direction));
}
+ if (pcf8574!=null){
+ pcf8574.Close();
+ }
}));
- init_gpio();
+ System.out.println("Current Directory : "+currentDirectory);
+
+ //init_gpio();
+ init_pcf8574();
init_system_monitoring();
init_properties();
@@ -81,20 +91,54 @@ public class Main {
init_Vapix();
init_audio();
+
init_pantiltcontroller();
init_webserver();
init_rtspgrabber();
}
+ private static void init_pcf8574(){
+ if (Platform.isLinux()){
+ i2c_bus = new I2C_BUS(7);
+ if (i2c_bus.Open_Bus()){
+ Logger.info("I2C Bus opened");
+ pcf8574 = new PCF8574(i2c_bus.getI2c_handle(), 0x27);
+ if (pcf8574.Open_Slave()){
+ System.out.println("PCF8574 opened");
+ pcf8574.AllOff();
+ pcf8574.setPinName(0, "Amplifier Power");
+ pcf8574.setPinName(1, "Led Web");
+ pcf8574.setPinName(2, "Led IP Camera");
+ pcf8574.setPinName(3, "Led Pan Tilt");
+ pcf8574.setPinName(4, "Max485 Direction");
+ gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
+
+
+ } else {
+ System.out.println("Failed to open PCF8574");
+ }
+ } else {
+ System.out.println("Failed to open I2C Bus");
+ }
+ } else System.out.println("PCF8574 not supported on this platform");
+ }
+
private static void init_gpio(){
- if (GPIO.HaveGPIO()){
- gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
- AmplifierPower = InitializePin(JetsonOrinPins.Pin13, true);
- LedWeb = InitializePin(JetsonOrinPins.Pin15, true);
- LedIpCamera = InitializePin(JetsonOrinPins.Pin19, true);
- LedPanTilt = InitializePin(JetsonOrinPins.Pin21, true);
- Max485Direction = InitializePin(JetsonOrinPins.Pin23, true);
- }
+ if (Platform.isLinux()){
+ if (GPIO.HaveGPIO()){
+ gpioExecutor = Executors.newVirtualThreadPerTaskExecutor();
+ AmplifierPower = InitializePin(JetsonOrinPins.Pin13, true);
+ LedWeb = InitializePin(JetsonOrinPins.Pin15, true);
+ LedIpCamera = InitializePin(JetsonOrinPins.Pin19, true);
+ LedPanTilt = InitializePin(JetsonOrinPins.Pin21, true);
+ Max485Direction = InitializePin(JetsonOrinPins.Pin23, true);
+ GPIO.SetValue(AmplifierPower,false);
+ GPIO.SetValue(LedWeb,false);
+ GPIO.SetValue(LedIpCamera,false);
+ GPIO.SetValue(LedPanTilt,false);
+ GPIO.SetValue(Max485Direction,false);
+ }
+ } else System.out.println("GPIO not supported on this platform");
}
@@ -121,17 +165,65 @@ public class Main {
public static void Max485Direction(boolean isTransmit){
if (Max485Direction!=null){
GPIO.SetValue(Max485Direction, isTransmit);
+ } else if (pcf8574!=null && pcf8574.isOpened()){
+ if (isTransmit){
+ pcf8574.SetPin("Max485 Direction");
+ } else {
+ pcf8574.ClearPin("Max485 Direction");
+ }
}
}
// dipanggil di PanTiltController, maka perlu public dan static
public static void Blink_LedPanTilt(){
- Blink(LedPanTilt);
+ if (LedPanTilt!=null){
+ Blink(LedPanTilt);
+ } else if (pcf8574!=null && pcf8574.isOpened()){
+ Blink("Led Pan Tilt");
+ }
+ }
+
+ public static void Blink_LedWeb(){
+ if (LedWeb!=null){
+ Blink(LedWeb);
+ } else if (pcf8574!=null && pcf8574.isOpened()){
+ Blink("Led Web");
+ }
+ }
+
+ public static void Blink_LedIpCamera(){
+ if (LedIpCamera!=null){
+ Blink(LedIpCamera);
+ } else if (pcf8574!=null && pcf8574.isOpened()){
+ Blink("Led IP Camera");
+ }
}
private static void AmplifierControl(boolean isON){
if (AmplifierPower!=null){
GPIO.SetValue(AmplifierPower, isON);
+ } else if (pcf8574!=null && pcf8574.isOpened()){
+ if (isON){
+ pcf8574.SetPin("Amplifier Power");
+ } else {
+ pcf8574.ClearPin("Amplifier Power");
+ }
+ }
+ }
+
+ private static void Blink(String pinName){
+ if (pcf8574!=null && pcf8574.isOpened()){
+ if (gpioExecutor!=null){
+ gpioExecutor.submit(()->{
+ pcf8574.SetPin(pinName);
+ try {
+ Thread.sleep(20);
+ } catch (InterruptedException ignored) {
+ }
+ pcf8574.ClearPin(pinName);
+ });
+ }
+
}
}
@@ -227,10 +319,16 @@ public class Main {
private static void init_Vapix(){
Properties config = SomeCodes.LoadProperties("config.properties");
+ System.out.println("Saved Configuration for Camera");
String ip = config.getProperty("Camera_ip");
String port = config.getProperty("Camera_port");
String username = config.getProperty("Camera_user");
String password = config.getProperty("Camera_password");
+ System.out.println("Camera IP : "+ip);
+ System.out.println("Camera Port : "+port);
+ System.out.println("Camera Username : "+username);
+ System.out.println("Camera Password : "+password);
+
if (ValidString(ip)){
if (ValidPortNumber(port)){
if (ValidString(username)){
@@ -246,7 +344,7 @@ public class Main {
} else Logger.error("PTZ Disabled");
Logger.info("Max Zoom: "+vapixProtocol.GetPTZMaxZoom());
Logger.info("Min Zoom: "+vapixProtocol.GetPTZMinZoom());
- Blink(LedIpCamera);
+ Blink_LedIpCamera();
} else Logger.error("Failed to query camera");
} else Logger.error("Camera IP is not reachable");
} else Logger.error("Camera Password is not valid string");
@@ -255,15 +353,42 @@ public class Main {
} else Logger.error( "Camera IP is not valid string");
}
+ private static void test_pantiltcontroller(){
+ System.out.println("Pan Tilt Controller Test");
+ panTiltController.PanLeft((byte)0x20);
+ System.out.println("Pan Left");
+ Sleep(2000);
+ panTiltController.PanRight((byte)0x20);
+ System.out.println("Pan Right");
+ Sleep(2000);
+ panTiltController.StopMovement();
+ System.out.println("Stop Movement");
+ panTiltController.TiltUp((byte)0x20);
+ System.out.println("Tilt Up");
+ Sleep(2000);
+ panTiltController.TiltDown((byte)0x20);
+ System.out.println("Tilt Down");
+ Sleep(2000);
+ panTiltController.StopMovement();
+ System.out.println("Stop Movement");
+ panTiltController.GoToPreset((byte)0);
+ System.out.println("Go To Preset 0");
+ }
+
private static void init_pantiltcontroller() {
Properties config = SomeCodes.LoadProperties("config.properties");
String portname = config.getProperty("SerialPort");
String baudrate = config.getProperty("SerialBaudRate");
String PanTiltID = config.getProperty("PanTiltID");
+ Logger.info("Saved Configuration for Pan Tilt Controller");
+ Logger.info("Serial Port : "+portname);
+ Logger.info("Serial Baud Rate : "+baudrate);
+ Logger.info("Pan Tilt ID : "+PanTiltID);
if (ValidString(portname)){
if (ValidInteger(baudrate)){
if (ValidInteger(PanTiltID)){
panTiltController = new PanTiltController(portname, Integer.parseInt(baudrate), Integer.parseInt(PanTiltID));
+ if (panTiltController.isOpen()) test_pantiltcontroller();
}
} else Logger.error("Invalid PTZ Baudrate");
} else Logger.error("Invalid PTZ Port");
@@ -277,16 +402,18 @@ public class Main {
Properties config = SomeCodes.LoadProperties("config.properties");
String targetip = config.getProperty("Camera_ip");
String rtsppath = config.getProperty("Camera_Rtsp_path");
+ System.out.println("Camera IP : "+targetip);
+ System.out.println("Camera Rtsp Path : "+rtsppath);
rtspGrabber = null;
if (ValidString(targetip)){
if (ValidString(rtsppath)){
if (IpIsReachable(targetip)){
- Logger.info("Camera IP is reachable");
+ Logger.info("Camera IP : "+targetip+" is reachable");
rtspGrabber = new RtspGrabber(targetip, rtsppath);
rtspGrabber.Start(true, 1920, 1080);
- } else Logger.error("Camera IP is not reachable");
- } else Logger.error("Camera Path is not valid string");
- } else Logger.error("Camera IP is not valid string");
+ } else System.out.println("Camera IP : "+targetip+" is not reachable");
+ } else System.out.println("Camera Path : "+rtsppath+" is not valid string");
+ } else System.out.println("Camera IP : "+targetip+" is not valid string");
}
private static void init_audio() {
@@ -309,16 +436,19 @@ public class Main {
@Override
public void onPlaybackStart(AudioFileProperties prop) {
Logger.info("Playback started for {}", prop.filename);
+ AmplifierControl(true);
}
@Override
public void onPlaybackFinished(AudioFileProperties prop) {
Logger.info("Playback finished for {}", prop.filename);
+ AmplifierControl(false);
}
@Override
public void onPlaybackFailure(AudioFileProperties prop, String reason) {
Logger.error("Playback failed for {}: {}", prop.filename, reason);
+ AmplifierControl(false);
}
@Override
@@ -335,7 +465,7 @@ public class Main {
@Override
public WebsocketReply onWebsocketCommand(WebsocketCommand command) {
- Blink(LedWeb);
+ Blink_LedWeb();
byte speed;
String cmd = command.command.toUpperCase().trim();
switch (cmd){
@@ -361,10 +491,10 @@ public class Main {
return new WebsocketReply("STOP MOVEMENT", "");
// Audio Related Commands
case "MUTE":
- audioPlayer.Mute();
+ if (audioPlayer!=null) audioPlayer.Mute();
return new WebsocketReply("MUTE", "");
case "UNMUTE":
- audioPlayer.Unmute();
+ if (audioPlayer!=null) audioPlayer.Unmute();
return new WebsocketReply("UNMUTE", "");
case "SET VOLUME" :
int volume=-1;
@@ -374,11 +504,11 @@ public class Main {
if (volume>100) volume = 100;
}
if (volume>=0){
- audioPlayer.setPlaybackvolume(volume);
+ if (audioPlayer!=null) audioPlayer.setPlaybackvolume(volume);
return new WebsocketReply("SET VOLUME", String.valueOf(volume));
} else return new WebsocketReply("SET VOLUME", "Invalid Volume Value");
case "GET VOLUME" :
- int vol = audioPlayer.getPlaybackvolume();
+ int vol = audioPlayer!=null ? audioPlayer.getPlaybackvolume() : 0;
return new WebsocketReply("GET VOLUME", String.valueOf(vol));
case "PLAY AUDIO" :
if (ValidInteger(command.data)){
@@ -391,7 +521,7 @@ public class Main {
if (afp!=null){
audioFileProperties = afp;
audioPlayer.PlayAudioFile(afp, true, pe);
- AmplifierControl(true);
+ //AmplifierControl(true);
return new WebsocketReply("PLAY AUDIO", afp.filename);
} else return new WebsocketReply("PLAY AUDIO", "Failed to open audio file "+filename);
@@ -403,18 +533,18 @@ public class Main {
audioPlayer.CloseAudioFile(audioFileProperties); // close previous audio file
String filename = audioFileProperties.filename;
audioFileProperties = null;
- AmplifierControl(false);
+ //AmplifierControl(false);
return new WebsocketReply("STOP AUDIO", filename);
} else return new WebsocketReply("STOP AUDIO", "No audioFileProperties");
// ZOOM Related Commands
case "GET MAX ZOOM":
if (vapixProtocol!=null){
- Blink(LedIpCamera);
+ Blink_LedIpCamera();
return new WebsocketReply("GET MAX ZOOM", String.valueOf(vapixProtocol.GetPTZMaxZoom()));
} else return new WebsocketReply("GET MAX ZOOM", "VapixProtocol not initialized");
case "GET ZOOM":
if (vapixProtocol!=null){
- Blink(LedIpCamera);
+ Blink_LedIpCamera();
return new WebsocketReply("GET ZOOM", String.valueOf(vapixProtocol.GetCurrentZoomValue()));
} else return new WebsocketReply("GET ZOOM", "VapixProtocol not initialized");
case "SET ZOOM":
@@ -424,7 +554,7 @@ public class Main {
if (zoomvapixProtocol.GetPTZMaxZoom()) zoom = vapixProtocol.GetPTZMaxZoom();
if (vapixProtocol.Zoom(1, zoom)){
- Blink(LedIpCamera);
+ 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");
@@ -432,15 +562,21 @@ public class Main {
// Live Streaming Related Commands
case "GET BASE64":
if (rtspGrabber!=null){
- if (Objects.equals(command.data,"HQ"))
- return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
- else
- return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
+ switch (command.data){
+ case "HQ":
+ return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastHQBase64(), rtspGrabber.HQStreamingStatus());
+ case "LQ":
+ return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastLQBase64(), rtspGrabber.LQStreamingStatus());
+ case "YOLO":
+ return new WebsocketReply("GET BASE64", "data:image/jpeg;base64,"+ rtspGrabber.getLastYoloBase64(), rtspGrabber.HQStreamingStatus());
+ default:
+ return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
+ }
} else return new WebsocketReply("GET BASE64", "RTSP Grabber not initialized");
case "GET RESOLUTION":
if (vapixProtocol!=null){
int[] res = vapixProtocol.GetCurrentResolution(1);
- Blink(LedIpCamera);
+ Blink_LedIpCamera();
return new WebsocketReply("GET RESOLUTION", String.format("%dx%d", res[0], res[1]));
} else return new WebsocketReply("GET RESOLUTION", "VapixProtocol not initialized");
case "GET AUDIOFILES":