From 4f816b13a5c54895eaa67484b051f70f97c53fb3 Mon Sep 17 00:00:00 2001 From: dawnwinterLiu <1737801684@qq.com> Date: Fri, 12 Apr 2024 20:32:01 +0800 Subject: [PATCH] feat: import_wmxdata --- apps/dgiot/src/utils/dgiot_csv.erl | 139 ++++++++++++++++++ apps/dgiot_api/priv/swagger/swagger_data.json | 43 ++++++ .../src/handler/dgiot_data_handler.erl | 22 +++ apps/dgiot_bridge/src/dgiot_bridge.erl | 3 +- 4 files changed, 205 insertions(+), 2 deletions(-) diff --git a/apps/dgiot/src/utils/dgiot_csv.erl b/apps/dgiot/src/utils/dgiot_csv.erl index 6ee68861..38d60eaf 100644 --- a/apps/dgiot/src/utils/dgiot_csv.erl +++ b/apps/dgiot/src/utils/dgiot_csv.erl @@ -22,6 +22,8 @@ read_from_csv/2 , save_csv_ets/2 , read_csv/3 + , save_csv_ets/1 + , post_properties/1 ]). read_from_csv(Path, Fun) -> @@ -73,3 +75,140 @@ save_csv_ets(Module, FilePath) -> _ -> FileName end. + + +save_csv_ets(#{<<"fullpath">> := Fullpath}) -> + <> = dgiot_utils:to_md5(Fullpath), + AtomName = dgiot_utils:to_atom(FileName), + dgiot_data:delete(AtomName), + dgiot_data:init(AtomName), + put(count, -1), + Fun = fun(X) -> + Count = get(count), + case Count > 0 of + true -> + dgiot_data:insert(AtomName, Count, X ++ [0]); + _ -> + pass + end, + put(count, Count + 1) + end, + read_from_csv(Fullpath, Fun), + AtomName. + + +post_properties(Things) -> + lists:foldl(fun([Index, Devicetype, Name, Identifier, Address, Originaltype, AccessMode, Min_Max, Unit, Type, Specs | _], Acc) -> + Acc#{ + to_lower(Identifier) => #{ + <<"name">> => Name, + <<"index">> => Index, + <<"isstorage">> => true, + <<"isshow">> => true, + <<"dataForm">> => #{ + <<"address">> => <<"0">>, + <<"rate">> => 1, + <<"order">> => Index, + <<"round">> => <<"all">>, + <<"offset">> => 0, + <<"control">> => <<"%{d}">>, + <<"iscount">> => <<"0">>, + <<"protocol">> => <<"S7">>, + <<"strategy">> => <<"1">>, + <<"collection">> => <<"%{s}">>, + <<"countround">> => <<"all">>, + <<"countstrategy">> => 3, + <<"countcollection">> => <<"%{s}">> + }, + <<"dataType">> => get_dataType(to_lower(Type), Min_Max, Unit, Specs), + <<"required">> => true, + <<"accessMode">> => get_accessmode(AccessMode), + <<"dataSource">> => #{ + <<"_dlinkindex">> => <<"">>, + <<"address">> => Address, + <<"originaltype">> => Originaltype + }, + <<"devicetype">> => Devicetype, + <<"identifier">> => to_lower(Identifier), + <<"moduleType">> => <<"properties">>, + <<"isaccumulate">> => false + }} + end, #{}, Things). + +get_accessmode(<<229, 143, 170, 232, 175, 187>>) -> + <<"r">>; + +get_accessmode(_AccessMode) -> + <<"rw">>. + +to_lower(Value) -> + Str1 = re:replace(Value, <<"\\.">>, <<"_">>, [global, {return, list}]), + list_to_binary(string:to_lower(Str1)). + +get_min_max(Min_Max) -> + case binary:split(Min_Max, <<$->>, [global, trim]) of + [<<>>, Min, Max] -> + {-dgiot_utils:to_int(Min), dgiot_utils:to_int(Max)}; + [Min, Max] -> + {dgiot_utils:to_int(Min), dgiot_utils:to_int(Max)}; + _ -> + {-65535, 65535} + end. + +get_dataType(<<"float">>, Min_Max, Unit, _) -> + {Min, Max} = get_min_max(Min_Max), + #{ + <<"das">> => [], + <<"type">> => <<"float">>, + <<"specs">> => #{ + <<"min">> => Min, + <<"max">> => Max, + <<"step">> => 0, + <<"unit">> => get_unit(Unit), + <<"precision">> => 3 + } + }; + +get_dataType(<<"enum">>, _, _, Specs) -> + Newspecs = get_specs(Specs), + #{ + <<"das">> => [], + <<"type">> => <<"enum">>, + <<"specs">> => Newspecs + }; + +get_dataType(Type, Min_Max, Unit, _) -> + {Min, Max} = get_min_max(Min_Max), + #{ + <<"das">> => [], + <<"type">> => Type, + <<"specs">> => #{ + <<"min">> => Min, + <<"max">> => Max, + <<"step">> => 0, + <<"unit">> => get_unit(Unit), + <<"precision">> => 3 + } + }. + + +get_specs(Specs) -> + case binary:split(Specs, <<$;>>, [global, trim]) of + List when length(List) > 0 -> + lists:foldl(fun(Map, Acc) -> + case binary:split(Map, <<$:>>, [global, trim]) of + [Key, Value] -> + Acc#{Key => Value}; + _ -> + Acc + end + end, #{}, List); + _ -> + #{} + end. + +get_unit(<<"null">>) -> + <<"">>; + +get_unit(Unit) -> + Unit. diff --git a/apps/dgiot_api/priv/swagger/swagger_data.json b/apps/dgiot_api/priv/swagger/swagger_data.json index a8d86d27..4047eb30 100644 --- a/apps/dgiot_api/priv/swagger/swagger_data.json +++ b/apps/dgiot_api/priv/swagger/swagger_data.json @@ -205,6 +205,49 @@ ] } }, + "/import_wmxdata": { + "post": { + "summary": "导入物模型", + "description": "导入物模型", + "consumes": [ + "multipart/form-data" + ], + "parameters": [ + { + "name": "objectId", + "in": "formData", + "description": "产品id", + "type": "string" + }, + { + "name": "file", + "in": "formData", + "description": "数据文件", + "type": "file" + } + ], + "responses": { + "200": { + "description": "Returns operation status" + }, + "400": { + "description": "Bad Request" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "500": { + "description": "Server Internal error" + } + }, + "tags": [ + "Data" + ] + } + }, "/import_data": { "post": { "summary": "导库", diff --git a/apps/dgiot_api/src/handler/dgiot_data_handler.erl b/apps/dgiot_api/src/handler/dgiot_data_handler.erl index b1fa8e60..791dbbd8 100644 --- a/apps/dgiot_api/src/handler/dgiot_data_handler.erl +++ b/apps/dgiot_api/src/handler/dgiot_data_handler.erl @@ -273,6 +273,28 @@ do_request(post_export_data, #{<<"classname">> := Name} = Body, #{<<"sessionToke Err end; +%% 导入物模型 +do_request(post_import_wmxdata, #{<<"objectId">> := ProductId, <<"file">> := File} = Args, _Context, _Req) -> + io:format("~s ~p Args =~p.~n", [?FILE, ?LINE, Args]), + AtomName = dgiot_csv:save_csv_ets(File), + Things = ets:match(AtomName, {'$1', ['$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$10', '$11' | '_']}), + NewProperties = dgiot_csv:post_properties(Things), + case dgiot_parsex:get_object(<<"Product">>, ProductId) of + {ok, #{<<"thing">> := Thing}} -> + OldProperties = + lists:foldl(fun(#{<<"identifier">> := Identifier} = X, Acc) -> + Acc#{Identifier => X} + end, #{}, maps:get(<<"properties">>, Thing, [])), + Properties = + maps:fold(fun(_, Prop, Acc) -> + Acc ++ [Prop] + end, [], dgiot_map:merge(OldProperties, NewProperties)), + dgiot_parsex:update_object(<<"Product">>, ProductId, #{<<"thing">> => Thing#{<<"properties">> => Properties}}); + _ -> + pass + end, + {ok, #{<<"code">> => 200, <<"msg">> => <<"success">>}}; + %% DB 概要: 导库 描述:json文件导库 %% OperationId:post_import_data %% 请求:POST /iotapi/import_data diff --git a/apps/dgiot_bridge/src/dgiot_bridge.erl b/apps/dgiot_bridge/src/dgiot_bridge.erl index 751c5b54..9c3dfeff 100644 --- a/apps/dgiot_bridge/src/dgiot_bridge.erl +++ b/apps/dgiot_bridge/src/dgiot_bridge.erl @@ -46,7 +46,7 @@ start() -> start_channel(Name, Filter) -> dgiot_bridge_loader:start(Name, Filter, fun(Module, Channel) -> - timer:sleep(1000), + timer:sleep(100), dgiot_bridge_server ! {start_channel, Module, Channel} end). @@ -225,7 +225,6 @@ load_channel() -> false -> ?LOG(error, "~p is not json.", [Json]); Filter -> - ?LOG(info, "Filter: ~p", [Filter]), start_channel(dgiot_bridge, Filter) end end, Filters);