
    j5L                        d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlmZ d dl	m
Z
mZmZ d:dZd;dZd<dZd=dZd>dZd?d@dZdAd"ZdBdCd$ZdDd%ZdDd&ZdEdFd)Zd*ZdGd-ZdHd/ZdId0ZdJd3ZdKd6ZdLd7ZdDd8ZdMd9Z dS )N    )annotationsN)datetime)logger)execute	query_all	query_oneschemastrtablereturnboolc                    d}	 t          t          || |d                    S # t          $ r"}t          j        d| ||           Y d }~dS d }~ww xY w)Nz
        SELECT 1 AS exists
        FROM information_schema.tables
        WHERE table_schema = %(s)s
          AND table_name = %(t)s
        LIMIT 1
    stz*Table existence probe failed for %s.%s: %sF)r   r   	Exceptionr   warningr	   r   sqlexcs       N/home/longshao/multi-rider-rag/modules/dashboard/services/alert_rule_engine.py_table_existsr      sr    CIce#<#<==>>>   CVUTWXXXuuuuus   $ 
AAAtablestuple[str, str]c                 4    t          d | D                       S )Nc              3  <   K   | ]\  }}t          ||          V  d S N)r   ).0r	   r   s      r   	<genexpr>z _tables_exist.<locals>.<genexpr>   s0      HH}VU++HHHHHH    )all)r   s    r   _tables_existr"      s    HHHHHHHHr    set[str]c                    d}	 d t          || |d          D             S # t          $ r/}t          j        d| ||           t	                      cY d }~S d }~ww xY w)Nz
        SELECT column_name
        FROM information_schema.columns
        WHERE table_schema = %(s)s
          AND table_name = %(t)s
    c                |    h | ]9}|                     d           t          |                     d                     :S )column_name)getr
   r   rows     r   	<setcomp>z!_table_columns.<locals>.<setcomp>(   sA    {{{dgdkdklydzdz{CGGM**++{{{r    r   z!Column probe failed for %s.%s: %s)r   r   r   r   setr   s       r   _table_columnsr,       s~    C{{yFY^F_F_7`7`{{{{   :FE3OOOuus   ! 
A$AAAnamec                T    dt          |                               dd          z   dz   S )N"z"")r
   replace)r-   s    r   _quote_identr1   .   s(    T""3---33r    columns
candidatestuple[str, ...]
str | Nonec                    d | D             }|D ]4}|                                 |v r||                                          c S 5d S )Nc                8    i | ]}|                                 |S  lower)r   columns     r   
<dictcomp>z&_pick_first_column.<locals>.<dictcomp>3   s"    >>>F>>>r    r9   )r2   r3   	lower_map	candidates       r   _pick_first_columnr?   2   s^    >>g>>>I 0 0	??	))Y__..//// *4r       
alert_typezjhmlocationwindow_minutesintc                   ddg}| |d}|r|                     d           ||d<   |r|                     d           ||d<   d                    d	                    |          
          }t          t	          ||                    S )Nzalert_type = %(alert_type)szMtrigger_time >= CURRENT_TIMESTAMP - make_interval(mins => %(window_minutes)s))rA   rD   zzjhm = %(zjhm)srB   zlocation = %(location)srC   zx
        SELECT 1 AS exists
        FROM "jcgkzx_monitor"."wcnr_alert"
        WHERE {where_clause}
        LIMIT 1
    z AND )where_clause)appendformatjoinr   r   )rA   rB   rC   rD   
