github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/mappers/modbus_mapper/src/modbus.js (about)

     1  const ModbusRTU = require('modbus-serial');
     2  const Buffer = require('buffer').Buffer;
     3  const async = require('async');
     4  const common = require('./common');
     5  
     6  class Modbus {
     7      constructor(protocol, visitor){
     8          this.protocol = protocol;
     9          this.visitor = visitor;
    10          this.client = new ModbusRTU();
    11      }
    12  
    13      // connect to device with modbus protocol
    14      connect(callback) {
    15          let protocol = this.protocol;
    16          let client = this.client;
    17          switch(protocol.protocol) {
    18              case 'modbus-tcp':
    19                  client.connectTCP(protocol.protocol_config.ip, { port: parseInt(protocol.protocol_config.port) }, ()=>{
    20                      client.setTimeout(500);
    21                      client.setID(parseInt(protocol.protocol_config.slaveID));
    22                      callback(client);
    23                  });
    24                  break;
    25              case 'modbus-rtu':
    26                  async.series([
    27                      function(callback) {
    28                          setTimeout(function () {
    29                             callback(null, null);
    30                          }, 100);
    31                      },
    32                      function (callback) {
    33                          client.connectRTUBuffered(protocol.protocol_config.serialPort, { baudRate: parseInt(protocol.protocol_config.baudRate) }, ()=>{
    34                              client.setTimeout(500);
    35                              client.setID(parseInt(protocol.protocol_config.slaveID));
    36                              callback(null, client);
    37                          });
    38                      }], (err, res) => {callback(res[1]);
    39                  });
    40                  break;
    41              default:
    42                  logger.info('unknwon modbus_type ', protocol.protocol);
    43                  break;
    44          }
    45      }
    46  
    47      // WriteAction write the value into device registers
    48      WriteAction(value, callback) {
    49          let visitor = this.visitor;
    50          let client = this.client;
    51          switch(visitor.visitorConfig.register){
    52          case 'CoilRegister':
    53              client.writeCoils(parseInt(visitor.visitorConfig.index), value, (err, data)=>{
    54                  client.close();
    55                  callback(err, data);
    56              });
    57              break;
    58          case 'HoldingRegister':
    59              client.writeRegisters(parseInt(visitor.visitorConfig.index), value, (err, data)=>{
    60                  client.close();
    61                  callback(err, data);
    62              });
    63              break;
    64          default:
    65              client.close();
    66              logger.info('write action is not allowed on register type ', visitor.visitorConfig.register)
    67              callback('unkown action', null);
    68              break;
    69          }
    70      }
    71  
    72      // PreWriteAction transfer data before writing data to register
    73      PreWriteAction(type, value, callback) {
    74          let visitor = this.visitor;
    75          let transData;
    76          async.waterfall([
    77              function(callback) {
    78                  switch(type) {
    79                      case 'int':
    80                      case 'float':
    81                          value = parseInt(value);
    82                          if (visitor.visitorConfig.register === 'CoilRegister') {
    83                              transData = (value).toString(2).split('').map(function(s) { return parseInt(s); });
    84                          } else if (visitor.visitorConfig.register === 'HoldingRegister') {
    85                              common.IntToByteArray(value, (byteArr)=>{
    86                                  if (byteArr.length < visitor.visitorConfig.offset) {
    87                                      let zeroArr = new Array(visitor.visitorConfig.offset -byteArr.length).fill(0);
    88                                      byteArr = zeroArr.concat(byteArr);
    89                                      transData = byteArr;
    90                                  } else {
    91                                      transData = byteArr;
    92                                  }
    93                              });
    94                          } else {
    95                              transData = null;
    96                          }
    97                          callback(null, transData);
    98                          break;
    99                      case 'string': {
   100                          let buf = new Buffer.from(value);
   101                          transData = buf.toJSON().data;
   102                          callback(null, transData);
   103                          break;
   104                      }
   105                      case 'boolean':
   106                          if (value === 'true') {
   107                              transData = [1];
   108                          } else if (value === 'false') {
   109                              transData = [0];
   110                          } else {
   111                              transData = null;
   112                          }
   113                          callback(null, transData);
   114                          break;
   115                      default:
   116                          transData = null;
   117                          callback(null, transData);
   118                          break;
   119                  }
   120              },
   121              function(transData, callback) {
   122                  if (visitor.visitorConfig.isRegisterSwap && transData != null) {
   123                      common.switchRegister(transData, (switchedData)=>{
   124                          callback(null, switchedData);
   125                      });
   126                  } else {
   127                      callback(null, transData);
   128                  }
   129              },
   130              function(internalData, callback) {
   131                  if (visitor.visitorConfig.isSwap && internalData != null && (visitor.visitorConfig.register === 'HoldingRegisters' || visitor.visitorConfig.register === 'CoilsRegisters')) {
   132                      common.switchByte(internalData, (switchedData)=>{
   133                          callback(null, switchedData);
   134                      });
   135                  } else {
   136                      callback(null, internalData);
   137                  }
   138              }], function(err, transData) {
   139                  callback(transData);
   140              }
   141          );
   142      }
   143  
   144      // ReadAction read register data from device
   145      ReadAction(callback) {
   146          let visitor = this.visitor;
   147          let client = this.client;
   148          switch (visitor.visitorConfig.register) {
   149              case 'CoilRegister':
   150                  client.readCoils(parseInt(visitor.visitorConfig.index), parseInt(visitor.visitorConfig.offset), (err, data)=>{
   151                      client.close();
   152                      callback(err, err?data:[data.data[0]]);
   153                  });
   154                  break;
   155              case 'DiscreteInputRegister':
   156                  client.readDiscreteInputs(parseInt(visitor.visitorConfig.index), parseInt(visitor.visitorConfig.offset), (err, data)=>{
   157                      client.close();
   158                      callback(err, err?data:[data.data[0]]);
   159                  });
   160                  break;
   161              case 'HoldingRegister':
   162                  client.readHoldingRegisters(parseInt(visitor.visitorConfig.index), parseInt(visitor.visitorConfig.offset), (err, data)=>{
   163                      client.close();
   164                      callback(err, err?data:data.data);
   165                  });
   166                  break;
   167              case 'InputRegister':
   168                  client.readInputRegisters(parseInt(visitor.visitorConfig.index), parseInt(visitor.visitorConfig.offset), (err, data)=>{
   169                      client.close();
   170                      callback(err, err?data:data.data);
   171                  });
   172                  break;
   173              default:
   174                  client.close();
   175                  logger.info('read action is not allowed on register type ', visitor.visitorConfig.register)
   176                  callback('unknown Registers type', null);
   177                  break;
   178          }
   179      }
   180  
   181      // ModbusDelta deal with the delta message to modify the register
   182      ModbusDelta(type, value, callback) {
   183          this.connect(()=>{
   184              this.PreWriteAction(type, value, (transData)=>{
   185                  if (transData != null) {
   186                      this.WriteAction(transData, (err, data)=>{
   187                          callback(err, data);
   188                      });
   189                  }
   190              });
   191          });
   192      }
   193  
   194      // ModbusUpdate deal with the update message to read the register
   195      ModbusUpdate(callback) {
   196          this.connect(()=>{
   197              this.ReadAction((err, data)=>{
   198                  callback(err, data);
   199              });
   200          });
   201      }
   202  }
   203  
   204  module.exports = Modbus;