fix
This commit is contained in:
parent
ec392e1795
commit
5de6731d7f
@ -42,13 +42,8 @@
|
|||||||
%% 连接模式
|
%% 连接模式
|
||||||
mode :: #rtu_mode{} | #tcp_mode{} | undefined,
|
mode :: #rtu_mode{} | #tcp_mode{} | undefined,
|
||||||
|
|
||||||
is_pending = true :: boolean(),
|
|
||||||
|
|
||||||
socket :: gen_tcp:socket() | undefined,
|
|
||||||
|
|
||||||
%% #{slaveId => DevicePid}
|
%% #{slaveId => DevicePid}
|
||||||
devices_map = #{},
|
devices_map = #{},
|
||||||
|
|
||||||
%% 所有的处理过程
|
%% 所有的处理过程
|
||||||
processor_pids = [],
|
processor_pids = [],
|
||||||
%% alarms
|
%% alarms
|
||||||
@ -100,11 +95,11 @@ init([AST = #ast{modbus = Modbus = #modbus{transport = Transport, error_log = Er
|
|||||||
{rtu, Port, DelayMs} ->
|
{rtu, Port, DelayMs} ->
|
||||||
|
|
||||||
{ok, ?CONNECTED, #state{ast = AST, access_log_pid = create_log_file(AccessLog), error_log_pid = create_log_file(ErrorLog),
|
{ok, ?CONNECTED, #state{ast = AST, access_log_pid = create_log_file(AccessLog), error_log_pid = create_log_file(ErrorLog),
|
||||||
mode = #rtu_mode{port = Port, delay_ms = DelayMs}, is_pending = false,
|
mode = #rtu_mode{port = Port, delay_ms = DelayMs},
|
||||||
queue = queue:new(), packet_id = 1, devices_map = DevicesMap, alarm_pids = []}};
|
queue = queue:new(), packet_id = 1, devices_map = DevicesMap, alarm_pids = []}};
|
||||||
Socket ->
|
Socket ->
|
||||||
{ok, ?CONNECTED, #state{ast = AST, access_log_pid = create_log_file(AccessLog), error_log_pid = create_log_file(ErrorLog),
|
{ok, ?CONNECTED, #state{ast = AST, access_log_pid = create_log_file(AccessLog), error_log_pid = create_log_file(ErrorLog),
|
||||||
mode = #tcp_mode{socket = Socket}, is_pending = false,
|
mode = #tcp_mode{socket = Socket},
|
||||||
queue = queue:new(), packet_id = 1, devices_map = DevicesMap, alarm_pids = []}}
|
queue = queue:new(), packet_id = 1, devices_map = DevicesMap, alarm_pids = []}}
|
||||||
end;
|
end;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
@ -127,18 +122,12 @@ callback_mode() ->
|
|||||||
%% process message, this function is called.
|
%% process message, this function is called.
|
||||||
|
|
||||||
%% 请求的时候必须先加入队列,modbus需要控制请求的频率
|
%% 请求的时候必须先加入队列,modbus需要控制请求的频率
|
||||||
handle_event(info, {request, ReceiverPid, Ref, SlaveId, Address}, StateName, State = #state{mode = rtu, is_pending = IsPending, packet_id = PacketId, queue = Q}) ->
|
handle_event(info, {request, ReceiverPid, Ref, SlaveId, Address}, StateName, State = #state{mode = #rtu_mode{}, packet_id = PacketId, queue = Q}) ->
|
||||||
case StateName of
|
case StateName of
|
||||||
?CONNECTED ->
|
?CONNECTED ->
|
||||||
Actions = case IsPending of
|
|
||||||
true ->
|
|
||||||
[{next_event, info, read_next}];
|
|
||||||
false ->
|
|
||||||
[]
|
|
||||||
end,
|
|
||||||
%% 基于队列处理, modbus不是全双工的模式
|
%% 基于队列处理, modbus不是全双工的模式
|
||||||
NQ = queue:in({PacketId, ReceiverPid, Ref, SlaveId, Address}, Q),
|
NQ = queue:in({PacketId, ReceiverPid, Ref, SlaveId, Address}, Q),
|
||||||
{keep_state, State#state{queue = NQ, packet_id = PacketId + 1}, Actions};
|
{keep_state, State#state{queue = NQ, packet_id = PacketId + 1}, [{next_event, info, read_next}]};
|
||||||
_ ->
|
_ ->
|
||||||
{keep_state, State}
|
{keep_state, State}
|
||||||
end;
|
end;
|
||||||
@ -153,9 +142,9 @@ handle_event(info, read_next, ?CONNECTED, State = #state{mode = #rtu_mode{port =
|
|||||||
Port ! {self(), {command, ReadCmd}},
|
Port ! {self(), {command, ReadCmd}},
|
||||||
{keep_state, State#state{queue = Q2, inflight = maps:put(PacketId, {ReceiverPid, Ref}, Inflight)}};
|
{keep_state, State#state{queue = Q2, inflight = maps:put(PacketId, {ReceiverPid, Ref}, Inflight)}};
|
||||||
{empty, Q1} ->
|
{empty, Q1} ->
|
||||||
{keep_state, State#state{queue = Q1, is_pending = true}}
|
{keep_state, State#state{queue = Q1}}
|
||||||
end;
|
end;
|
||||||
handle_event(info, read_next, ?DISCONNECTED, State = #state{mode = rtu}) ->
|
handle_event(info, read_next, ?DISCONNECTED, State = #state{mode = #rtu_mode{}}) ->
|
||||||
{keep_state, State};
|
{keep_state, State};
|
||||||
|
|
||||||
%% 从port读取数据, todo 获取到的数据表示为32位整数
|
%% 从port读取数据, todo 获取到的数据表示为32位整数
|
||||||
@ -184,25 +173,25 @@ handle_event(info, {broadcast, Key, Val}, ?CONNECTED, State = #state{alarm_pids
|
|||||||
handle_event(info, {Port, {exit_status, Code}}, ?CONNECTED, State = #state{mode = #rtu_mode{port = Port}}) ->
|
handle_event(info, {Port, {exit_status, Code}}, ?CONNECTED, State = #state{mode = #rtu_mode{port = Port}}) ->
|
||||||
lager:debug("[modbus_service] port: ~p, exit with code: ~p", [Port, Code]),
|
lager:debug("[modbus_service] port: ~p, exit with code: ~p", [Port, Code]),
|
||||||
retry_connect(),
|
retry_connect(),
|
||||||
{next_state, ?DISCONNECTED, State#state{mode = undefined, is_pending = true}};
|
{next_state, ?DISCONNECTED, State#state{mode = undefined}};
|
||||||
|
|
||||||
%% 处理port的退出消息
|
%% 处理port的退出消息
|
||||||
handle_event(info, {'EXIT', Port, Reason}, ?CONNECTED, State = #state{mode = #rtu_mode{port = Port}}) ->
|
handle_event(info, {'EXIT', Port, Reason}, ?CONNECTED, State = #state{mode = #rtu_mode{port = Port}}) ->
|
||||||
lager:debug("[modbus_service] port: ~p, exit with code: ~p", [Port, Reason]),
|
lager:debug("[modbus_service] port: ~p, exit with code: ~p", [Port, Reason]),
|
||||||
retry_connect(),
|
retry_connect(),
|
||||||
{next_state, ?DISCONNECTED, State#state{mode = undefined, is_pending = true}};
|
{next_state, ?DISCONNECTED, State#state{mode = undefined}};
|
||||||
|
|
||||||
%% tcp退出
|
%% tcp退出
|
||||||
handle_event(info, {tcp_closed, Socket}, ?CONNECTED, State = #state{mode = tcp, socket = Socket}) ->
|
handle_event(info, {tcp_closed, Socket}, ?CONNECTED, State = #state{mode = #tcp_mode{socket = Socket}}) ->
|
||||||
lager:debug("[modbus_service] socket: ~p, exit with tcp_closed", [Socket]),
|
lager:debug("[modbus_service] socket: ~p, exit with tcp_closed", [Socket]),
|
||||||
retry_connect(),
|
retry_connect(),
|
||||||
{next_state, ?DISCONNECTED, State#state{socket = undefined}};
|
{next_state, ?DISCONNECTED, State#state{mode = undefined}};
|
||||||
|
|
||||||
%% 处理tcp的退出消息
|
%% 处理tcp的退出消息
|
||||||
handle_event(info, {tcp_error, Socket, Reason}, ?CONNECTED, State = #state{mode = tcp, socket = Socket}) ->
|
handle_event(info, {tcp_error, Socket, Reason}, ?CONNECTED, State = #state{mode = #tcp_mode{socket = Socket}}) ->
|
||||||
lager:debug("[modbus_service] socket: ~p, exit with code: ~p", [Socket, Reason]),
|
lager:debug("[modbus_service] socket: ~p, exit with code: ~p", [Socket, Reason]),
|
||||||
retry_connect(),
|
retry_connect(),
|
||||||
{next_state, ?DISCONNECTED, State#state{socket = undefined}};
|
{next_state, ?DISCONNECTED, State#state{mode = undefined}};
|
||||||
|
|
||||||
%% 建立连接, todo is_pending的状态要形成闭环
|
%% 建立连接, todo is_pending的状态要形成闭环
|
||||||
handle_event(info, {timeout, _Ref, 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}) ->
|
||||||
@ -216,7 +205,7 @@ handle_event(info, {timeout, _Ref, modbus_connect}, ?DISCONNECTED, State = #stat
|
|||||||
end,
|
end,
|
||||||
case ConnectResult of
|
case ConnectResult of
|
||||||
{rtu, Port, DelayMs} ->
|
{rtu, Port, DelayMs} ->
|
||||||
{next_state, ?CONNECTED, State#state{mode = #rtu_mode{port = Port, delay_ms = DelayMs}, is_pending = false}, Actions};
|
{next_state, ?CONNECTED, State#state{mode = #rtu_mode{port = Port, delay_ms = DelayMs}}, Actions};
|
||||||
Socket ->
|
Socket ->
|
||||||
{next_state, ?CONNECTED, State#state{mode = #tcp_mode{socket = Socket}}, Actions}
|
{next_state, ?CONNECTED, State#state{mode = #tcp_mode{socket = Socket}}, Actions}
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user