conditionsparamsr   s          r   _alert_existsrM   :   s    %WJ
 !( F  +,,,v &3444%z
 	GLL4455  	#v&&'''r    xmalert_levelalert_contentc                    t          || |          rdS d}| ||||||d}	 t          ||          dk    S # t          $ r"}	t          j        d|| |	           Y d }	~	dS d }	~	ww xY w)NFa  
        INSERT INTO "jcgkzx_monitor"."wcnr_alert"
            (zjhm, xm, alert_type, alert_level, alert_content, location, trigger_time)
        VALUES
            (%(zjhm)s, %(xm)s, %(alert_type)s, %(alert_level)s,
             %(alert_content)s, %(location)s, %(trigger_time)s)
    rB   rN   rA   rO   rP   rC   trigger_timer   z'Insert alert failed type=%s zjhm=%s: %s)rM   r   r   r   r   )
rB   rN   rA   rO   rP   rC   rS   r   rL   r   s
             r   _insert_alertrT   S   s     Zx00 uC  "&$ FsF##a''   @*dTWXXXuuuuus   5 
A!AA!   c                   t          dddd          sdS d}d}t          |dt          dt          | pd	                    i          D ]~}|                    d
          }|                    d          pd}|                    d          p|}|sHt          ||dd| d| d||                    d                    }|r|dz  }|S )Njcgkzx_monitorwcnr_ryrl_gjrX   
