解决标准输入输出的问题
This commit is contained in:
parent
f9910a23de
commit
9c38133b1f
@ -258,11 +258,11 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
|
||||
Transport = case string:trim(Name0) of
|
||||
<<"rtu">> ->
|
||||
#modbus_transport_rtu{
|
||||
port = maps:get(<<"port">>, PropsMap, undefined),
|
||||
baudrate = maps:get(<<"baudrate">>, PropsMap, undefined),
|
||||
parity = maps:get(<<"parity">>, PropsMap, undefined),
|
||||
stopbits = maps:get(<<"stopbits">>, PropsMap, undefined),
|
||||
timeout = maps:get(<<"timeout">>, PropsMap, undefined)
|
||||
port = map_of_binary(<<"port">>, PropsMap, undefined),
|
||||
baudrate = map_of_integer(<<"baudrate">>, PropsMap, undefined),
|
||||
parity = map_of_binary(<<"parity">>, PropsMap, undefined),
|
||||
stopbits = map_of_integer(<<"stopbits">>, PropsMap, undefined),
|
||||
timeout = map_of_time(<<"timeout">>, PropsMap, undefined)
|
||||
};
|
||||
<<"tcp">> ->
|
||||
#modbus_transport_tcp {
|
||||
@ -276,12 +276,13 @@ parse_ast1([#block{ident = <<"transport", Name0/binary>>, props = Props}|T], Acc
|
||||
%% 语义验证:检查AST的合法性和一致性
|
||||
validate([]) ->
|
||||
ok;
|
||||
validate([#modbus{transport = #modbus_transport_rtu{port = Port, baudrate = Baudrate}}|T]) ->
|
||||
case filelib:is_file(Port) andalso Baudrate > 0 of
|
||||
validate([#modbus{transport = #modbus_transport_rtu{port = Port0, baudrate = Baudrate}}|T]) ->
|
||||
Port = binary_to_list(Port0),
|
||||
case filename:validate(Port) andalso Baudrate > 0 of
|
||||
true ->
|
||||
validate(T);
|
||||
false ->
|
||||
throw({invalid_transport_rtu, {Port, Baudrate}})
|
||||
throw({invalid_transport_rtu, {Port0, Baudrate}})
|
||||
end;
|
||||
validate([#modbus{transport = #modbus_transport_tcp{host = Host, port = Port}}|T]) ->
|
||||
case Host /= undefined andalso Port > 0 of
|
||||
|
||||
@ -198,7 +198,8 @@ handle_event(info, {tcp_error, Socket, Reason}, ?CONNECTED, State = #state{mode
|
||||
{next_state, ?DISCONNECTED, State#state{socket = undefined}};
|
||||
|
||||
%% 建立连接, todo is_pending的状态要形成闭环
|
||||
handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modbus = #modbus{transport = Transport}}, queue = Q}) ->
|
||||
handle_event(info, {timeout, _Ref, modbus_connect}, ?DISCONNECTED, State = #state{ast = #ast{modbus = #modbus{transport = Transport}}, queue = Q}) ->
|
||||
lager:debug("call me will connect, transport: ~p", [Transport]),
|
||||
case connect(Transport) of
|
||||
{ok, ConnectResult} ->
|
||||
Actions = case not queue:is_empty(Q) of
|
||||
@ -207,8 +208,8 @@ handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modb
|
||||
end,
|
||||
case ConnectResult of
|
||||
{rtu, Port, DelayMs} ->
|
||||
%% 触发读取下一条
|
||||
erlang:start_timer(0, self(), read_next),
|
||||
%% todo 触发读取下一条
|
||||
% erlang:start_timer(0, self(), read_next),
|
||||
{next_state, ?CONNECTED, State#state{mode = rtu, port = Port, delay_ms = DelayMs, is_pending = false}, Actions};
|
||||
Socket ->
|
||||
{next_state, ?CONNECTED, State#state{mode = tcp, socket = Socket}, Actions}
|
||||
@ -218,11 +219,7 @@ handle_event(info, modbus_connect, ?DISCONNECTED, State = #state{ast = #ast{modb
|
||||
%% 5秒后重试
|
||||
retry_connect(),
|
||||
{keep_state, State}
|
||||
end;
|
||||
|
||||
handle_event(_EventType, _EventContent, _StateName, State = #state{}) ->
|
||||
NextStateName = the_next_state_name,
|
||||
{next_state, NextStateName, State}.
|
||||
end.
|
||||
|
||||
%% @private
|
||||
%% @doc This function is called by a gen_statem when it is about to
|
||||
@ -244,16 +241,29 @@ code_change(_OldVsn, StateName, State = #state{}, _Extra) ->
|
||||
-spec connect(Transport :: #modbus_transport_rtu{} | #modbus_transport_tcp{}) ->
|
||||
{ok, {rtu, Port :: port(), DelayMs :: integer()}} | {ok, Socket :: gen_tcp:socket()} | {error, Reason :: any()}.
|
||||
%% databits为8位
|
||||
connect(#modbus_transport_rtu{port = Port, baudrate = BaudRate, stopbits = StopBits, parity = Parity, timeout = Timeout}) ->
|
||||
RealExecCmd = "",
|
||||
Port = erlang:open_port({spawn_executable, RealExecCmd}, [binary, {packet, 2}, exit_status]),
|
||||
connect(#modbus_transport_rtu{port = SerialPort, baudrate = BaudRate, stopbits = StopBits, parity = Parity0, timeout = Timeout}) ->
|
||||
lager:warning("call me here connect, serial_port: ~p", [SerialPort]),
|
||||
|
||||
%% 奇偶校验
|
||||
Parity = case Parity0 of
|
||||
<<"none">> -> 0;
|
||||
<<"odd">> -> 1;
|
||||
<<"even">> -> 2;
|
||||
_ -> 0
|
||||
end,
|
||||
RealExecCmd = "/usr/local/code/cloudkit/modbus/apps/modbus/priv/bin/modbus_agent",
|
||||
Args = [
|
||||
"--port " ++ binary_to_list(SerialPort),
|
||||
"--baud_rate " ++ integer_to_list(BaudRate),
|
||||
"--stop_bits " ++ integer_to_list(StopBits),
|
||||
"--parity " ++ integer_to_list(Parity),
|
||||
"--timeout " ++ integer_to_list(Timeout)
|
||||
],
|
||||
Port = erlang:open_port({spawn_executable, RealExecCmd}, [binary, {packet, 2}, exit_status, {args, Args}]),
|
||||
lager:debug("args: ~p", [Args]),
|
||||
DelayMs = frame_delay(BaudRate, 8, Parity, StopBits),
|
||||
|
||||
Len0 = byte_size(Port),
|
||||
ConnectCmd = <<?MODBUS_CONNECT:8, Len0:8, Port/binary, BaudRate:32, StopBits:8, Parity:8, Timeout:32>>,
|
||||
lager:debug("port is: ~p", [Port]),
|
||||
%% 建立连接
|
||||
Port ! {self(), {command, ConnectCmd}},
|
||||
{ok, {rtu, Port, DelayMs}};
|
||||
connect(#modbus_transport_tcp{host = Host, port = Port, timeout = Timeout0}) ->
|
||||
Timeout = case is_integer(Timeout0) andalso Timeout0 > 0 of
|
||||
|
||||
10
modbus.conf
10
modbus.conf
@ -9,11 +9,11 @@ modbus {
|
||||
}
|
||||
|
||||
# 或TCP配置
|
||||
transport tcp {
|
||||
host 192.168.1.100;
|
||||
port 502;
|
||||
timeout 500ms;
|
||||
}
|
||||
#transport tcp {
|
||||
# host 192.168.1.100;
|
||||
# port 502;
|
||||
# timeout 500ms;
|
||||
#}
|
||||
|
||||
# 日志设置
|
||||
error_log /var/log/modbus_error.log;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user