package art.servers.gost.access.controller;
|
|
import art.library.interop.serialization.Serialization;
|
import art.library.model.devices.DeviceStatus;
|
import art.library.model.devices.gost.access.AccessEnforcement;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection_Image;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection_State;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection_State_Vehicle;
|
import art.library.model.devices.gost.access.types.AccessEnforcement_Detection_VPV;
|
import art.servers.gost.access.Shared;
|
import art.servers.gost.access.types.DatabasePoolConnection;
|
import com.xuggle.mediatool.IMediaWriter;
|
import com.xuggle.mediatool.ToolFactory;
|
import com.xuggle.xuggler.ICodec;
|
import com.xuggle.xuggler.IRational;
|
import java.awt.image.BufferedImage;
|
import java.io.File;
|
import java.io.IOException;
|
import java.nio.file.Files;
|
import java.nio.file.StandardCopyOption;
|
import java.time.LocalDateTime;
|
import java.time.ZoneId;
|
import java.time.format.DateTimeFormatter;
|
import java.util.stream.Stream;
|
import javax.imageio.ImageIO;
|
|
|
public class Controller_ACCESS_VPV extends Controller_ACCESS
|
{
|
|
|
|
private static final int VIDEO_FRAME_RATE = 1;
|
|
private static final String REG_DIR = "/REG";
|
private static final String LOG_DIR = "/LOG";
|
private static final String AMB_DIR = "/FOTO/AMB";
|
private static final String AMB2_DIR = "/FOTO/AMB2";
|
private static final String LPR_DIR = "/FOTO/LPR";
|
|
public Controller_ACCESS_VPV(AccessEnforcement access, DatabasePoolConnection database)
|
{
|
super(access, database);
|
this.setName(Shared.getMessage("Controller VPV") + " " + access.information.name);
|
}
|
|
public AccessEnforcement getAccessEnforcement()
|
{
|
return (AccessEnforcement)getDevice();
|
}
|
|
public void run()
|
{
|
Shared.traceInformation(getName(), Shared.getMessage("Starting"));
|
|
initialise();
|
|
while ((isInterrupted() == false) && (exit == false))
|
{
|
try
|
{
|
if (Shared.isServerEnabled() == true)
|
{
|
update();
|
}
|
}
|
catch (Exception exception)
|
{
|
exception.printStackTrace();
|
}
|
|
try
|
{
|
sleep(1000);
|
}
|
catch (Exception e)
|
{
|
|
}
|
|
if (Shared.model.existsDevice(this.getAccessEnforcement().getIdentifier()) == false)
|
{
|
Shared.traceInformation(getName(), Shared.getMessage("Device no longer exists"));
|
exit = true;
|
}
|
}
|
|
Shared.traceInformation(getName(), Shared.getMessage("Finishing"));
|
}
|
|
private void online(AccessEnforcement clon) throws Exception
|
{
|
clon.setAlarm("alarm_offline", false);
|
clon.setAlarm("alarm_invalid", false);
|
clon.getDeviceStatus().status = DeviceStatus.STATUS_ONLINE;
|
Shared.model.updateDevice(getAccessEnforcement(), clon);
|
}
|
|
private void update() throws Exception
|
{
|
AccessEnforcement clon = Serialization.clone(getAccessEnforcement());
|
online(clon);
|
|
File detectionsPath = new File(clon.getDeviceInformation().vpv.path);
|
|
if(detectionsPath.listFiles() == null)
|
return;
|
|
for(File detectionDateDir : detectionsPath.listFiles())
|
{
|
File regFileDir = new File(detectionDateDir.getPath() + REG_DIR);
|
File ambFileDir = new File(detectionDateDir.getPath() + AMB_DIR);
|
File amb2FileDir = new File(detectionDateDir.getPath() + AMB2_DIR);
|
File lprFileDir = new File(detectionDateDir.getPath() + LPR_DIR);
|
|
if(regFileDir.listFiles() == null)
|
continue;
|
|
for (File regFile : regFileDir.listFiles())
|
{
|
if(regFile.exists() == false)
|
continue;
|
|
String[] regCSV = Files.readAllLines(regFile.toPath())
|
.get(0)
|
.split(",");
|
|
|
|
AccessEnforcement_Detection detection = getDetection(regCSV, lprFileDir, ambFileDir, amb2FileDir);
|
|
updateDatabaseDetection(getAccessEnforcement().getDeviceInformation(), detection);
|
|
moveFiles(detectionDateDir, regCSV[0]);
|
|
}
|
}
|
}
|
|
|
|
public AccessEnforcement_Detection getDetection(String[] regCSV, File lprFileDir, File ambFileDir, File amb2FileDir) throws IOException
|
{
|
String number = regCSV[0];
|
String plate = regCSV[1];
|
String exitDate = regCSV[2];
|
String exitTime = regCSV[3];
|
String entryDate = regCSV[5];
|
String entryTime = regCSV[6];
|
|
String exitImagePath = lprFileDir.getPath() + "/" + number + "/" + regCSV[4];
|
String entryImagePath = lprFileDir.getPath() + "/" + number + "/" + regCSV[7];
|
|
File[] imageFilesAMB = new File(ambFileDir.getPath() + "/" + number).listFiles();
|
File[] imageFilesAMB2 = new File(amb2FileDir.getPath() + "/" + number).listFiles();
|
|
AccessEnforcement_Detection detection = new AccessEnforcement_Detection();
|
{
|
detection.device = getAccessEnforcement().getDeviceInformation();
|
detection.timestamp = getEpochDatetime(entryDate, entryTime);
|
|
AccessEnforcement_Detection_State detectionState = new AccessEnforcement_Detection_State();
|
{
|
detectionState.timestamp = getEpochDatetime(entryDate, entryTime);
|
|
detectionState.vehicle = new AccessEnforcement_Detection_State_Vehicle();
|
{
|
detectionState.vehicle.plate = plate.toUpperCase();
|
detectionState.vehicle.confidence = 100f;
|
}
|
}
|
detection.states.add(detectionState);
|
|
detection.vpv = new AccessEnforcement_Detection_VPV();
|
{
|
detection.vpv.entryIdentifier = getAccessEnforcement().getDeviceInformation().vpv.vpvs[0];
|
detection.vpv.exitIdentifier = getAccessEnforcement().getDeviceInformation().vpv.vpvs[1];
|
|
detection.vpv.entryLocation = getAccessEnforcement().getDeviceInformation().location;
|
detection.vpv.exitLocation = getAccessEnforcement().getDeviceInformation().location;
|
|
detection.vpv.entryTimestamp = getEpochDatetime(entryDate, entryTime);
|
detection.vpv.exitTimestamp = getEpochDatetime(exitDate, exitTime);
|
}
|
|
AccessEnforcement_Detection_Image imageEntryLPR = new AccessEnforcement_Detection_Image();
|
{
|
imageEntryLPR.format = AccessEnforcement_Detection_Image.FORMAT_JPG;
|
imageEntryLPR.data = Files.readAllBytes(new File(entryImagePath).toPath());
|
imageEntryLPR.name = Shared.getMessage("Plate entry");
|
}
|
|
AccessEnforcement_Detection_Image imageExitLPR = new AccessEnforcement_Detection_Image();
|
{
|
imageExitLPR.format = AccessEnforcement_Detection_Image.FORMAT_JPG;
|
imageExitLPR.data = Files.readAllBytes(new File(exitImagePath).toPath());
|
imageExitLPR.name = Shared.getMessage("Plate exit");
|
}
|
|
AccessEnforcement_Detection_Image videoAMB = new AccessEnforcement_Detection_Image();
|
{
|
videoAMB.format = AccessEnforcement_Detection_Image.FORMAT_AVI;
|
videoAMB.data = encodeVideoFile(imageFilesAMB);
|
videoAMB.name = Shared.getMessage("Video entry");
|
}
|
|
AccessEnforcement_Detection_Image videoAMB2 = new AccessEnforcement_Detection_Image();
|
{
|
videoAMB2.format = AccessEnforcement_Detection_Image.FORMAT_AVI;
|
videoAMB2.data = encodeVideoFile(imageFilesAMB2);
|
videoAMB2.name = Shared.getMessage("Video exit");
|
}
|
|
detection.images.add(imageEntryLPR);
|
detection.images.add(imageExitLPR);
|
detection.images.add(videoAMB);
|
detection.images.add(videoAMB2);
|
}
|
|
return detection;
|
}
|
|
private byte[] encodeVideoFile(File[] imageFiles) throws IOException
|
{
|
String outputFile = imageFiles[0].getParent() + "/temp.avi";
|
|
IMediaWriter writer = ToolFactory.makeWriter(outputFile);
|
|
IRational rationalFrameRate = IRational.make(VIDEO_FRAME_RATE, 1);
|
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, rationalFrameRate, 1280, 720);
|
|
int index = 0;
|
|
for (File imgFile : Stream.of(imageFiles).filter(file -> file.getPath().endsWith(".jpg")).toArray(File[]::new))
|
{
|
BufferedImage image;
|
|
try {
|
image = ImageIO.read(imgFile);
|
}
|
catch (IOException e) {
|
break;
|
}
|
|
long timeStamp = index * (1000 / VIDEO_FRAME_RATE);
|
writer.encodeVideo(0, image, timeStamp, java.util.concurrent.TimeUnit.MILLISECONDS);
|
|
index++;
|
}
|
|
writer.close();
|
|
byte[] data = Files.readAllBytes(new File(outputFile).toPath());
|
|
Files.delete(new File(outputFile).toPath());
|
|
return data;
|
}
|
|
private static long getEpochDatetime(String date, String time)
|
{
|
LocalDateTime localDateTime = LocalDateTime.parse(date + " " + time, DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss.[SSS][SS][S]"));
|
|
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
}
|
|
|
private String getProcessedDetectionsPath(String sourcePath)
|
{
|
return sourcePath.replace("\\", "/")
|
.replace(getAccessEnforcement().getDeviceInformation().vpv.path,
|
getAccessEnforcement().getDeviceInformation().storage.processedFolder);
|
}
|
|
private void moveToProcessed(File file)
|
{
|
try
|
{
|
File destinationFile = new File(getProcessedDetectionsPath(file.getPath()));
|
|
if (Files.exists(destinationFile.getParentFile().toPath()) == false)
|
{
|
Files.createDirectories(destinationFile.getParentFile().toPath());
|
}
|
|
Files.move(file.toPath(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
|
} catch (Exception ex){}
|
}
|
|
private void moveFiles(File detectionDate, String csv) throws IOException
|
{
|
String parentDir = detectionDate.getPath();
|
String detectionNumber = csv.split(",")[0];
|
|
File regFile = new File(parentDir + REG_DIR + "/" + detectionNumber + ".txt");
|
File logFile = new File(parentDir + LOG_DIR + "/log" + detectionNumber + ".log");
|
|
File ambDir = new File(parentDir + AMB_DIR + "/" + detectionNumber);
|
File amb2Dir = new File(parentDir + AMB2_DIR + "/" + detectionNumber);
|
File lprDir = new File(parentDir + LPR_DIR + "/" + detectionNumber);
|
|
moveToProcessed(regFile);
|
moveToProcessed(logFile);
|
|
Stream.of(ambDir.listFiles())
|
.forEach(this::moveToProcessed);
|
|
Stream.of(amb2Dir.listFiles())
|
.forEach(this::moveToProcessed);
|
|
Stream.of(lprDir.listFiles())
|
.forEach(this::moveToProcessed);
|
|
}
|
|
|
}
|