wcnr_scorerX   wcnr_target_poolrX   
wcnr_alertr   a  
        SELECT g.zjhm, p.xm, g.device_name, g.shot_time, s.total_score
        FROM "jcgkzx_monitor"."wcnr_ryrl_gj" g
        JOIN "jcgkzx_monitor"."wcnr_score" s
          ON s.zjhm = g.zjhm
        LEFT JOIN "jcgkzx_monitor"."wcnr_target_pool" p
          ON p.zjhm = g.zjhm
        WHERE g.shot_time >= CURRENT_TIMESTAMP - make_interval(mins => %(window_minutes)s)
          AND s.total_score >= 80
          AND g.zjhm IS NOT NULL
        ORDER BY g.shot_time DESC
        LIMIT 200
    rD      rU   rB   device_nameu   未知设备rN   high_risk_face_hitcriticalu    在 u    出现	shot_timerR   )r"   r   maxrE   r'   rT   )rD   r   countr)   rB   ra   rN   inserteds           r   scan_high_risk_face_hitrh   w   s   *(.(	   qC E/QN<Oa8P8P1Q1QRSS  wwvggm,,>WWT]]"d 	 +"::k::: --
 
 
  	QJELr    c                    t          dddd          sdS d} d}t          |           D ]}|                    d          pd}t          |                    d	          pd          }t          |                    d
          pd          }t	          d |                    d          pddd| d| d| d||                    d                    }|r|dz  }|S )NrW   rZ   r\   r^   r   u  
        WITH recent AS (
            SELECT g.device_name,
                   g.zjhm,
                   COALESCE(p.xm, g.zjhm) AS xm,
                   g.shot_time,
                   COALESCE(s.total_score, 0) AS total_score
            FROM "jcgkzx_monitor"."wcnr_ryrl_gj" g
            LEFT JOIN "jcgkzx_monitor"."wcnr_score" s
              ON s.zjhm = g.zjhm
            LEFT JOIN "jcgkzx_monitor"."wcnr_target_pool" p
              ON p.zjhm = g.zjhm
            WHERE g.shot_time >= CURRENT_TIMESTAMP - INTERVAL '30 minutes'
              AND (EXTRACT(HOUR FROM g.shot_time) >= 22 OR EXTRACT(HOUR FROM g.shot_time) < 6)
              AND g.device_name IS NOT NULL
              AND g.zjhm IS NOT NULL
        )
        SELECT device_name,
               COUNT(DISTINCT zjhm) AS person_count,
               COUNT(DISTINCT CASE WHEN total_score >= 60 THEN zjhm END) AS high_risk_count,
               MAX(shot_time) AS last_time,
               STRING_AGG(DISTINCT xm, '、') AS names
        FROM recent
        GROUP BY device_name
        HAVING COUNT(DISTINCT zjhm) >= 3
           AND COUNT(DISTINCT CASE WHEN total_score >= 60 THEN zjhm END) >= 2
        ORDER BY last_time DESC
        LIMIT 50
    ra   u   未知地点person_counthigh_risk_countnamesu   多人聚集night_aggregationr   u    夜间聚集 u    人，其中高风险 u    人	last_timerR   r`   )r"   r   r'   rE   rT   )r   rf   r)   ra   rj   rk   rg   s          r   scan_night_aggregationro      s   *(.(	   qC: E~~  ggm,,>377>227a88cgg&788=A>> www1>*!(rrrr]lrrr --
 
 
  	QJELr    c                    t          ddd          sdS t          dd          } t          dd          }| rd	nd
}|rdnd
}g }| r|                    d           |r|                    ddg           |r(d                    d                    |                    nd}d                    |||          }d}t          |          D ]}|                    d          }	|                    d          p|                    d          pd}
|	sF|                    d          p|	}t          |	|dd| d|
 d|
|                    d                    }|r|dz  }|S ) N)rX   wcnr_ly_checkinr\   r^   r   ywdatab_per_qskjwcnrrX   	wcnr_czrkz8LEFT JOIN "ywdata"."b_per_qskjwcnr" f ON f.zjhm = c.zjhm z;LEFT JOIN "jcgkzx_monitor"."wcnr_czrk" r ON r.zjhm = c.zjhmzf.jhr1xmzr.fqxmzr.mqxmzCOALESCE({})z, zNULL::VARCHARa  
        WITH checkins AS (
            SELECT c.zjhm,
                   p.xm,
                   c.lgmc,
                   c.lgdz,
                   c.rzsj,
                   c.tfrxm,
                   {guardian_expr} AS guardian_name
            FROM "jcgkzx_monitor"."wcnr_ly_checkin" c
            JOIN "jcgkzx_monitor"."wcnr_target_pool" p
              ON p.zjhm = c.zjhm
            {family_join}
            {basic_join}
            WHERE c.rzsj >= CURRENT_TIMESTAMP - INTERVAL '24 hours'
              AND c.zjhm IS NOT NULL
        )
        SELECT *
        FROM checkins
        WHERE NULLIF(BTRIM(COALESCE(tfrxm, '')), '') IS NULL
           OR guardian_name IS NULL
           OR tfrxm <> guardian_name
        ORDER BY rzsj DESC
        LIMIT 100
    )guardian_exprfamily_join
basic_joinrB   lgmclgdzu   旅馆rN   abnormal_hotel_checkinr   u    入住u   ，同住人异常rzsjrR   r`   )	r"   r   rH   extendrI   rJ   r   r'   rT   )
has_family	has_basicrw   rx   guardian_partsrv   r   rf   r)   rB   
hotel_namerN   rg   s                r   scan_abnormal_hotel_checkinr      s   -.(  
 qx)9::J.<<IPZbLL`bKR[cNNacJN *j))) 4x2333HVkN))$))N*C*CDDD\kM0 	# 	 	 	1 : E~~  wwvWWV__CC8
 	WWT]]"d /!FF
FFF
 
 
  	QJELr       radius_mc                   t          ddddd          sdS t          dd          }t          |d	          }t          |d
          }|r|st          j        d           dS t          |d          }|rdt          |           nd}dt          |           }dt          |           }	 t          dt          | pd                    }n# t          t          f$ r d}Y nw xY wd}	d| d| d| d| d| d|	 d}
d}	 t          |
d|i          }n-# t          $ r }t          j        d|           Y d }~dS d }~ww xY w|D ]}|                    d          }|                    d          p|}|                    d          pd}	 t          t          |                    d          pd                    }n# t          t          f$ r d}Y nw xY wt!          ||d d!| d"| d#| d$||                    d%          &          }|r|dz  }|S )'NrW   rZ   r\   r^   )rr   sh_fzxxsj_xxr   rr   r   )jdlng	longitudeu   经度)wdlatlatitudeu   纬度zPSchool perimeter rule skipped: ywdata.sh_fzxxsj_xx has no usable lng/lat columns)xxmcxxjcschool_namer-   mcu   学校名称zs.u   '学校'r`   r   a  
        2 * 6371000 * ASIN(SQRT(LEAST(1,
            POWER(SIN(RADIANS((r.lat - school.school_lat) / 2)), 2)
            + COS(RADIANS(school.school_lat)) * COS(RADIANS(r.lat))
            * POWER(SIN(RADIANS((r.lng - school.school_lng) / 2)), 2)
        )))
    z-
        WITH school AS (
            SELECT z AS xxmc,
                   z5::DOUBLE PRECISION AS school_lng,
                   z^::DOUBLE PRECISION AS school_lat
            FROM "ywdata"."sh_fzxxsj_xx" s
            WHERE z IS NOT NULL
              AND aZ   IS NOT NULL
        ),
        recent AS (
            SELECT g.zjhm,
                   COALESCE(p.xm, g.xm, g.zjhm) AS xm,
                   g.device_name,
                   g.shot_time,
                   g.jd::DOUBLE PRECISION AS lng,
                   g.wd::DOUBLE PRECISION AS lat
            FROM "jcgkzx_monitor"."wcnr_ryrl_gj" g
            JOIN "jcgkzx_monitor"."wcnr_score" sc
              ON sc.zjhm = g.zjhm
            LEFT JOIN "jcgkzx_monitor"."wcnr_target_pool" p
              ON p.zjhm = g.zjhm
            WHERE g.shot_time >= CURRENT_TIMESTAMP - INTERVAL '1 hour'
              AND sc.total_score >= 80
              AND g.zjhm IS NOT NULL
              AND g.jd IS NOT NULL
              AND g.wd IS NOT NULL
        ),
        hits AS (
            SELECT r.zjhm, r.xm, r.device_name, r.shot_time, school.xxmc,
                   z AS dist
            FROM recent r
            CROSS JOIN school
        )
        SELECT *
        FROM hits
        WHERE dist <= %(radius_m)s
        ORDER BY shot_time DESC
        LIMIT 200
    r   z&School perimeter rule query failed: %srB   rN   r   u   学校distschool_perimeter_high_riskr   u    出现在学校 u	    周边 ~u   米rd   rR   )r"   r,   r?   r   infor1   re   rE   	TypeError
