Fixed build dist containing the correct structure and be able to build zip files explicitly.

Also fixed some compile warnings
This commit is contained in:
Ziver Koc 2025-12-18 03:47:54 +01:00
parent c7f0d4e8b3
commit 1779916d97
111 changed files with 254 additions and 162 deletions

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016 Daniel Collin, Ziver Koc Copyright (c) 2016-2025 Daniel Collin, Ziver Koc
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -65,6 +65,11 @@ subprojects {
} }
} }
} }
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:deprecation"
//options.compilerArgs << "-Xlint:unchecked"
}
} }
// ------------------------------------ // ------------------------------------
@ -78,34 +83,44 @@ dependencies {
} }
distributions { distributions {
distTar.enabled = false
distZip.enabled = false
main { main {
contents { contents {
// from root project
from 'hal.conf.example' from 'hal.conf.example'
from 'logging.properties' from 'logging.properties'
from 'run.sh'
from sourceSets.main.output.resourcesDir // from subprojects
}
}
}
task copyRecources(type: Copy) {
doFirst{
System.out.println("Copying resource files...")
}
project.subprojects.each { subProject -> project.subprojects.each { subProject ->
from "${subProject.projectDir}/resources" into('bin') {
from "${subProject.projectDir}/resources/bin"
}
into('web') {
from "${subProject.projectDir}/resources/web"
}
into('resources') {
from ("${subProject.projectDir}/resources") {
exclude 'bin'
exclude 'web'
}
}
}
}
}
} }
into(sourceSets.main.output.resourcesDir) distTar.enabled = false
} distZip.enabled = false
assemble.dependsOn(installDist)
jar.dependsOn(copyRecources) project.gradle.startParameter.taskNames.each { taskName ->
copyRecources.mustRunAfter(processResources) if (taskName == 'distZip') {
distZip.enabled = true
}
}
application { application {
mainClass = 'se.hal.HalServer' mainClass = 'se.hal.HalServer'
} }
startScripts.enabled = false

View file

@ -1,27 +1,3 @@
<!--
~ The MIT License (MIT)
~
~ Copyright (c) 2025 Ziver Koc
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<h1 class="page-header">Event Configuration</h1> <h1 class="page-header">Event Configuration</h1>
<div class="col-md-12"> <div class="col-md-12">

View file

@ -1,27 +1,3 @@
<!--
~ The MIT License (MIT)
~
~ Copyright (c) 2025 Ziver Koc
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>

View file

@ -1,27 +1,3 @@
<!--
~ The MIT License (MIT)
~
~ Copyright (c) 2025 Ziver Koc
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
~ THE SOFTWARE.
-->
<h1 class="page-header">Sensor Configuration</h1> <h1 class="page-header">Sensor Configuration</h1>
<div class="col-md-12"> <div class="col-md-12">

View file

