edit : ward_id 적용 (정의된 상수값 사용)

This commit is contained in:
2026-03-04 16:54:28 +09:00
parent 0b446eed54
commit d2a84c1da0
4 changed files with 60 additions and 16 deletions

37
cctv.py
View File

@@ -116,12 +116,14 @@ class CameraStream:
print(f"[{self.name}] 재접속 실패")
def get_frame(self):
"""현재 저장된 가장 최신 프레임을 반환 (타임아웃 체크 포함)"""
"""
현재 저장된 가장 최신 프레임을 반환 (타임아웃 체크 포함)
"""
with self.lock:
# 마지막 수신 후 3초 이상 지났으면 신호 없음(False) 처리
if time.time() - self.last_read_time > 3.0:
return False, None
return self.ret, self.latest_frame
return False, None, self.name
return self.ret, self.latest_frame, self.name
def stop(self):
self.running = False
@@ -153,6 +155,8 @@ def main():
DISPLAY_TURN_ON = CFG.get('display').get('turn_on') # display 출력 여부
SNAPSHOT_SEND = CFG.get('img_snap_shot')
current_cam_index = 0 # 현재 보고 있는 카메라 인덱스
last_switch_time = time.time() # 마지막 전환 시간
switch_interval = SWITCH_INTERVAL # 5초마다 자동 전환
@@ -168,6 +172,10 @@ def main():
fps_count = 0
warmup_frames = 30 # 초반 불안정한 프레임 제외
# pubilsh time check
last_publish_time = None
delay_after_publish = 4.0 # publish 후 n초 동안은 추가 publish 금지, 0일경우 무제한
print("\n=== CCTV 시스템 시작 ===")
print(f"{switch_interval}초마다 자동으로 카메라가 전환됩니다.")
if DISPLAY_TURN_ON:
@@ -212,7 +220,7 @@ def main():
# 2. 현재 선택된 카메라의 최신 프레임 가져오기
target_cam = cameras[current_cam_index]
ret, frame = target_cam.get_frame()
ret, frame, name = target_cam.get_frame()
if ret and frame is not None:
# FPS 계산
@@ -248,11 +256,29 @@ def main():
od_message = []
parser.set(msg=hpe_message,img=frame)
parser.set(
msg=hpe_message,
img=frame if SNAPSHOT_SEND else None,
ward_id=name)
parsing_msg = parser.parse()
#mqtt publish
if parsing_msg is not None:
#time check
if last_publish_time is None:
last_publish_time = datetime.now()
mqtt_publisher.client.publish(MQTT_TOPIC, parsing_msg, qos=1)
else:
current_time = datetime.now()
time_diff = current_time - last_publish_time
time_diff_seconds = time_diff.total_seconds()
# n초에 한 번만 publish
if time_diff_seconds < delay_after_publish:
pass
else:
last_publish_time = datetime.now()
mqtt_publisher.client.publish(MQTT_TOPIC, parsing_msg, qos=1)
# 탐지 결과 라벨링 (원본 좌표 기준)
@@ -299,7 +325,6 @@ def main():
cv2.imshow(window_name, frame)
elif DISPLAY_TURN_ON:
# 신호가 없을 때 보여줄 대기 화면
# MONITOR_RESOLUTION은 (width, height)이므로 numpy shape는 (height, width, 3)이어야 함

View File

@@ -16,6 +16,7 @@ use_hpe_frame_check: false # n개 프레임 체크 후 HPE 위험 판단
# --- 디버그 ---
add_cross_arm: false # cross arm 디버그 모드
img_snap_shot: false # 이미지 스냅샷 전송 여부
# --- 소스 설정 ---
# RTSP 카메라 프리셋 (source에서 프리셋 이름으로 사용 가능)
@@ -75,8 +76,8 @@ cctv:
# - {src: 0, name: "Realtek_Webcam_0"}
# - {src: "rtsp://daool:Ekdnfeldpsdptm1@192.168.200.101/axis-media/media.amp", name: "ipcam_1"}
# - {src: "rtsp://daool:Ekdnfeldpsdptm1@192.168.200.102/axis-media/media.amp", name: "ipcam_2"}
- {src: "rtsp://192.168.200.231:50199/wd", name: "dev1_stream"}
- {src: "rtsp://192.168.200.232:50299/wd", name: "dev2_stream"}
# - {src: "rtsp://192.168.200.231:50199/wd", name: "dev1_stream"}
# - {src: "rtsp://192.168.200.232:50299/wd", name: "dev2_stream"}
# - {src: "rtsp://192.168.200.236:8554/videodevice", name: "boss_webcam"}
# - {src: "rtsp://192.168.200.236:8554/1.mp4", name: "boss_stream1"}
# - {src: "rtsp://192.168.200.214/1.mp4", name: "sgm_stream1"}
@@ -85,3 +86,17 @@ cctv:
# - {src: "rtsp://192.168.200.111/2.mp4", name: "hp_stream2"}
# - {src: "rtsp://192.168.200.215/1.mp4", name: "msk_stream1"}
# - {src: "rtsp://192.168.200.215/2.mp4", name: "msk_stream2"}
- {src: "rtsp://192.168.200.233:50399/h1", name: "dev3_stream_hospital_1"}
- {src: "rtsp://192.168.200.233:50399/h2", name: "dev3_stream_hospital_2"}
- {src: "rtsp://192.168.200.233:50399/h3", name: "dev3_stream_hospital_3"}
- {src: "rtsp://192.168.200.233:50399/h4", name: "dev3_stream_hospital_4"}
- {src: "rtsp://192.168.200.233:50399/h5", name: "dev3_stream_hospital_5"}
- {src: "rtsp://192.168.200.233:50399/h6", name: "dev3_stream_hospital_6"}
# - {src: "rtsp://192.168.200.233:50399/k1", name: "dev3_stream_kepco_1"}
# - {src: "rtsp://192.168.200.233:50399/k2", name: "dev3_stream_kepco_2"}
# - {src: "rtsp://192.168.200.233:50399/k3", name: "dev3_stream_kepco_3"}
# - {src: "rtsp://192.168.200.233:50399/k4", name: "dev3_stream_kepco_4"}
# - {src: "rtsp://192.168.200.233:50399/k5", name: "dev3_stream_kepco_5"}
# - {src: "rtsp://192.168.200.233:50399/k6", name: "dev3_stream_kepco_6"}

View File

@@ -11,14 +11,18 @@ class ParsingMsg():
def __init__(self):
self.msg = None
self.img = None
self.ward_id = None
self.parsed_msg = None
def set(self, msg:list, img):
def set(self, msg:list, img, ward_id):
self.msg = None
self.img = None
self.ward_id = None
self.msg = msg
self.img = img
self.ward_id = ward_id
self.parsed_msg = None
def get(self):
@@ -33,7 +37,7 @@ class ParsingMsg():
"""
_, JPEG = cv2.imencode(".jpg", img_data, [int(cv2.IMWRITE_JPEG_QUALITY), 80])
# Base64 encode
b64 = b64encode(JPEG)
b64 = b64encode(JPEG.tobytes())
return b64.decode("utf-8")
@@ -54,7 +58,7 @@ class ParsingMsg():
"""
msg = Header(
camera_id= "CAMERA_001",
ward_id= "WARD_001",
ward_id= self.ward_id,
timestamp= datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
frame_id= 0
)

View File

@@ -7,8 +7,8 @@ from datetime import datetime
#=========================================
class Header(BaseModel):
camera_id: str
ward_id: str
timestamp: datetime
ward_id: str | None
timestamp: str
frame_id: int
#=========================================