ValueErrorr   r   r   r'   roundfloatrT   )r   r2   lng_collat_colname_colschool_name_exprlng_exprlat_exprsafe_radius	dist_exprr   rf   rowsr   r)   rB   rN   r   distancerg   s                       r   scan_school_perimeterr      s   *(.("   qX~66G *NOOG *MNNG ' fgggq!'+hiiH8@P4L22444j+L))++H+L))++H!SS1122z"   I&$& & & & 	& & & & & &: ;& & &CP Ez;788   ?EEEqqqqq   wwvWWT]]"dggfoo1	U3776??#7a8899HH:& 	 	 	HHH	 3!UU+UUUUU --
 
 
  	QJELs<   +C C! C!>D 
D;D66D;1F88GG)u   飙车u	   翘车头u   炸街r)   dictc                J     d}d                      fd|D                       S )N)category
class_namelabeltype
event_typeillegal_typesource_name	device_idra   summary_textclasses_raw	model_key c              3  `   K   | ](}t                              |          pd           V  )dS )ru   N)r
   r'   )r   fieldr)   s     r   r   z_row_text.<locals>.<genexpr>  s:      BB%C,"--BBBBBBr    )rJ   )r)   fieldss   ` r   	_row_textr     s3    F
 88BBBB6BBBBBBr    r   c                    dD ]B}|                      |          }|	 t          |          c S # t          t          f$ r Y ?w xY wdS )N)