@ -1,3 +1,27 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2025 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal; package se.hal;
import zutil.ObjectUtil; import zutil.ObjectUtil;
@ -22,6 +46,7 @@ public class HalContext {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
// Constants // Constants
public static final String CONFIG_HTTP_PORT = "hal_core.http_port"; public static final String CONFIG_HTTP_PORT = "hal_core.http_port";
public static final String CONFIG_HTTP_EXTERNAL_PORT = "hal_core.http_external_port"; public static final String CONFIG_HTTP_EXTERNAL_PORT = "hal_core.http_external_port";
public static final String CONFIG_HTTP_EXTERNAL_DOMAIN = "hal_core.http_external_domain"; public static final String CONFIG_HTTP_EXTERNAL_DOMAIN = "hal_core.http_external_domain";
@ -29,22 +54,25 @@ public class HalContext {
public static final String CONFIG_DNS_LOCAL_DOMAIN = "hal_core.dns_local_domain"; public static final String CONFIG_DNS_LOCAL_DOMAIN = "hal_core.dns_local_domain";
public static final String CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage"; public static final String CONFIG_MAP_BACKGROUND_IMAGE = "hal_core.map_bgimage";
public static final String RESOURCE_ROOT; // Path Constants
public static final String RUNTIME_ROOT;
static { static {
if (FileUtil.find("build/resources/") != null) // Development environment if (FileUtil.find("build/install/Hal") != null) // Development environment
RESOURCE_ROOT = "build/resources"; RUNTIME_ROOT = "build/install/Hal";
else if (FileUtil.find("resources/") != null) // Release package environment
RESOURCE_ROOT = "resources";
else else
RESOURCE_ROOT = "."; RUNTIME_ROOT = ".";
} }
public static final String RESOURCE_WEB_ROOT = HalContext.RESOURCE_ROOT + "/web"; public static final String RESOURCE_ROOT = HalContext.RUNTIME_ROOT + "/resources";
public static final String RESOURCE_WEB_ROOT = HalContext.RUNTIME_ROOT + "/web";
public static final String RESOURCE_BIN_ROOT = HalContext.RUNTIME_ROOT + "/bin";
private static final String CONF_FILE = "hal.conf"; private static final String CONF_FILE = RUNTIME_ROOT + "/hal.conf";
static final String DB_FILE = "hal.db"; static final String DB_FILE = RUNTIME_ROOT + "/hal.db";
// Variables // Variables
private static DBConnection db; // TODO: Should probably be a db pool as we have multiple threads accessing the DB private static DBConnection db; // TODO: Should probably be a db pool as we have multiple threads accessing the DB
private static HashMap<String,String> registeredConf = new HashMap<>(); private static HashMap<String,String> registeredConf = new HashMap<>();

View file

@ -1,3 +1,27 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2025 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.nvr.rtsp; package se.hal.plugin.nvr.rtsp;
import se.hal.HalContext; import se.hal.HalContext;
@ -21,11 +45,11 @@ import java.util.logging.Logger;
public class RTSPCameraRecorder implements Runnable { public class RTSPCameraRecorder implements Runnable {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private static final File FFMPEG_BINARY_PATH = FileUtil.find(HalContext.RESOURCE_ROOT + "/bin/"); private static final File FFMPEG_BINARY_PATH = FileUtil.find(HalContext.RESOURCE_BIN_ROOT);
private RTSPCameraConfig camera; private RTSPCameraConfig camera;
private String storagePath; private String storagePath;
private Process process; private Process ffmpegProcess;
public RTSPCameraRecorder(RTSPCameraConfig camera, String storagePath) { public RTSPCameraRecorder(RTSPCameraConfig camera, String storagePath) {
@ -64,42 +88,46 @@ public class RTSPCameraRecorder implements Runnable {
"-var_stream_map \"v:0,a:0,name:Source v:1,a:1,name:720p v:2,a:2,name:360p\"" "-var_stream_map \"v:0,a:0,name:Source v:1,a:1,name:720p v:2,a:2,name:360p\""
);*/ );*/
ffmpegOutput.addAdditionalArg( ffmpegOutput.addAdditionalArg(
"-c:v:0 libx264 -x264-params \"nal-hrd=cbr:force-cfr=1\" -b:v:0 5M -maxrate:v:0 5M -minrate:v:0 5M -bufsize:v:0 10M -preset veryfast -g 25 -sc_threshold 0" "-c:v:0", "libx264",
"-x264-params", "nal-hrd=cbr:force-cfr=1",
"-b:v:0", "5M",
"-maxrate:v:0", "5M",
"-minrate:v:0", "5M",
"-bufsize:v:0", "10M",
"-preset", "veryfast",
"-g", "25",
"-sc_threshold", "0"
); );
ffmpegOutput.addAdditionalArg("-f hls", ffmpegOutput.addAdditionalArg("-f", "hls",
"-hls_time 2", // segment length in seconds "-hls_time", "2", // segment length in seconds
//"-hls_playlist_type event", // Do not delete old segments //"-hls_playlist_type", "event", // Do not delete old segments
"-hls_flags independent_segments+delete_segments", "-hls_flags", "independent_segments+delete_segments",
"-hls_segment_type mpegts", "-hls_segment_type", "mpegts",
"-hls_segment_filename \"" + new File(storagePath, "stream_%v/data%02d.ts").getPath() + "\"", "-hls_segment_filename", new File(storagePath, "stream_%v/data%02d.ts").getPath(),
"-master_pl_name \"playlist.m3u8\"" "-master_pl_name", "playlist.m3u8"
); );
FFmpeg ffmpeg = new FFmpeg(); FFmpeg ffmpeg = new FFmpeg();
ffmpeg.setLogLevel(FFmpegConstants.FFmpegLogLevel.ERROR); ffmpeg.setLogLevel(FFmpegConstants.FFmpegLogLevel.ERROR);
ffmpeg.addInput(ffmpegInput); ffmpeg.addInput(ffmpegInput);
ffmpeg.addOutput(ffmpegOutput); ffmpeg.addOutput(ffmpegOutput);
String cmdParams = ffmpeg.buildCommand();
// ---------------------------------- // ----------------------------------
// Execute command // Execute command
// ---------------------------------- // ----------------------------------
File cmdPath = OSALBinaryManager.getPath(FFMPEG_BINARY_PATH, "ffmpeg");
String cmd = cmdPath.getParent() + File.separator + cmdParams;
logger.finest("Executing ffmpeg: " + cmd);
Runtime.getRuntime().addShutdownHook(new Thread() { Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { public void run() {
if (process != null) process.destroyForcibly(); if (ffmpegProcess != null) ffmpegProcess.destroyForcibly();
} }
}); });
process = Runtime.getRuntime().exec(cmd); File cmdPath = OSALBinaryManager.getPath(FFMPEG_BINARY_PATH, "ffmpeg");
BufferedReader output = new BufferedReader(new InputStreamReader(process.getErrorStream())); ffmpegProcess = ffmpeg.execute(cmdPath);
while (process.isAlive()) { BufferedReader output = new BufferedReader(new InputStreamReader(ffmpegProcess.getInputStream()));
while (ffmpegProcess.isAlive()) {
String line; String line;
while ((line = output.readLine()) != null) { while ((line = output.readLine()) != null) {
logger.finest("[Cam: " + camera.getRtspUrl() + "] " + line); logger.finest("[Cam: " + camera.getRtspUrl() + "] " + line);
@ -107,6 +135,7 @@ public class RTSPCameraRecorder implements Runnable {
Thread.sleep(1000); Thread.sleep(1000);
} }
output.close(); output.close();
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "RTSP Stream recording thread has crashed for: " + camera.getRtspUrl(), e); logger.log(Level.SEVERE, "RTSP Stream recording thread has crashed for: " + camera.getRtspUrl(), e);
@ -124,10 +153,10 @@ public class RTSPCameraRecorder implements Runnable {
} }
public void close() { public void close() {
if (process != null) { if (ffmpegProcess != null) {
logger.info("Killing ffmpeg instance."); logger.info("Killing FFmpeg instance.");
camera = null; camera = null;
process.destroy(); ffmpegProcess.destroyForcibly();
} }
} }
} }

View file

@ -1,3 +1,27 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2025 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.raspberry.hardware; package se.hal.plugin.raspberry.hardware;
import com.pi4j.io.gpio.*; import com.pi4j.io.gpio.*;
@ -32,7 +56,7 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
this.controller = controller; this.controller = controller;
this.gpioPin = gpioPin; this.gpioPin = gpioPin;
// setup a thread pool for executing jobs // Setup a thread pool for executing jobs
this.executorPool = Executors.newCachedThreadPool(); this.executorPool = Executors.newCachedThreadPool();
//Enable non privileged access to the GPIO pins (no sudo required from now) //Enable non privileged access to the GPIO pins (no sudo required from now)
@ -45,9 +69,6 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
} catch(IllegalArgumentException e) { } catch(IllegalArgumentException e) {
logger.log(Level.SEVERE, "", e); logger.log(Level.SEVERE, "", e);
throw e; throw e;
}catch(UnsatisfiedLinkError e) {
logger.log(Level.SEVERE, "", e);
throw e;
} }
// provision gpio pin as an input pin with its internal pull up resistor enabled // provision gpio pin as an input pin with its internal pull up resistor enabled
@ -73,9 +94,8 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
@Override @Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
if (event.getState() == PinState.LOW) { //low = light went on if (event.getState() == PinState.LOW) { //low = light went on
//System.out.println("IR LED turned ON");
//logger.log(Level.INFO, "IR LED turned on"); //logger.log(Level.INFO, "IR LED turned on");
synchronized(impulseCount) { synchronized(this) {
impulseCount++; impulseCount++;
} }
} }
@ -84,19 +104,24 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
@Override @Override
public void run() { public void run() {
long startTime = System.nanoTime(); long startTime = System.nanoTime();
synchronized(impulseCount) {
synchronized(this) {
impulseCount = 0; //reset the impulse count impulseCount = 0; //reset the impulse count
} }
while (!executorPool.isShutdown()) { while (!executorPool.isShutdown()) {
sleepNano(nanoSecondsSleep); //sleep for some time. This variable will be modified every loop to compensate for the loop time spent. sleepNano(nanoSecondsSleep); //sleep for some time. This variable will be modified every loop to compensate for the loop time spent.
int count = -1; int count = -1;
synchronized(impulseCount) {
synchronized(this) {
count = impulseCount; count = impulseCount;
impulseCount = 0; impulseCount = 0;
} }
save(System.currentTimeMillis(), count); //save the impulse count
report(count, System.currentTimeMillis()); //save the impulse count
long estimatedNanoTimeSpent = System.nanoTime() - startTime; //this is where the loop ends long estimatedNanoTimeSpent = System.nanoTime() - startTime; //this is where the loop ends
startTime = System.nanoTime(); //this is where the loop starts from now on startTime = System.nanoTime(); //this is where the loop starts from now on
if (estimatedNanoTimeSpent > 0) { //if no overflow if (estimatedNanoTimeSpent > 0) { //if no overflow
long nanoSecondsTooMany = estimatedNanoTimeSpent - (REPORT_TIMEOUT*1000000L); long nanoSecondsTooMany = estimatedNanoTimeSpent - (REPORT_TIMEOUT*1000000L);
//System.out.println("the look took ~" + estimatedNanoTimeSpent + "ns. That is " + nanoSecondsTooMany/1000000L + "ms off"); //System.out.println("the look took ~" + estimatedNanoTimeSpent + "ns. That is " + nanoSecondsTooMany/1000000L + "ms off");
@ -107,10 +132,10 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
/** /**
* Sleep for [ns] nanoseconds * Sleep for [ns] nanoseconds
* @param ns *
* @param ns nanoseconds to sleep
*/ */
private void sleepNano(long ns) { private void sleepNano(long ns) {
//System.out.println("will go to sleep for " + ns + "ns");
try{ try{
Thread.sleep(ns/1000000L, (int)(ns%1000000L)); Thread.sleep(ns/1000000L, (int)(ns%1000000L));
}catch(InterruptedException e) { }catch(InterruptedException e) {
@ -119,25 +144,21 @@ public class RPiInteruptPulseFlankCounter implements Runnable, GpioPinListenerDi
} }
/** /**
* Saves the data to the database. * Report back some data to Hal Core,
* This method should block the caller as short time as possible.
* This method should try block the same amount of time every time it is called.
* Try to make the time spent in the method the same for every call (low variation).
* *
* @param timestamp_end * @param data The data to report back to Hal.
* @param data * @param timestamp The timestamp of the received data
*/ */
private void save(final long timestamp_end, final int data) { private void report(final int data, final long timestamp) {
//offload the timed loop by not doing the db interaction in this thread. // Offload the timed loop by not doing the db interaction in this thread.
executorPool.execute(new Runnable() { executorPool.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
logger.log(Level.INFO, "Reporting data. timestamp_end="+timestamp_end+", data="+data); logger.log(Level.INFO, "Reporting data. timestamp_end=" + timestamp + ", data=" + data);
controller.sendDataReport( controller.sendDataReport(
new RPiPowerConsumptionSensor(gpioPin), new RPiPowerConsumptionSensor(gpioPin),
new PowerConsumptionSensorData( new PowerConsumptionSensorData(data, timestamp)
timestamp_end, data );
));
} }
}); });
} }

View file

@ -1,5 +1,7 @@
/* /*
* Copyright (c) 2015 Ziver * The MIT License (MIT)
*
* Copyright (c) 2015-2025 Ziver Koc
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -113,7 +115,7 @@ public class TellstickParser {
public static void registerProtocol(Class<? extends TellstickProtocol> protClass) { public static void registerProtocol(Class<? extends TellstickProtocol> protClass) {
try { try {
registerProtocol(protClass.newInstance()); registerProtocol(protClass.getDeclaredConstructor().newInstance());
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, null, e); logger.log(Level.SEVERE, null, e);
} }

View file

@ -1,3 +1,27 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2025 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.zigbee; package se.hal.plugin.zigbee;
@ -110,7 +134,7 @@ public class ZigbeeController implements HalSensorController,
// Register extensions // Register extensions
ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension(); ZigBeeDiscoveryExtension discoveryExtension = new ZigBeeDiscoveryExtension();
discoveryExtension.setUpdatePeriod(86400); // in seconds, 24h discoveryExtension.setUpdateMeshPeriod(86400); // in seconds, 24h
networkManager.addExtension(discoveryExtension); networkManager.addExtension(discoveryExtension);
networkManager.addExtension(new ZigBeeOtaUpgradeExtension()); networkManager.addExtension(new ZigBeeOtaUpgradeExtension());
@ -404,7 +428,7 @@ public class ZigbeeController implements HalSensorController,
@Override @Override
public void attributeUpdated(ZclAttribute attribute, Object value) { public void attributeUpdated(ZclAttribute attribute, Object value) {
logger.finer("[Node: " + endpoint.getIeeeAddress() + ", Endpoint: " + endpoint.getEndpointId() + ", Cluster: " + attribute.getCluster().getId() + "] Attribute " + config.getClass().getSimpleName() + " updated: id=" + attribute.getId() + ", attribute_name=" + attribute.getName() + ", value=" + attribute.getLastValue()); logger.finer("[Node: " + endpoint.getIeeeAddress() + ", Endpoint: " + endpoint.getEndpointId() + ", Cluster: " + attribute.getClusterType().getId() + "] Attribute " + config.getClass().getSimpleName() + " updated: id=" + attribute.getId() + ", attribute_name=" + attribute.getName() + ", value=" + attribute.getLastValue());
HalDeviceData data = config.getDeviceData(endpoint, attribute); HalDeviceData data = config.getDeviceData(endpoint, attribute);
if (data != null) { if (data != null) {

Some files were not shown because too many files have changed in this diff Show more