defmodule RtuMaster do use ExUnit.Case @moduledoc """ These tests only runs if 'tty0tty' is installed in the host computer. """ test "Master test for fc => [1, 2, 3, 4, 5, 6, 15, 16]" do RingLogger.attach() {:ok, m_pid} = Modbux.Rtu.Master.start_link(tty: "tnt0") model = %{ 80 => %{ {:c, 1} => 1, {:c, 2} => 0, {:i, 1} => 1, {:i, 2} => 1, {:ir, 1} => 0, {:ir, 2} => 1, {:hr, 1} => 102, {:hr, 2} => 103 } } {:ok, s_pid} = Modbux.Rtu.Slave.start_link(tty: "tnt1", model: model, active: true) assert model == Modbux.Rtu.Slave.get_db(s_pid) # Master Requests. # Read Coil Status (FC=01) resp = Modbux.Rtu.Master.request(m_pid, {:rc, 80, 1, 1}) # slave assert_receive {:modbus_rtu, {:slave_request, {:rc, 80, 1, 1}}} # master assert resp == {:ok, [1]} # Read Input Status (FC=02) resp = Modbux.Rtu.Master.request(m_pid, {:ri, 80, 1, 1}) # slave assert_receive {:modbus_rtu, {:slave_request, {:ri, 80, 1, 1}}} # master assert resp == {:ok, [1]} # Read Holding Registers (FC=03) resp = Modbux.Rtu.Master.request(m_pid, {:rhr, 80, 1, 2}) # slave assert_receive {:modbus_rtu, {:slave_request, {:rhr, 80, 1, 2}}} # master assert resp == {:ok, [102, 103]} # # Read Input Registers (FC=04) resp = Modbux.Rtu.Master.request(m_pid, {:rir, 80, 1, 1}) # slave assert_receive {:modbus_rtu, {:slave_request, {:rir, 80, 1, 1}}} # master assert resp == {:ok, [0]} # Force Single Coil (FC=05) resp = Modbux.Rtu.Master.request(m_pid, {:fc, 80, 1, 0}) # slave assert_receive {:modbus_rtu, {:slave_request, {:fc, 80, 1, 0}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:c, 1}] == 0 # backward resp = Modbux.Rtu.Master.request(m_pid, {:fc, 80, 1, 1}) # slave assert_receive {:modbus_rtu, {:slave_request, {:fc, 80, 1, 1}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:c, 1}] == 1 # Preset Single Register (FC=06) resp = Modbux.Rtu.Master.request(m_pid, {:phr, 80, 1, 10}) # slave assert_receive {:modbus_rtu, {:slave_request, {:phr, 80, 1, 10}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:hr, 1}] == 10 # backward resp = Modbux.Rtu.Master.request(m_pid, {:phr, 80, 1, 102}) # slave assert_receive {:modbus_rtu, {:slave_request, {:phr, 80, 1, 102}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:hr, 1}] == 102 # Force Multiple Coils (FC=15) resp = Modbux.Rtu.Master.request(m_pid, {:fc, 80, 1, [0, 1]}) # slave assert_receive {:modbus_rtu, {:slave_request, {:fc, 80, 1, [0, 1]}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:c, 1}] == 0 assert model[80][{:c, 2}] == 1 # backward resp = Modbux.Rtu.Master.request(m_pid, {:fc, 80, 1, [1, 0]}) # slave assert_receive {:modbus_rtu, {:slave_request, {:fc, 80, 1, [1, 0]}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:c, 1}] == 1 assert model[80][{:c, 2}] == 0 # Preset Multiple Registers (FC=16) resp = Modbux.Rtu.Master.request(m_pid, {:phr, 80, 1, [0, 1]}) # slave assert_receive {:modbus_rtu, {:slave_request, {:phr, 80, 1, [0, 1]}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:hr, 1}] == 0 assert model[80][{:hr, 2}] == 1 # backward resp = Modbux.Rtu.Master.request(m_pid, {:phr, 80, 1, [102, 103]}) # slave assert_receive {:modbus_rtu, {:slave_request, {:phr, 80, 1, [102, 103]}}} # master assert resp == :ok model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:hr, 1}] == 102 assert model[80][{:hr, 2}] == 103 # Return exception for invalid address resp = Modbux.Rtu.Master.request(m_pid, {:phr, 80, 2, [102, 103]}) # slave assert_receive {:modbus_rtu, {:slave_error, {:phr, 80, 2, 'fg'}, :eaddr}} # master assert resp == {:error, :eaddr} model = Modbux.Rtu.Slave.get_db(s_pid) assert model[80][{:hr, 1}] == 102 assert model[80][{:hr, 2}] == 103 # Return CRC error # bad crc assert Modbux.Rtu.Slave.raw_write(s_pid, <<80, 4, 2, 0, 1, 133, 61>>) resp = Modbux.Rtu.Master.read(m_pid) assert resp == {:error, :ecrc} Modbux.Rtu.Master.configure(m_pid, active: true) # Active mode. # Read Coil Status (FC=01) resp = Modbux.Rtu.Master.request(m_pid, {:rc, 80, 1, 1}) # slave assert_receive {:modbus_rtu, {:slave_request, {:rc, 80, 1, 1}}} # master assert resp == :ok assert_receive {:modbus_rtu, {:slave_response, {:rc, 80, 1, 1}, [1]}} end end