fix parser
This commit is contained in:
parent
df3e7c4346
commit
f8fd7d0c43
33
apps/modbus/src/modbus_crc.erl
Normal file
33
apps/modbus/src/modbus_crc.erl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author anlicheng
|
||||||
|
%%% @copyright (C) 2025, <COMPANY>
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 13. 6月 2025 15:08
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(modbus_crc).
|
||||||
|
-author("anlicheng").
|
||||||
|
|
||||||
|
%% CRC16 constants
|
||||||
|
-define(CRC_POLY, 16#A001).
|
||||||
|
|
||||||
|
-export([crc16/1]).
|
||||||
|
|
||||||
|
-spec crc16(binary()) -> binary().
|
||||||
|
crc16(Data) ->
|
||||||
|
crc16(Data, 16#FFFF).
|
||||||
|
|
||||||
|
crc16(<<>>, CRC) ->
|
||||||
|
<<CRC:16/little>>;
|
||||||
|
crc16(<<Byte:8, Rest/binary>>, CRC0) ->
|
||||||
|
CRC1 = CRC0 bxor Byte,
|
||||||
|
CRC2 = lists:foldl(fun(_, C) ->
|
||||||
|
if C band 1 =:= 1 -> (C bsr 1) bxor ?CRC_POLY;
|
||||||
|
true -> C bsr 1
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
CRC1,
|
||||||
|
lists:seq(1,8)),
|
||||||
|
|
||||||
|
crc16(Rest, CRC2).
|
||||||
@ -150,8 +150,8 @@ parse_ast0(#block{ident = <<"modbus">>, props = Props}) ->
|
|||||||
MapProps = parse_ast1(Props),
|
MapProps = parse_ast1(Props),
|
||||||
#modbus {
|
#modbus {
|
||||||
transport = maps:get(<<"transport">>, MapProps, undefined),
|
transport = maps:get(<<"transport">>, MapProps, undefined),
|
||||||
access_log = maps:get(<<"access_log">>, MapProps, undefined),
|
access_log = map_of_string(<<"access_log">>, MapProps, undefined),
|
||||||
error_log = maps:get(<<"error_log">>, MapProps, undefined)
|
error_log = map_of_string(<<"error_log">>, MapProps, undefined)
|
||||||
};
|
};
|
||||||
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
|
parse_ast0(#block{ident = <<"device", Name0/binary>>, props = Props}) ->
|
||||||
MapProps = parse_ast1(Props),
|
MapProps = parse_ast1(Props),
|
||||||
@ -213,9 +213,9 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
|
|||||||
};
|
};
|
||||||
<<"tcp">> ->
|
<<"tcp">> ->
|
||||||
#modbus_transport_tcp {
|
#modbus_transport_tcp {
|
||||||
host = maps:get(<<"host">>, PropsMap, undefined),
|
host = map_of_string(<<"host">>, PropsMap, undefined),
|
||||||
port = maps:get(<<"port">>, PropsMap, undefined),
|
port = map_of_integer(<<"port">>, PropsMap, undefined),
|
||||||
timeout = maps:get(<<"timeout">>, PropsMap, undefined)
|
timeout = map_of_time(<<"timeout">>, PropsMap, undefined)
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
parse_ast1(T, [{<<"transport">>, Transport}|Acc]).
|
parse_ast1(T, [{<<"transport">>, Transport}|Acc]).
|
||||||
@ -260,3 +260,31 @@ map_of_integer(Key, M, Def) ->
|
|||||||
Def
|
Def
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
map_of_string(Key, M, Def) ->
|
||||||
|
case maps:is_key(Key, M) of
|
||||||
|
true ->
|
||||||
|
[Val0] = maps:get(Key, M),
|
||||||
|
binary_to_list(Val0);
|
||||||
|
false ->
|
||||||
|
Def
|
||||||
|
end.
|
||||||
|
|
||||||
|
map_of_time(Key, M, Def) ->
|
||||||
|
case maps:is_key(Key, M) of
|
||||||
|
true ->
|
||||||
|
[Val0] = maps:get(Key, M),
|
||||||
|
case re:run(Val0, <<"^(\\d+(?:\\.\\d+)?)(\\D+)$">>, [{capture, all_but_first, binary}]) of
|
||||||
|
{match, [Val, Unit]} ->
|
||||||
|
Digit = binary_to_integer(Val),
|
||||||
|
case Unit of
|
||||||
|
<<"ms">> ->
|
||||||
|
Digit;
|
||||||
|
<<"s">> ->
|
||||||
|
Digit * 1000
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
Def
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
Def
|
||||||
|
end.
|
||||||
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
|
-export([test/0]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
|
||||||
@ -24,6 +25,12 @@
|
|||||||
|
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
test() ->
|
||||||
|
{ok, Config} = file:read_file("/usr/local/code/cloudkit/modbus/modbus.conf"),
|
||||||
|
%lager:debug("config is: ~ts", [Config]),
|
||||||
|
{ok, AST} = modbus_parser:parse(Config),
|
||||||
|
start_link(AST).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -32,7 +39,7 @@
|
|||||||
-spec(start_link(AST :: #ast{}) ->
|
-spec(start_link(AST :: #ast{}) ->
|
||||||
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
{ok, Pid :: pid()} | ignore | {error, Reason :: term()}).
|
||||||
start_link(AST) ->
|
start_link(AST) ->
|
||||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
gen_server:start_link(?MODULE, [AST], []).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% gen_server callbacks
|
%%% gen_server callbacks
|
||||||
@ -43,7 +50,10 @@ start_link(AST) ->
|
|||||||
-spec(init(Args :: term()) ->
|
-spec(init(Args :: term()) ->
|
||||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term()} | ignore).
|
{stop, Reason :: term()} | ignore).
|
||||||
init([]) ->
|
init([AST = #ast{modbus = Modbus}]) ->
|
||||||
|
|
||||||
|
lager:debug("modbus is: ~p", [Modbus]),
|
||||||
|
|
||||||
{ok, #state{}}.
|
{ok, #state{}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
@ -98,3 +108,15 @@ code_change(_OldVsn, State = #state{}, _Extra) ->
|
|||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
|
||||||
|
x(#modbus{transport = #modbus_transport_rtu{port = Port, baudrate = Baudrate, stopbits = Stopbits, timeout = Timeout}}) ->
|
||||||
|
ok;
|
||||||
|
x(#modbus{transport = #modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}}) ->
|
||||||
|
Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of
|
||||||
|
true ->
|
||||||
|
Timeout0;
|
||||||
|
false ->
|
||||||
|
2000
|
||||||
|
end,
|
||||||
|
gen_tcp:connect(Host, Port, [binary], Timeout).
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
{"1.2.0",
|
{"1.2.0",
|
||||||
[{<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1},
|
[
|
||||||
|
{<<"fs">>,{pkg,<<"fs">>,<<"6.1.1">>},1},
|
||||||
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
{<<"goldrush">>,{pkg,<<"goldrush">>,<<"0.1.9">>},1},
|
||||||
{<<"gpb">>,
|
{<<"gpb">>,
|
||||||
{git,"https://github.com/tomas-abrahamsson/gpb.git",
|
{git,"https://github.com/tomas-abrahamsson/gpb.git",
|
||||||
@ -17,6 +18,7 @@
|
|||||||
{git,"https://github.com/uwiger/parse_trans",
|
{git,"https://github.com/uwiger/parse_trans",
|
||||||
{ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}},
|
{ref,"6f3645afb43c7c57d61b54ef59aecab288ce1013"}},
|
||||||
0},
|
0},
|
||||||
|
|
||||||
{<<"sync">>,
|
{<<"sync">>,
|
||||||
{git,"https://github.com/rustyio/sync.git",
|
{git,"https://github.com/rustyio/sync.git",
|
||||||
{ref,"7dc303ed4ce8d26db82e171dbbd7c41067852c65"}},
|
{ref,"7dc303ed4ce8d26db82e171dbbd7c41067852c65"}},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user