Module: ModBus::Server

Included in:
RTUServer, RTUViaTCPServer, TCPServer
Defined in:
lib/rmodbus/server.rb

Overview

Module for implementation ModBus server

Constant Summary

Funcs =
[1,2,3,4,5,6,15,16]

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (Object) coils

Returns the value of attribute coils



21
22
23
# File 'lib/rmodbus/server.rb', line 21

def coils
  @coils
end

- (Object) discrete_inputs

Returns the value of attribute discrete_inputs



21
22
23
# File 'lib/rmodbus/server.rb', line 21

def discrete_inputs
  @discrete_inputs
end

- (Object) holding_registers

Returns the value of attribute holding_registers



21
22
23
# File 'lib/rmodbus/server.rb', line 21

def holding_registers
  @holding_registers
end

- (Object) input_registers

Returns the value of attribute input_registers



21
22
23
# File 'lib/rmodbus/server.rb', line 21

def input_registers
  @input_registers
end

- (Object) uid

Returns the value of attribute uid



21
22
23
# File 'lib/rmodbus/server.rb', line 21

def uid
  @uid
end

Instance Method Details

- (Object) exec_req(req, coils, discrete_inputs, holding_registers, input_registers) (private)



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rmodbus/server.rb', line 29

def exec_req(req, coils, discrete_inputs, holding_registers, input_registers)
  func = req.getbyte(0)

  unless Funcs.include?(func)
    params = { :err => 1 }
  end

  case func
    when 1
      params = parse_read_func(req, coils, 2000)
      if params[:err] == 0
        val = coils[params[:addr],params[:quant]].pack_to_word
        pdu = func.chr + val.size.chr + val
      end
    when 2
      params = parse_read_func(req, discrete_inputs, 2000)
      if params[:err] == 0
        val = discrete_inputs[params[:addr],params[:quant]].pack_to_word
        pdu = func.chr + val.size.chr + val
      end
    when 3
      params = parse_read_func(req, holding_registers)
      if params[:err] == 0
        pdu = func.chr + (params[:quant] * 2).chr + holding_registers[params[:addr],params[:quant]].pack('n*')
      end
    when 4
      params = parse_read_func(req, input_registers)
      if params[:err] == 0
        pdu = func.chr + (params[:quant] * 2).chr + input_registers[params[:addr],params[:quant]].pack('n*')
      end
    when 5
      params = parse_write_coil_func(req)
      if params[:err] == 0
        coils[params[:addr]] = params[:val]
        pdu = req
      end
    when 6
      params = parse_write_register_func(req)
      if params[:err] == 0
        holding_registers[params[:addr]] = params[:val]
        pdu = req
      end
    when 15
      params = parse_write_multiple_coils_func(req)
      if params[:err] == 0
        coils[params[:addr],params[:quant]] = params[:val][0,params[:quant]]
        pdu = req[0,5]
      end
    when 16
      params = parse_write_multiple_registers_func(req)
      if params[:err] == 0
        holding_registers[params[:addr],params[:quant]] = params[:val][0,params[:quant]]
        pdu = req[0,5]
      end
  end

  if params[:err] == 0
    pdu
  else
    pdu = (func | 0x80).chr + params[:err].chr
  end
end

- (Object) parse_read_func(req, field, quant_max = 0x7d) (private)



92
93
94
95
96
97
98
99
100
101
# File 'lib/rmodbus/server.rb', line 92

def parse_read_func(req, field, quant_max=0x7d)
  quant = req[3,2].unpack('n')[0]

  return { :err => 3} unless quant <= quant_max

  addr = req[1,2].unpack('n')[0]
  return { :err => 2 } unless addr + quant <= field.size

  return { :err => 0, :quant => quant, :addr => addr }
end

- (Object) parse_write_coil_func(req) (private)



103
104
105
106
107
108
109
110
111
112
# File 'lib/rmodbus/server.rb', line 103

def parse_write_coil_func(req)
  addr = req[1,2].unpack('n')[0]
  return { :err => 2 } unless addr <= @coils.size

  val = req[3,2].unpack('n')[0]
  return { :err => 3 } unless val == 0 or val == 0xff00

  val = 1 if val == 0xff00
  return { :err => 0, :addr => addr, :val => val }
end

- (Object) parse_write_multiple_coils_func(req) (private)



123
124
125
126
127
128
129
130
# File 'lib/rmodbus/server.rb', line 123

def parse_write_multiple_coils_func(req)
  params = parse_read_func(req, @coils)

  if params[:err] == 0
    params = {:err => 0, :addr => params[:addr], :quant => params[:quant], :val => req[6,params[:quant]].unpack_bits }
  end
  params
end

- (Object) parse_write_multiple_registers_func(req) (private)



132
133
134
135
136
137
138
139
# File 'lib/rmodbus/server.rb', line 132

def parse_write_multiple_registers_func(req)
  params = parse_read_func(req, @holding_registers)

  if params[:err] == 0
    params = {:err => 0, :addr => params[:addr], :quant => params[:quant], :val => req[6,params[:quant] * 2].unpack('n*')}
  end
  params
end

- (Object) parse_write_register_func(req) (private)



114
115
116
117
118
119
120
121
# File 'lib/rmodbus/server.rb', line 114

def parse_write_register_func(req)
   addr = req[1,2].unpack('n')[0]
   return { :err => 2 } unless addr <= @holding_registers.size

   val = req[3,2].unpack('n')[0]

   return { :err => 0, :addr => addr, :val => val }
end