confidenceconfscoreprobabilityg        )r'   r   r   r   r)   keyvalues      r   _row_confidencer     si    =  =	<<:& 	 	 	H	3s   /AAc                    dD ]i}|                      |          }|t          |t          t          f          r0	 t	          j        |          c S # t          t          f$ r Y  d S w xY w|c S t	          j                    S )N)rS   detected_at
created_atend_timeend_tsstart_ts)	r'   
isinstancerE   r   r   fromtimestampOSErrorr   nowr   s      r   _row_trigger_timer     s    ^ 	 	=ec5\** 	-e44444Z(   ttt<>>s   AA&%A&min_confidencelist[dict] | Nonec                   	 t          j        d          }n# t          $ r Y d S w xY wdD ]}t          ||d           }t	          |          s#d| |dfd| |dfdddifdi ffD ]^\  }}	  ||i |}|d |D             c c S # t
          $ r Y -t          $ r&}t          j        d	||           g cY d }~c c S d }~ww xY wt          j        d
           g S )Nz3modules.detection.repositories.ai_result_repository)list_recent_resultsget_recent_resultsquery_recent_resultsfind_recent_resultsr8   )rD   r   )minutesr   limitr   c                ,    g | ]}t          |          S r8   )r   r(   s     r   
<listcomp>z._call_detection_repository.<locals>.<listcomp>  s    222cS		222r    z'Detection repository call %s failed: %sz=Detection repository has no supported recent-result interface)		importlibimport_moduler   getattrcallabler   r   r   r   )	rD   r   repor-   funcargskwargsr   r   s	            r   _call_detection_repositoryr     sy   &'\]]   tt m  tT4((~~ 	NnUUV^>JJK'3 H	
 	 	LD&	tT,V,,<22T22222222      H$PSTTT											  KOPPPIs6    
%%)
B4B
B?	B?B:0B?:B?job
list[dict]c                   |                      d          }|rt          j                            |          sg S 	 t	          |dd          5 }t          j        |          }d d d            n# 1 swxY w Y   n/# t          $ r"}t          j	        d||           g cY d }~S d }~ww xY wg }|                     d          pg D ]}t          |t                    s|                     d          p+|                     d          p|                     d	          pg }|ri|D ]e}t          |t                    rNt          |           }	|	                    |           |	                    |           |                    |	           ft          |           }	|	                    |           |                    |	           |S )
Nresult_manifest_pathrzutf-8)encodingz%Read detection manifest failed %s: %sitems
detectionsboxesresults)r'   ospathisfileopenjsonloadr   r   r   r   r   updaterH   )
r   manifest_pathfhmanifestr   r   itemr   	detectionr)   s
             r   _manifest_detection_rowsr     s   GG233M } = = 	-w777 	%2y}}H	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	%   >sSSS						 DW%%+  $%% 	XXl++]txx/@/@]DHHYDWDW][]
 
	' % %	i.. %s))CJJt$$$JJy)))KK$$$% s))CJJtKKKsA   A9 A-!A9 -A11A9 4A15A9 9
B%B B% B%c                   	 ddl m} n.# t          $ r!}t          j        d|           g cY d }~S d }~ww xY wt          j                    t          dt          | pd                    dz  z
  }g }	  |d          }n.# t          $ r!}t          j        d	|           g cY d }~S d }~ww xY w|D ] }|	                    d
          p|	                    d          pd}	 t          |pd          |k     rFn# t          t          f$ r Y Zw xY wt          |	                    d          pd          dvrt          |          }	|	r|                    |	           t          |	                    d          pd          dk    rt!          |          }
