Enable Modbus Query of DIA Devices

From Digi Developer

Jump to: navigation, search



Modbus is a simple memory read/write protocol. It allows a remote SCADA or HMI host to read a block of words. What those words mean must be manually configured into the host software. The DIA Modbus Server Module allows a Modbus master to read the data from a collection of XBee devices as if they were each a Modbus device. For example, twenty level sensors on twenty tanks would appear as 20 Modbus devices.

Mapping Modbus Unit Id to DIA Device

The Modbus server uses an ASCII text file in the FS/WEB/python directory named mbus_map.txt, which you can edit manually as required. A reboot is required to activate any changes you made. Below is an example file. The CSV-like fields are:

  • Modbus slave address / Unit Id
  • DIA device name, which is used to locate the device for each Modbus poll
  • The device type (name) returned by the device driver - the exact value is not important and is used primarily for debug trace information
  • MAC address of the device (if applicable)
# DIA Modbus Server unit_id mapping as of 2010-02-08 15:55:41

Hard-Coded Mapping

The YML can be used to hard-code a DIA device to Modbus mapping. The YML example below assumes the devices named 'solar', 'outdoor', and 'indoor' exist. Polling any Unit Id but 1, 2 or 3 will result in a Modbus exception 0x0A.

  - name: mbus_srv
    driver: presentations.modbus.mbdia_pres:MbDiaPresentation
        mapping: "( (1,'solar'), (2,'outdoor'), (3,'indoor') )"

Auto-Enumerated Mapping

The YML below assumes the auto-enum driver named 'xbee_autoenum' exists. It allows automatic creation of Modbus slaves numbered 1 to 20. Note that the same mbus_map.txt file is created to make the auto-assignment consistent between gateway reboots. You can edit this file as desired. To remove a device previously mapped, delete the appropriate line of the file. New devices will be placed into the lowest Unit Id available, so if you delete Unit Id 3 when 10 are defined, the next device discovered will be placed as Unit Id 3.

  - name: mbus_srv
    driver: presentations.modbus.mbdia_pres:MbDiaPresentation
        mapping: "('auto', 1, 20)"
        auto_enum_name: xbee_autoenum

Forming Modbus Responses

The Modbus server module requires the target Dia device driver to support the following methods:

  • Returns a string name of the type. No particular meaning is assigned - it can be the class name, but does not need to be.
  • Returns a numeric code, which is included as one of the registers in the register block response. No particular meaning is assigned - it can be the lower DD word or any other value.
  • Returns a dictionary of values for use with the Modbus Read Device Identification command (not yet implemented in the Modbus code, but will be eventually). The dictionary keys are the numeric "Object Ids" defined by the standard, and the values are all ASCII strings. Here is an example:
    def export_device_id( self):
        """Return the Device Id response strings"""
        dct = { 0:'Digi', 1:'XS-B14-CB1RB', 2:'1.0', 3:'www.digi.com',
                4:'XBee Sensor', 5:'/L/T', 6:'Dia' }
        return dct

To summarize the Object Id items:

Object Id Required Description
0x00 Yes Vendor Name
0x01 Yes Product Code
0x02 Yes Major/Minor Revision
0x03 Yes Vendor URL
0x04 No Product Name
0x05 No Model Name
0x06 No User Application Name
export_base_regs( req_dict)
  • extract the python dictionary formatted for the Modbus block. The input dictionary will include the actual Modbus request parsed, so you can tailor the output to fit the request. See the examples in src\devices\modbus. The caller expects you to return a list (an 'array') of 16-bit integers which custom fit the Modbus request exactly. If the Modbus request is coil/boolean based, then the return is a list of boolean True/False values.

A call to src.common.modbus.mbdia_block.mbblk_to_data() creates this array for the standard values of ['status', 'din', 'ain1', 'ain2', 'ain3', 'ain4', 'dot', 'aot1', 'aot2', 'aot3', 'aot4', 'volt', 'timestamp', 'dd', 'mac' ], but nothing stops you from manually creating your own custom response without using mbblk_to_data(). See the wiki page Modbus_Dia_Block_Register_Map to understand the standard register mapping.

The req_dict will include at least keys:

  • req_dict['protfnc'] = Modbus function code such as 3 or 6.
  • req_dict['dst'] = Modbus Slave Address / Unit Id.
  • req_dict['iofs'] = zero-based offset from the request.
  • req_dict['icnt'] = object count from the request.

See the file src.common.modbus.mbus_pdu.py to review the other keys usable.

import_base_regs( req_dict)
  • allows Modbus to write data - FUTURE FEATURE, SO NOT YET SUPPORTED
Personal tools
Wiki Editing