diff --git a/apps/iot/include/iot.hrl b/apps/iot/include/iot.hrl index f9dfa82..fd99058 100644 --- a/apps/iot/include/iot.hrl +++ b/apps/iot/include/iot.hrl @@ -35,7 +35,7 @@ -define(METHOD_FEEDBACK_RESULT, 16#06). -define(METHOD_EVENT, 16#07). %% ai识别的事件上报 --define(METHOD_AI_EVENT, 16#08). +-define(METHOD_AI_EVENT, 17#08). %% 消息体类型 -define(PACKET_REQUEST, 16#01). diff --git a/apps/iot/src/endpoint/iot_donghuoliren_endpoint.erl b/apps/iot/src/endpoint/iot_donghuoliren_endpoint.erl index 07e179e..d03a979 100644 --- a/apps/iot/src/endpoint/iot_donghuoliren_endpoint.erl +++ b/apps/iot/src/endpoint/iot_donghuoliren_endpoint.erl @@ -99,21 +99,25 @@ handle_cast({forward, LocationCode, DynamicLocationCode, EventType, Params}, State = #state{url = Url, token = Token, location_map = LocationMap, logger_pid = LoggerPid, succ_counter = SuccCounter, fail_counter = FailCounter}) -> Location = maps:get(LocationCode, LocationMap, <<"">>), - Body = format_event(Location, DynamicLocationCode, EventType, Params), - %% 签名信息 - Sign = iot_util:md5(iolist_to_binary([Token, Body, Token])), - Url1 = Url ++ "?sign=" ++ binary_to_list(Sign), + case format_event(Location, DynamicLocationCode, EventType, Params) of + {ok, Body} -> + %% 签名信息 + Sign = iot_util:md5(iolist_to_binary([Token, Body, Token])), + Url1 = Url ++ "?sign=" ++ binary_to_list(Sign), - case do_post(Url1, Body) of - {ok, RespBody} -> - %% 记录日志 - iot_logger:write(LoggerPid, [<<"OK">>, list_to_binary(Url1), Body, RespBody]), - {noreply, State#state{succ_counter = SuccCounter + 1}}; - {error, Reason} -> - NReason = iolist_to_binary(io_lib:format("~p", [Reason])), - iot_logger:write(LoggerPid, [<<"ERROR">>, list_to_binary(Url1), Body, NReason]), - {noreply, State#state{fail_counter = FailCounter + 1}} - end. + case do_post(Url1, Body) of + {ok, RespBody} -> + %% 记录日志 + iot_logger:write(LoggerPid, [<<"OK">>, list_to_binary(Url1), Body, RespBody]), + {noreply, State#state{succ_counter = SuccCounter + 1}}; + {error, Reason} -> + NReason = iolist_to_binary(io_lib:format("~p", [Reason])), + iot_logger:write(LoggerPid, [<<"ERROR">>, list_to_binary(Url1), Body, NReason]), + {noreply, State#state{fail_counter = FailCounter + 1}} + end; + error -> + lager:notice("[iot_donghuoliren_endpoint] format_event error, message is: ~p", [Params]) +end. %% @private %% @doc Handling all non call/cast messages @@ -165,32 +169,48 @@ do_post(Url, Body) when is_binary(Body) -> end. %% 格式话要发送的数据,避免多次格式化处理 --spec format_event(LocationCode :: binary(), DynamicLocationCode :: binary(), EventType :: integer(), Params :: map()) -> Body :: binary(). +-spec format_event(LocationCode :: binary(), DynamicLocationCode :: binary(), EventType :: integer(), Params :: map()) -> {ok, Body :: binary()} | error. format_event(Location, DynamicLocationCode, EventType, - #{<<"datetime">> := Datetime, <<"attachments">> := Attachments0}) - when is_binary(Location), is_binary(DynamicLocationCode), is_integer(EventType) -> + #{<<"datetime">> := Datetime, <<"rtsp">> := RTSPUrl, <<"attachments">> := Attachments0}) + when is_binary(Location), is_binary(DynamicLocationCode), is_integer(EventType), is_binary(RTSPUrl) -> - %Attachments = lists:map(fun(#{<<"filename">> := Filename}) -> - % {ok, FileUrl} = iot_util:file_uri(Filename), - % Name = filename:basename(FileUrl), - % #{<<"name">> => Name, <<"url">> => FileUrl} - % end, Attachments0), + Attachments = lists:map(fun(#{<<"filename">> := Filename, <<"type">> := Type}) -> + {ok, FileUrl} = iot_util:file_uri(Filename), + {Type, FileUrl} + end, Attachments0), - Attachments = [ - <<"https://lgsiot.njau.edu.cn/upload/2024/11/29/2024-11-29-1732842080-1732842100.mp4">>, - <<"https://lgsiot.njau.edu.cn/upload/2024/11/29/2024-11-29-1732842080-1732842100.jpg">> - ], + %% 查找视频信息 + Videos = lists:filtermap(fun({Type, Url}) -> + case Type =:= <<"video">> of + true -> + {true, Url}; + false -> false + end + end, Attachments), + %% 查找附件信息 + Thumbnails = lists:filtermap(fun({Type, Url}) -> + case Type =:= <<"thumbnail">> of + true -> + {true, Url}; + false -> + false + end + end, Attachments), - %% 对端有key的顺序限制 - Params = #{ - <<"attachments">> => Attachments, - <<"eventLocation">> => Location, - <<"eventTime">> => Datetime, - <<"eventType">> => <<"动火离人"/utf8>>, - <<"videoJkAddr">> => <<"rtsp://admin:admin@123@192.168.111.147/cam/realmonitor?channel=1&subtype=0">> - }, - - iolist_to_binary(serialize(Params)). + case length(Videos) > 0 andalso length(Thumbnails) > 0 of + true -> + %% 对端有key的顺序限制 + Params = #{ + <<"attachments">> => [hd(Videos), hd(Thumbnails)], + <<"eventLocation">> => Location, + <<"eventTime">> => Datetime, + <<"eventType">> => <<"动火离人"/utf8>>, + <<"videoJkAddr">> => RTSPUrl + }, + {ok, iolist_to_binary(serialize(Params))}; + false -> + error + end. %% 简单的序列话函数,升序排列 -spec serialize(M :: map()) -> JsonString :: binary().