t          |	                    d          pd          |
d<   |                    |
           "fd|D             S )Nr   )list_all_jobsz+SQLite detection job reader unavailable: %sr`   rU   <   d   )r   zList detection jobs failed: %sr   r   statusru   >   done	completedkeptconf_threshr   c                :    g | ]}t          |          k    |S r8   )r   )r   r)   r   s     r   r   z*_sqlite_detection_rows.<locals>.<listcomp>
  s+    JJJC?3#7#7>#I#IC#I#I#Ir    )shared.db.sqliter   r   r   r   timere   rE   r   r'   r   r   r   r
   r   r}   r   rH   )rD   r   r   r   cutoffr   jobsr   r   manifest_rowsr)   s    `         r   _sqlite_detection_rowsr    s@   2222222   A3GGG						 Y[[3q#n&9":":;;b@@FD}3'''   7===						   "">cggj&9&9>Q	V[q!!F** +:& 	 	 	H	swwx  &B''/DDD055 	KK&&&swwv#!$$))3ii!#''-"8"8"=A>>LCJJJJ4JJJJsD   
 
50551A> >
B)B$B)$B)C55D	D	c                 V  	 t          dd          sdS d} d}t          | |          }|st          | |          }|st          j        d           dS d}|D ]Q}t          |          	t          |                    d          pd                                          }t          	fd	t          D                       s|d
k    rot          |          }||k     r|                    d          p)|                    d          p|                    d          }|st          |                    d          |                    d          ddd| |                    d          p#|                    d          pt          |          t          |                    }|r|dz  }S|S )NrX   r_   r   rU   g333333?zOSpeeding detection rule skipped: no detection repository rows or SQLite resultsr   ru   c              3      K   | ]}|v V  	d S r   r8   )r   keywordtexts     r   r   z*scan_speeding_detection.<locals>.<genexpr>  s'      DDw7d?DDDDDDr    bczjr   ra   r   rB   rN   speeding_detectedr   u   飙车检测命中 device=rR   r`   )r   r   r  r   r   r   r
   r'   r:   anySPEEDING_KEYWORDSr   rT   r   )
rD   r   r   rf   r)   r   r   r   rg   r  s
            @r   scan_speeding_detectionr    s   )<88 qNN%nnEED F%nnEE efffqE  ~~,,23399;;	DDDD2CDDDDD 	V\I\I\$S))
&&GGK((\CGGM,B,B\cggmF\F\	 	 wwt}}*!ByBBWW]++Wsww}/E/EWY*3//
 
 
  	QJELr    c                     t           t          t          t          t          d} i }|                                 D ]E\  }}	  |            ||<   # t          $ r%}t          j        d||           d||<   Y d }~>d }~ww xY w|S )N)rb   rm   r{   r   r	  zAlert rule %s failed: %sr   )	rh   ro   r   r   r  r   r   r   r   )rulesresultr-   r   r   s        r   run_all_rulesr  4  s    53"=&;4 E Fkkmm  
d	466F4LL 	 	 	N5tSAAAF4LLLLLL	 Ms   A
A;A66A;)r	   r
   r   r
   r   r   )r   r   r   r   )r	   r
   r   r
   r   r#   )r-   r
   r   r
   )r2   r#   r3   r4   r   r5   )r@   )
rA   r
   rB   r5   rC   r5   rD   rE   r   r   )rB   r5   rN   r5   rA   r
   rO   r
   rP   r
   rC   r5   r   r   )rU   )rD   rE   r   rE   )r   rE   )r   )r   rE   r   rE   )r)   r   r   r
   )r)   r   r   r   )r)   r   )rD   rE   r   r   r   r   )r   r   r   r   )rD   rE   r   r   r   r   )r   r   )!
__future__r   r   r   r   r   r   shared.config.configr   shared.db.kingbaser   r   r   r   r"   r,   r1   r?   rM   rT   rh   ro   r   r   r  r   r   r   r   r   r  r  r  r8   r    r   <module>r     s9   " " " " " "      				        ' ' ' ' ' ' < < < < < < < < < <   I I I I   4 4 4 4   ( ( ( ( (2! ! ! !H( ( ( ( (V6 6 6 6rB B B BJd d d d dN 6 C C C C	 	 	 	      <   <!K !K !K !KH$ $ $ $N     r    