commit 16/06/2025
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import database.ContactInputData;
|
||||
import database.Database;
|
||||
import gpio.NanopiGpio;
|
||||
import mqtt.MqttClient;
|
||||
import org.tinylog.Logger;
|
||||
import pa.VX3K;
|
||||
import pa.VX3KPseudoContactInput;
|
||||
|
||||
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
|
||||
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||
@@ -10,13 +13,21 @@ public class Main {
|
||||
private static MqttClient mqttClient;
|
||||
private static NanopiGpio gpio;
|
||||
private static Database db;
|
||||
private static VX3K vx3K;
|
||||
// Application entry point
|
||||
public static void main(String[] args) {
|
||||
Logger.info("Application started");
|
||||
|
||||
// initialize config
|
||||
config = new config();
|
||||
|
||||
// initialize database
|
||||
db = new Database();
|
||||
//db.contactInputDataList.forEach(System.out::println);
|
||||
|
||||
// initialize VX3K
|
||||
vx3K = new VX3K(config.getVX3KTargetIP(), config.getVX3KTargetPort());
|
||||
|
||||
// Initialize the GPIO pins
|
||||
gpio = new NanopiGpio();
|
||||
// cek di https://wiki.friendlyelec.com/wiki/index.php/NanoPi_Duo20
|
||||
@@ -29,17 +40,41 @@ public class Main {
|
||||
}, pinStatus -> {
|
||||
// TODO Handle pin status updates here
|
||||
Logger.info("Gpio {}, Description {}, status updated to {}", pinStatus.getGpioNumber(), pinStatus.getDescription(), pinStatus.getStatus());
|
||||
// MQTT publish pin status update
|
||||
if (mqttClient != null && mqttClient.isConnected()) mqttClient.Publish(config.getMQTT_Topic(), config.getMQTT_ClientID(),
|
||||
String.format("Gpio %d, Description %s, Status %d", pinStatus.getGpioNumber(), pinStatus.getDescription(), pinStatus.getStatus()),
|
||||
published -> {
|
||||
if (published) {
|
||||
Logger.info("Pin status update published successfully.");
|
||||
|
||||
ContactInputData cib = db.GetContactInputData(pinStatus.getDescription());
|
||||
if (cib!=null){
|
||||
if (cib.isEnableMQTT()){
|
||||
// MQTT publish pin status update
|
||||
if (mqttClient != null && mqttClient.isConnected()) mqttClient.Publish(config.getMQTT_Topic(), config.getMQTT_ClientID(),
|
||||
String.format("Gpio %d, Description %s, Status %d", pinStatus.getGpioNumber(), pinStatus.getDescription(), pinStatus.getStatus()),
|
||||
published -> {
|
||||
if (published) {
|
||||
Logger.info("Pin status update published successfully.");
|
||||
} else {
|
||||
Logger.error("Failed to publish pin status update.");
|
||||
}
|
||||
});
|
||||
}
|
||||
if (cib.isEnableEmail()){
|
||||
// Email notification can be added here
|
||||
}
|
||||
if (cib.isEnableVX3K()){
|
||||
// VX3K Broadcast here
|
||||
VX3KPseudoContactInput cmd = new VX3KPseudoContactInput(cib.getVX3KFrameID(), cib.getVX3KContactID(), pinStatus.getStatus()==1);
|
||||
vx3K.PseudoContactInput(cmd, result -> {
|
||||
if (result.success()){
|
||||
Logger.info("VX3K PseudoContactInput successfully executed.");
|
||||
} else {
|
||||
Logger.error("Failed to publish pin status update.");
|
||||
Logger.error("VX3K PseudoContactInput failed to execute, Message {}.", result.message());
|
||||
}
|
||||
});
|
||||
// Email notification can be added here
|
||||
}
|
||||
if (cib.isEnableModbus()){
|
||||
// update Modbus Register here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
import com.google.gson.Gson;
|
||||
|
||||
|
||||
|
||||
public class Somecodes {
|
||||
|
||||
public static String currentdirectory = System.getProperty("user.dir");
|
||||
public static Gson gson = new Gson();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ import java.util.List;
|
||||
public class Database {
|
||||
|
||||
private static final String DB_NAME = "jdbc:sqlite:database.sqlite";
|
||||
private final int maxContactInputData = 16; // Maximum number of contact input data
|
||||
public final List<ContactInputData> contactInputDataList = new ArrayList<>();
|
||||
public Database(){
|
||||
CreateContactInputDataTable();
|
||||
@@ -83,6 +82,8 @@ public class Database {
|
||||
return loadedData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load ContactInputData into the contactInputDataList.
|
||||
* @param loadedData List of ContactInputData objects loaded from the database.
|
||||
@@ -90,6 +91,8 @@ public class Database {
|
||||
@SuppressWarnings("ExtractMethodRecommender")
|
||||
private void LoadContactInputDataList(List<ContactInputData> loadedData){
|
||||
contactInputDataList.clear();
|
||||
// Maximum number of contact input data
|
||||
int maxContactInputData = 16;
|
||||
for (int i = 1; i <= maxContactInputData; i++){
|
||||
final int contactID = i;
|
||||
ContactInputData cid = loadedData.stream()
|
||||
@@ -151,6 +154,24 @@ public class Database {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ContactInputData by ID
|
||||
* @param contactID ID to get
|
||||
* @return ContactInputData object if exists, or null if not exists
|
||||
*/
|
||||
public ContactInputData GetContactInputData(int contactID){
|
||||
return contactInputDataList.stream().filter(x -> x.getContactID() == contactID).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ContactInputData by description
|
||||
* @param description Description to get
|
||||
* @return ContactInputData if exists, or null if not exists
|
||||
*/
|
||||
public ContactInputData GetContactInputData(String description){
|
||||
return contactInputDataList.stream().filter(x -> x.getDescription().equals(description)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the content of a specific ContactInputData entry in the database.
|
||||
* @param contactID The ID of the ContactInputData entry to be cleared.
|
||||
|
||||
43
src/pa/VX3K.java
Normal file
43
src/pa/VX3K.java
Normal file
@@ -0,0 +1,43 @@
|
||||
package pa;
|
||||
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class VX3K {
|
||||
private final InetSocketAddress inetSocketAddress;
|
||||
|
||||
public VX3K(String ipaddress, int port){
|
||||
this.inetSocketAddress = new InetSocketAddress(ipaddress, port);
|
||||
}
|
||||
|
||||
public void PseudoContactInput(VX3KPseudoContactInput input, @NonNull Consumer<@NonNull VX3KCommandResult> callback){
|
||||
|
||||
try(SocketChannel channel = SocketChannel.open(inetSocketAddress)){
|
||||
channel.write(input.getBuffer());
|
||||
input.getBuffer().clear();
|
||||
int read = channel.read(input.getBuffer());
|
||||
if (read>0){
|
||||
short command = input.getBuffer().getShort(0);
|
||||
short responsecode = input.getBuffer().getShort(1);
|
||||
if (command == input.getCommandID()){
|
||||
if (responsecode == 0x0000){
|
||||
callback.accept(new VX3KCommandResult(input.getCommandID(), true, "success"));
|
||||
} else callback.accept(new VX3KCommandResult(input.getCommandID(), false , "Code:"+responsecode ));
|
||||
} else callback.accept(new VX3KCommandResult(input.getCommandID(), false, "Invalid CommandID reply"));
|
||||
} else callback.accept( new VX3KCommandResult(input.getCommandID(), false, "Read 0"));
|
||||
} catch (Exception e){
|
||||
Logger.error("PseudoContactInput failed, Message {}", e.getMessage());
|
||||
callback.accept(new VX3KCommandResult(input.getCommandID(), false, "Exception"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
4
src/pa/VX3KCommandResult.java
Normal file
4
src/pa/VX3KCommandResult.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package pa;
|
||||
|
||||
public record VX3KCommandResult(int command, boolean success, String message) {
|
||||
}
|
||||
23
src/pa/VX3KPseudoContactInput.java
Normal file
23
src/pa/VX3KPseudoContactInput.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package pa;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class VX3KPseudoContactInput{
|
||||
private final @Getter int CommandID;
|
||||
private final @Getter ByteBuffer buffer;
|
||||
public VX3KPseudoContactInput(int FrameID, int contactID, boolean isON){
|
||||
final int length = 8 + 6; // 8 bytes header + 6 bytes payload
|
||||
CommandID = 0x1001;
|
||||
buffer = ByteBuffer.allocate(length);
|
||||
buffer.putShort((short) CommandID);
|
||||
buffer.putShort((short) 0);
|
||||
buffer.putShort((short) length);
|
||||
buffer.putShort((short) 0x8000);
|
||||
buffer.putShort((short) FrameID);
|
||||
buffer.putShort((short) contactID);
|
||||
buffer.putShort((short)(isON ? 1 : 0));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user