Skip to content

Commit

Permalink
feat: da
Browse files Browse the repository at this point in the history
  • Loading branch information
dawnwinterLiu committed May 22, 2024
1 parent d22891c commit 4ff0633
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 127 deletions.
69 changes: 34 additions & 35 deletions apps/dgiot/src/utils/dgiot_csv.erl
Original file line number Diff line number Diff line change
Expand Up @@ -100,41 +100,40 @@ save_csv_ets(#{<<"fullpath">> := Fullpath}) ->
post_properties(<<"plc">>, AtomName) ->
Things = ets:match(AtomName, {'$1', ['$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$10', '$11' | '_']}),
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);
Acc ++ [#{
<<"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);

post_properties(<<"dlink">>, AtomName) ->
Things = ets:match(AtomName, {'$1', ['$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$10', '$11' | '_']}),
Expand Down
17 changes: 2 additions & 15 deletions apps/dgiot_api/src/handler/dgiot_data_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -280,21 +280,8 @@ do_request(post_import_wmxdata, #{<<"type">> := Type, <<"objectId">> := ProductI
case dgiot_csv:post_properties(Type, AtomName) of
error ->
{ok, #{<<"code">> => 500, <<"msg">> => <<"error">>}};
NewProperties ->
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,
Properties ->
dgiot_parsex:update_object(<<"Product">>, ProductId, #{<<"thing">> => #{<<"properties">> => Properties}}),
{ok, #{<<"code">> => 200, <<"msg">> => <<"success">>}}
end;

Expand Down
4 changes: 4 additions & 0 deletions apps/dgiot_bamis/src/dgiot_bamis.erl
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ format_value(#{<<"or">> := V}) ->
#{<<"$or">> => V};
format_value(#{<<"and">> := V}) ->
#{<<"$and">> => V};
format_value(#{<<"relatedTo">> := V}) ->
#{<<"$relatedTo">> => V};

format_value(<<"gt">>) ->
<<"$gt">>;
Expand All @@ -302,5 +304,7 @@ format_value(<<"or">>) ->
<<"$or">>;
format_value(<<"and">>) ->
<<"$and">>;
format_value(<<"relatedTo">>) ->
<<"$relatedTo">>;
format_value(V) ->
V.
65 changes: 65 additions & 0 deletions apps/dgiot_bridge/priv/swagger/swagger_rule.json
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,71 @@
]
}
},
"/resource_types/{cType}": {
"get": {
"summary": "根据cType获取资源类型列表",
"description": "根据cType获取资源类型列表",
"parameters": [
{
"name": "cType",
"in": "path",
"description": "通道类型",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "Returns operation status",
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "名称"
},
"params": {
"type": "object",
"description": "参数",
"properties": {
}
},
"provider": {
"type": "string",
"description": "provider"
},
"title": {
"type": "string",
"description": "标题"
},
"description": {
"type": "string",
"description": "描述"
}
}
}
}
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"403": {
"description": "Forbidden"
},
"500": {
"description": "Server Internal error"
}
},
"tags": [
"Rule"
]
}
},
"/rulesql": {
"post": {
"summary": "生成规则sql",
Expand Down
43 changes: 43 additions & 0 deletions apps/dgiot_bridge/src/handler/dgiot_rule_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,39 @@ do_request(get_resource_types, _Args, _Context, _Req) ->
Resources = dgiot_bridge:get_all_channel(),
{200, Resources};

do_request(get_resource_types_ctype, #{<<"cType">> := CType} = _Args, _Context, _Req) ->
case dgiot_bridge:get_behaviour(CType) of
{error, not_find} ->
{200, #{<<"status">> => 404, <<"msg">> => unknow}};
{ok, Mod} ->
Attributes = Mod:module_info(attributes),
[Params] = proplists:get_value(params, Attributes, [#{}]),
Controls =
maps:fold(fun
(Key, #{default := Default, type := Type, required := Required, title := #{zh := Name}}, Acc) ->
Acc ++ [
#{
<<"type">> => format(Type),
<<"label">> => Name,
<<"name">> => <<"profile.", Key/binary>>,
<<"required">> => Required,
<<"placeholder">> => Default
}
];
(Key, _, Acc) ->
Acc ++ [
#{
<<"type">> => <<"text">>,
<<"label">> => Key,
<<"name">> => <<"profile.", Key/binary>>,
<<"required">> => false
}
]
end, [], maps:without([<<"ico">>], Params)),

{200, #{<<"status">> => 0, <<"msg">> => <<"">>, <<"data">> => #{<<"controls">> => Controls}}}
end;


%% 服务器不支持的API接口
do_request(_OperationId, _Args, _Context, _Req) ->
Expand Down Expand Up @@ -541,3 +574,13 @@ create_rules(RuleID, ChannelId, Description, Rawsql, Target_topic, Args) ->
{ok, #{<<"error">> => Error}}
end
end.


format(string) ->
<<"text">>;

format(integer) ->
<<"number">>;

format(_) ->
<<"text">>.
2 changes: 1 addition & 1 deletion apps/dgiot_modbus/src/dgiot_modbusc_tcp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ handle_info({tcp, Buff}, #dclient{channel = ChannelId,
erlang:send_after(Freq * 1000, self(), read),
{noreply, Dclient#dclient{child = ChildState#{di => StartAddr, data => <<>>}}};
_ ->
erlang:send_after(1 * 1000, self(), read),
erlang:send_after(100, self(), read),
{noreply, Dclient#dclient{child = ChildState#{di => Address + Step, data => <<OldData/binary, Data/binary>>}}}
end;

Expand Down
2 changes: 2 additions & 0 deletions apps/dgiot_modbus/src/dgiot_modbusrtu_tcp.erl
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
ProfilePayload = dgiot_device_profile:encode_profile(ProductId, dgiot_json:decode(Payload)),
Payloads = modbus_rtu:set_params(ProfilePayload, ProductId, DevAddr),
lists:map(fun(X) ->
timer:sleep(100),
dgiot_tcp_server:send(TCPState, X)
end, Payloads),
{noreply, TCPState};
Expand All @@ -161,6 +162,7 @@ handle_info({deliver, _, Msg}, #tcp{state = #state{id = ChannelId} = State} = TC
ProfilePayload = dgiot_device_profile:encode_profile(ProductId, dgiot_json:decode(Payload)),
Payloads = modbus_rtu:set_params(ProfilePayload, ProductId, DevAddr),
lists:map(fun(X) ->
timer:sleep(100),
dgiot_tcp_server:send(TCPState, X)
end, Payloads),
{noreply, TCPState};
Expand Down
94 changes: 44 additions & 50 deletions apps/dgiot_modbus/src/modbus/modbus_rtu.erl
Original file line number Diff line number Diff line change
Expand Up @@ -213,61 +213,55 @@ is16(Data) ->
dgiot_utils:binary_to_hex(<<IntData:16>>).

set_params(Payload, _ProductId, _DevAddr) ->
Length = length(maps:keys(Payload)),
Payloads =
lists:foldl(fun(Index, Acc) ->
case maps:find(Index, Payload) of
{ok, #{
<<"dataForm">> := #{
<<"protocol">> := <<"MODBUSRTU">>,
<<"control">> := Setting},
<<"dataSource">> := #{
<<"slaveid">> := SlaveId,
<<"address">> := Address,
<<"originaltype">> := Originaltype,
<<"operatetype">> := OperateType} = DataSource
} = Data} ->
case maps:find(<<"value">>, Data) of
error ->
Acc;
{ok, Value} when erlang:byte_size(Value) == 0 ->
Acc;
{ok, Value} ->
FunCode =
case OperateType of
<<"readCoils">> -> ?FC_READ_COILS;
<<"readInputs">> -> ?FC_READ_INPUTS;
<<"readHregs">> -> ?FC_READ_HREGS;
<<"readIregs">> -> ?FC_READ_IREGS;
<<"writeCoil">> -> ?FC_WRITE_COIL;
<<"writeHreg">> -> ?FC_WRITE_HREG;
<<"writeCoils">> -> ?FC_WRITE_COILS; %%需要校验,写多个线圈是什么状态
<<"writeHregs">> -> ?FC_WRITE_HREGS; %%需要校验,写多个保持寄存器是什么状态
_ -> ?FC_READ_HREGS
end,
<<H:8, L:8>> = dgiot_utils:hex_to_binary(is16(Address)),
<<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(is16(SlaveId)),
Str1 = re:replace(Setting, "%{d}", "(" ++ dgiot_utils:to_list(Value) ++ ")", [global, {return, list}]),
Value1 = dgiot_utils:to_int(dgiot_task:string2value(Str1, <<"type">>)),
maps:fold(fun(_, #{
<<"dataForm">> := #{
<<"protocol">> := <<"MODBUSRTU">>,
<<"control">> := Setting},
<<"dataSource">> := #{
<<"slaveid">> := SlaveId,
<<"address">> := Address,
<<"originaltype">> := Originaltype,
<<"operatetype">> := OperateType} = DataSource
} = Data, Acc) ->
case maps:find(<<"value">>, Data) of
error ->
Acc;
{ok, Value} when erlang:byte_size(Value) == 0 ->
Acc;
{ok, Value} ->
FunCode =
case OperateType of
<<"readCoils">> -> ?FC_READ_COILS;
<<"readInputs">> -> ?FC_READ_INPUTS;
<<"readHregs">> -> ?FC_READ_HREGS;
<<"readIregs">> -> ?FC_READ_IREGS;
<<"writeCoil">> -> ?FC_WRITE_COIL;
<<"writeHreg">> -> ?FC_WRITE_HREG;
<<"writeCoils">> -> ?FC_WRITE_COILS; %%需要校验,写多个线圈是什么状态
<<"writeHregs">> -> ?FC_WRITE_HREGS; %%需要校验,写多个保持寄存器是什么状态
_ -> ?FC_READ_HREGS
end,
<<H:8, L:8>> = dgiot_utils:hex_to_binary(is16(Address)),
<<Sh:8, Sl:8>> = dgiot_utils:hex_to_binary(is16(SlaveId)),
Str1 = re:replace(Setting, "%{d}", "(" ++ dgiot_utils:to_list(Value) ++ ")", [global, {return, list}]),
Value1 = dgiot_utils:to_int(dgiot_task:string2value(Str1, <<"type">>)),
%% NewBt = Bytes * 8,
Registersnumber = maps:get(<<"registersnumber">>, DataSource, <<"1">>),
Bytes = get_len(Registersnumber, Originaltype),
RtuReq = #rtu_req{
slaveId = Sh * 256 + Sl,
funcode = dgiot_utils:to_int(FunCode),
address = H * 256 + L,
registersnumber = dgiot_utils:to_int(Registersnumber),
dataByteSize = dgiot_utils:to_int(Bytes),
quality = Value1
},
Acc ++ [build_req_message(RtuReq)];
_ ->
Acc
end;
Registersnumber = maps:get(<<"registersnumber">>, DataSource, <<"1">>),
Bytes = get_len(Registersnumber, Originaltype),
RtuReq = #rtu_req{
slaveId = Sh * 256 + Sl,
funcode = dgiot_utils:to_int(FunCode),
address = H * 256 + L,
registersnumber = dgiot_utils:to_int(Registersnumber),
dataByteSize = dgiot_utils:to_int(Bytes),
quality = Value1
},
Acc ++ [build_req_message(RtuReq)];
_ ->
Acc
end
end, [], lists:seq(1, Length)),
end, [], Payload),
Payloads.

%% 010300000002C40B 01030438A93E3B76C0
Expand Down
Loading

0 comments on commit 4ff0633

Please sign in to comment.