forked from dsutanto/karung-masuk_frigate-counter
SOme improvement
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -174,3 +174,6 @@ cython_debug/
|
|||||||
# PyPI configuration file
|
# PyPI configuration file
|
||||||
.pypirc
|
.pypirc
|
||||||
|
|
||||||
|
#
|
||||||
|
karung_counters.json
|
||||||
|
karung_counts.db
|
||||||
|
|||||||
@@ -28,10 +28,12 @@ class FrigateCounter:
|
|||||||
# MQTT configuration from environment variables
|
# MQTT configuration from environment variables
|
||||||
self.frigate_mqtt_host = os.environ.get('FRIGATE_MQTT_HOST', 'localhost')
|
self.frigate_mqtt_host = os.environ.get('FRIGATE_MQTT_HOST', 'localhost')
|
||||||
self.frigate_mqtt_port = int(os.environ.get('FRIGATE_MQTT_PORT', 1883))
|
self.frigate_mqtt_port = int(os.environ.get('FRIGATE_MQTT_PORT', 1883))
|
||||||
self.report_mqtt_host = os.environ.get('REPORT_MQTT_HOST', 'localhost')
|
self.report_mqtt_host = os.environ.get('REPORT_MQTT_HOST', 'mqtt.backone.cloud')
|
||||||
self.report_mqtt_port = int(os.environ.get('REPORT_MQTT_PORT', 1883))
|
self.report_mqtt_port = int(os.environ.get('REPORT_MQTT_PORT', 1883))
|
||||||
self.topic = os.environ.get('TOPIC', 'frigate')
|
self.top_topic = os.environ.get("TOP_TOPIC", "cpsp")
|
||||||
self.site_name = os.environ.get('SITE_NAME', 'default')
|
self.site_name = os.environ.get('SITE_NAME', 'sukawarna')
|
||||||
|
self.topic = os.environ.get('TOPIC', f"{self.top_topic}/counter/{self.site_name}")
|
||||||
|
self.camera_name = os.environ.get('CAMERA_NAME', 'kandang_1_karung_masuk_test')
|
||||||
|
|
||||||
# Database setup
|
# Database setup
|
||||||
self.db_path = 'karung_counts.db'
|
self.db_path = 'karung_counts.db'
|
||||||
@@ -48,6 +50,7 @@ class FrigateCounter:
|
|||||||
self.timer_start_time = None
|
self.timer_start_time = None
|
||||||
self.counter = 0
|
self.counter = 0
|
||||||
self.counter_lock = threading.Lock()
|
self.counter_lock = threading.Lock()
|
||||||
|
self.seen_objects = {}
|
||||||
|
|
||||||
# Load previous counter value on startup
|
# Load previous counter value on startup
|
||||||
self.load_previous_counter()
|
self.load_previous_counter()
|
||||||
@@ -60,7 +63,7 @@ class FrigateCounter:
|
|||||||
self.setup_mqtt_clients()
|
self.setup_mqtt_clients()
|
||||||
|
|
||||||
# Schedule daily reset at midnight
|
# Schedule daily reset at midnight
|
||||||
schedule.every().day.at("00:00").do(self.reset_counter)
|
schedule.every().day.at("23:59").do(self.reset_counter)
|
||||||
|
|
||||||
def init_database(self):
|
def init_database(self):
|
||||||
"""Initialize SQLite database with required table"""
|
"""Initialize SQLite database with required table"""
|
||||||
@@ -117,23 +120,50 @@ class FrigateCounter:
|
|||||||
"""Handle incoming Frigate MQTT messages"""
|
"""Handle incoming Frigate MQTT messages"""
|
||||||
try:
|
try:
|
||||||
# Parse the message (assuming JSON format)
|
# Parse the message (assuming JSON format)
|
||||||
import json
|
#import json
|
||||||
data = json.loads(msg.payload.decode())
|
payload = json.loads(msg.payload.decode())
|
||||||
|
|
||||||
|
if "after" not in payload:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
event_after = payload["after"]
|
||||||
|
event_before = payload.get("before", {})
|
||||||
|
|
||||||
|
camera_name = event_after.get("camera", "unknown")
|
||||||
|
event_type = event_after.get('type', '')
|
||||||
|
label = event_after.get("label", "")
|
||||||
|
track_id = event_after.get("id")
|
||||||
|
zones_after = event_after.get("entered_zones", [])
|
||||||
|
zones_before = event_before.get("entered_zones", [])
|
||||||
|
|
||||||
|
# Dont detect stationary
|
||||||
|
stationary = event_after.get("stationary")
|
||||||
|
if stationary:
|
||||||
|
return
|
||||||
|
|
||||||
|
new_zones = [z for z in zones_after if z not in zones_before]
|
||||||
|
|
||||||
|
# debounce per track_id
|
||||||
|
if camera_name not in self.seen_objects:
|
||||||
|
self.seen_objects[camera_name] = {}
|
||||||
|
if track_id in self.seen_objects[camera_name]:
|
||||||
|
return # sudah dihitung
|
||||||
|
|
||||||
# Extract object type and camera name
|
# Extract object type and camera name
|
||||||
camera_name = data.get('camera', 'unknown')
|
#camera_name = data.get('camera', 'unknown')
|
||||||
event_type = data.get('type', '')
|
#event_type = data.get('type', '')
|
||||||
label = data.get('label', '')
|
#label = data.get('label', '')
|
||||||
|
|
||||||
logger.debug(f"Received message: camera={camera_name}, type={event_type}, label={label}")
|
logger.debug(f"Received message: camera={camera_name}, type={event_type}, label={label}")
|
||||||
|
|
||||||
# Handle different object types
|
# Handle different object types
|
||||||
if label == "pintu-kiri-buka":
|
if label == "pintu-kiri-buka" and not self.timer_active:
|
||||||
self.handle_pintu_kiri_buka(camera_name)
|
self.handle_pintu_kiri_buka(camera_name)
|
||||||
elif label == "pintu-kanan-buka":
|
elif label == "pintu-kanan-buka" and not self.timer_active:
|
||||||
self.handle_pintu_kanan_buka(camera_name)
|
self.handle_pintu_kanan_buka(camera_name)
|
||||||
elif label == "karung":
|
elif label == "karung" and self.timer_active:
|
||||||
self.handle_karung(camera_name)
|
self.handle_karung(camera_name, track_id)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error processing MQTT message: {e}")
|
logger.error(f"Error processing MQTT message: {e}")
|
||||||
@@ -160,7 +190,7 @@ class FrigateCounter:
|
|||||||
else:
|
else:
|
||||||
logger.debug("Ignoring pintu-kanan-buka during timer period")
|
logger.debug("Ignoring pintu-kanan-buka during timer period")
|
||||||
|
|
||||||
def handle_karung(self, camera_name):
|
def handle_karung(self, camera_name, track_id):
|
||||||
"""Handle detection of karung object"""
|
"""Handle detection of karung object"""
|
||||||
logger.info(f"Detected karung on {camera_name}")
|
logger.info(f"Detected karung on {camera_name}")
|
||||||
|
|
||||||
@@ -168,7 +198,10 @@ class FrigateCounter:
|
|||||||
if self.timer_active:
|
if self.timer_active:
|
||||||
with self.counter_lock:
|
with self.counter_lock:
|
||||||
self.counter += 1
|
self.counter += 1
|
||||||
logger.info(f"Counter incremented to {self.counter}")
|
self.seen_objects[camera_name][track_id] = datetime.now()
|
||||||
|
self.save_to_json(camera_name)
|
||||||
|
self.publish_result()
|
||||||
|
logger.info(f"Counter incremented to {self.counter} and republish to MQTT")
|
||||||
else:
|
else:
|
||||||
logger.debug("Ignoring karung outside timer period")
|
logger.debug("Ignoring karung outside timer period")
|
||||||
|
|
||||||
@@ -199,13 +232,15 @@ class FrigateCounter:
|
|||||||
if self.timer_active:
|
if self.timer_active:
|
||||||
logger.info("Timer expired (30 minutes)")
|
logger.info("Timer expired (30 minutes)")
|
||||||
self.timer_active = False
|
self.timer_active = False
|
||||||
self.publish_result()
|
#self.publish_result()
|
||||||
self.reset_counter()
|
#self.reset_counter()
|
||||||
|
|
||||||
def publish_result(self):
|
def publish_result(self):
|
||||||
"""Publish counter result to MQTT topic"""
|
"""Publish counter result to MQTT topic"""
|
||||||
if self.counter > 0:
|
if self.counter > 0:
|
||||||
topic = f"{self.topic}/counter/{self.site_name}"
|
#topic = f"{self.topic}/{self.camera_name}/karung"
|
||||||
|
#TESTING
|
||||||
|
topic = f"{self.topic}/{self.camera_name}-check_pintu/karung"
|
||||||
message = str(self.counter)
|
message = str(self.counter)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -213,10 +248,10 @@ class FrigateCounter:
|
|||||||
logger.info(f"Published counter result to {topic}: {message}")
|
logger.info(f"Published counter result to {topic}: {message}")
|
||||||
|
|
||||||
# Save to database
|
# Save to database
|
||||||
self.save_to_database()
|
#self.save_to_database()
|
||||||
|
|
||||||
# Save to JSON for temporary persistent storage
|
# Save to JSON for temporary persistent storage
|
||||||
self.save_to_json('frigate_camera')
|
#self.save_to_json('frigate_camera')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error publishing result: {e}")
|
logger.error(f"Error publishing result: {e}")
|
||||||
@@ -281,7 +316,7 @@ class FrigateCounter:
|
|||||||
def load_previous_counter(self):
|
def load_previous_counter(self):
|
||||||
"""Load the previous counter value from JSON storage on startup"""
|
"""Load the previous counter value from JSON storage on startup"""
|
||||||
try:
|
try:
|
||||||
self.counter = self.load_from_json('frigate_camera')
|
self.counter = self.load_from_json(self.camera_name)
|
||||||
logger.info(f"Loaded previous counter value: {self.counter}")
|
logger.info(f"Loaded previous counter value: {self.counter}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error loading previous counter value: {e}")
|
logger.error(f"Error loading previous counter value: {e}")
|
||||||
@@ -314,6 +349,7 @@ class FrigateCounter:
|
|||||||
self.pintu_kanan_buka_detected = False
|
self.pintu_kanan_buka_detected = False
|
||||||
self.timer_active = False
|
self.timer_active = False
|
||||||
self.timer_start_time = None
|
self.timer_start_time = None
|
||||||
|
self.seen_objects = {}
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Main run loop"""
|
"""Main run loop"""
|
||||||
|
|||||||
Reference in New Issue
Block a user