Skip to content

Appendix N Genmon Supporting Other Controller Types

jgyates edited this page Aug 27, 2023 · 61 revisions

Genmon Supporting Other Controller Types

Beginning with genmon V1.17.0, to support other types of generator controllers the software supports an extensible architecture that will allow for additional controllers to be defined in a JSON format file based on modbus registers and numeric and bit definitions within the modbus registers. If new controllers are defined feel free to submit them to the project. New JSON files can be added to genmon/data/controllers and the advanced settings page will display them as a configuration option. Double click the gear icon in the upper right of the web interface to access the advanced settings page.

Currently Supported via the Custom Controller Interface:

Controller JSON File Description
Evolution Liquid Cooled Evolution_Liquid_Cooled.json Generac Evolution Liquid Cooled (Diesel)
Deep See Electronics Genset Controller Deepsea_controller.json https://www.deepseaelectronics.com/genset
Briggs & Stratton GC-1032 Controller Briggs_Stratton_GC-1032.json https://www.briggsandstratton.com/na/en_us/products/home-generators.html
Generac PowerZone 410 Controller Power_Zone_410.json https://www.generac.com/Industrial/GeneracIndustrialPower/media/library/A0001371117.pdf

How to Create Support for Additional Controllers

Know the modbus addresses

Use the modbusdump.py program in the OtherApps folder to validate either serial or serial over TCP communications with the controller. If you do not know the modbus address the controller uses you can potentially use this program to help determine the modbus address used. The genmon software will need to know the modbus address.

Obtain the modbus register definitions for your controller.

Using this information you can create a JSON format file that can be added to the project that will allow the generator to be supported with genmon. Note that complex manipulation of modbus register data is not supported wit this method so displaying log files or operations that deal with time and date are not supported using the JSON method at this time. The JSON file format syntax is listed below.

Enable the Custom Controller Type

Enable the Custom Controller Type - To enable the support for a user defined controller, modify the following entry to your /etc/genmon.conf file or change this value from the advanced page in the web interface.

controllertype = custom
import_config_file = filename.json

where filename.json is a JSON formatted file (see below) in the genmon/data/controller directory. Note: These values can be set from the advanced settings page. Double click the gear icon in the web interface to access the advanced settings page.

Modbus Communications

To facilitate communication differences is some controllers the following settings are available if the default values of 9600,N,8 and 1 are not compatible with your controller:

  • Optionally, enable "Use Modbus FC4 instead of FC3" on the Advanced Setting page - This allows the use fo modbus function 4 instead of function 3 to read modbus registers (Used for Briggs and Stratton controllers)
  • Use serial over network connections instead of direct serial connections. This includes Modbus TCP and serial over IP variants
  • Optionally, Edit the /etc/genmon/genmon.conf file and add an entry named 'serial_baud_rate' and set it to the desired baud rate (e.g. serial_baud_rate=11520)
  • Optionally, Edit the /etc/genmon/genmon.conf file and add an entry named 'serial_parity' and set it to 1 for odd parity and 2 for even parity. Remove the entry for no parity
  • Optionally, Edit the /etc/genmon/genmon.conf file and add an entry named 'serial_one_point_five_stop_bits' and set it to True to use 1.5 stop bits. Remove the entry or set it to False for 1 stop bit
  • Optionally, Edit the /etc/genmon/genmon.conf file and add an entry named 'serial_rate' and set it to the serial data rate (i.e. 115200, 19200, etc_ if using serial communications (not TCP). Only do this if the rate is something other than 9600 baud. The default rate is 9600. You can also change this setting on the Advanced Settings Page of the web interface (double click the gear icon to access Advanced Setting)

JSON File Syntax

NOTE: Before you start to develop an new JSON file for a generator that is not currently supported, the first thing to do is to make a copy and rename an existing JSON file and change the name of the "controller_name" entry in the file. If you do not change the name of the file your changes will be overwritten when the software is updated.

The file format is standard JSON format. The file can be validated using an online JSON format checker like this one. If the format does not conform to the JSON standard genmon will not load properly.

The file contains a single JSON object. Within the objects are several other objects. Presently there are no nested objects past the first level objects supported. The high level objects supported are:

  • "controller_name" - The name displayed for the controller in the software
  • “rated_max_output_power_kw" - This can be an Integer value. For example a 22kW system would use 22 for this value
  • “rated_nominal_voltage" - Integer value. This is typically 240 for US singled phase. For three phase put the maximum voltage of the combined phase. This value is used to set the gauge markings.
  • "rated_nominal_rpm” - Integer value, typically 1500, 1800, 3000 or 3600
  • "rated_nominal_freq" - Integer value. Typically 60 or 50
  • "nominal_battery_voltage" - Integer value. Typically 12 or 24
  • "generator_phase" - The phase of the generator (i.e. 1 or 3). This is an integer value
  • "base_registers" - an object of registers (4 digit hex values) and the second parameter describing the register. At a minimum the second parameter must be an integer specifying the length of each register. Each register length must be multiples of 2. For additional data in the user interface the second parameter can be a nested object that contains "length" and "text". The "base_registers" dict must contain all the registers that are read by the software. If another object in the JSON file references a register to read it must be defined in this object. These registers are read using the modbus read multiple register command (0x03). The modbus command to read input registers (0x04) can be used if the Advanced setting "Use Modbus FC4 instead of FC3" is enabled.

In addition to integer values the values of “rated_max_output_power_kw", “rated_nominal_voltage", "rated_nominal_rpm”, "rated_nominal_freq", "nominal_battery_voltage", and "generator_phase" can alternatively be a JSON object defining a register value (see examples in the repository). For example:

    "rated_max_output_power_kw":  {
        "reg": "0054",
        "mask": "7f00",
        "multiplier": 0.00390625,
        "type": "int",
        "title": "Nominal kW"
      }

If the values “rated_max_output_power_kw", “rated_nominal_voltage", "rated_nominal_rpm”, "rated_nominal_freq", "nominal_battery_voltage" can be set to non integer values, then the values for nominal kW, nominal line voltage, RPM, frequency and battery voltage will be used from the settings and advanced settings pages. For example if the JSON file looks like this:

    "nominal_battery_voltage": "Unknown"

then the value for nominal battery voltage will be set via the Advanced page.

The following JSON objects define logic conditions that can be performed on the resulting modbus data. All of the following objects consist of a single list of one or more condition objects. Some lists are evaluated as a single logic operation with multiple conditions (e.g. switch_state) and others are a list of multiple logic operations (e.g. status). A condition object is defined as a JSON object with the following members:

  • "reg" - modbus register. This value must be included in base_registers and it's length is also defined there. This value is a 4 digit string formatted as a hex number (e.g. "01fe")
  • "title" - A Title for the object. For single logic operations the name of the object is the same. For multiple operations the name is unique for each object in the list.
  • "type" - The describes the type of interpretation on the modbus data. Valid entries for this field are:
    • "bits" - The modbus value is AND-ed with the mask. If the result is equal to the "value" field, the the "text" field is displayed.
    • "int" - Integer value. The modbus value is AND-ed with the mask and the resulting integer value is returned.
    • "float" - Float value. Both "float" and "int" types can use the following modifiers: "multiplier", "shiftleft" and "shiftright".
      • "multiplier" - an integer or floating point value that multiplied by the modbus value and an int or floating point value is returned. If you need to shift values that are formatted as hex you can use decimal multipliers, for example a multiplier of 0.00390625 is the same as 1/256 or dividing by 0x100 hex or shifting right by 8 bits)
      • "shiftright" - shifts the modbus register right by the specified number of bits
      • "shiftleft" - shifts the modbus register left by the specified number of bits
    • "regex" - If the regex type is specified a "regex" field is used. The "regex" field contains a regular expression string (e.g. "^(1[0-9a-f]|[1-9a-f])$") to compare against the modbus results. The modbus results are stored in a hex string (e.g. "00a4"). If the regular expression evaluation is a match the "text" field is returned. Nothing is returned if the regular expression is evaluated to False unless a "default" value is specified.
    • "list" - This denotes that a JSON list of other types listed is used.
    • "object_int_index" - This denotes an integer that is a look up into a specified object. See the evo_lc.json example for details.
    • "ascii" - This denotes an ASCII string or a series of ASCII characters.
    • "default" - For single logic operations, if not condition is evaluated as true, this type of condition's "text" field will be used.
  • "mask" - This is a string representing a hex number. A logical AND operation is performed between the mask value value and the value read from the modbus register. The result of this is used to get the end value of the modbus register. This "mask" allows bits that are zero to be ignored in further calculations.
  • "value" - Used for type "bits", see above
  • "temperature" - if the value is an "int" or "float" this optional value can be "celsius" or "fahrenheit". This value will be converted, if necessary based on the "Use Metric Units" global setting.
  • "text" - The text string returned if type "bits" or type "regex" result in a True state. "text is also used with the "default" modifier in "list" and "object_int_index" types.
  • "sensor" - Used for gauge and sensor objects. Defines the type of sensor. Valid sensor types are: batteryvolts,linevolts,current,power,frequency,rpm,fuel,level,position,temperature,pressure,powergraph. These values determine the type of gauge or graph displayed. Only one powergraph is supported.
  • "nominal" - Used for gauge and sensor objects. Defines the nominal value of a gauge.

The following are the types of single condition lists (i.e. only one item in each list of objects is evaluated as true):

  • "switch_state" - Defines the conditions of the switch state.
  • "alarm_active" - (optional) Defines if an alarm is active. This is just an indicator if an alarm is active, not a specific alarm type.

The following are the types of multiple condition lists (i.e. all true entries are included in the returned status):

  • "status" - This list of objects determines the data displayed on the Status page of the web interface.
  • "maintenance" - This list of objects determines the data displayed on the Maintenance page of the web interface.
  • "alarm_conditions" - Defines the different types of alarms.
  • "generator_status" - Defines the generator status. This object is optional. For some controllers only switch_state and engine_state are needed.
  • "engine_state" - Defines the state of the engine.

Other types of objects:

  • "gauges" This list of objects defines the gauges displayed and the modbus values displayed.
  • "power" - Optional. This is defines the power output in kW. This is required to use the power log and estimated fuel consumption.
  • "fuel" - Optional. This defines the fuel level as a percentage. If this object is included then a fuel gauge will be added to sensors.
  • "run_hours" - This defines the run hours as an integer or float. This value provides the default run hours for the Service Journal.
  • "buttons" Optional. This list of objects defines the buttons displayed on the maintenance page and the modbus write commands that are issued if the button is pressed.
  • "linevoltage" - Optional. Utility line voltage. This value is used for determining when an outage occurs.
  • "outputvoltage" - Optional. Generator output voltage. This value is used if using external Current Transformers (CTs) to provide power. The current reading from the CT along with the generator output voltage is used to convert to power (assuming power is not provided by the controller registers)
  • "thresholdvoltage" - Optional. Can be an integer value or a JSON object defining a modbus register. This defines the line voltage level that signals the beginning of an outage
  • "pickupvoltage" - Optional. Can be an integer value or a JSON object defining a modbus register. This defines the line voltage level that signals the end of and outage
  • "datetime" - Optional. This is an object that describes the generator date and time. This can be in any format, but typically this is in "DayOfWeek Month DayofMonth, Year Hour:Min
  • "log_registers" - Optional. This object describes a range of registers that contain logs (e.g. alarm, run and service logs). This entry instructs genmon to read the described registers. The "logs" entry describes how the registers are displayed on the logs page in the user interface. See the file ./genmon/data/mib/Evolution_Liquid_Cooled.json
  • "logs" - Optional. This object describes how the log registers are displayed on the Logs page in the user interface. See the file ./genmon/data/mib/Evolution_Liquid_Cooled.json
  • "identity" - Optional. This is a register used to help identify the controller with a unique signature in the modbus registers. See the file ./genmon/data/mib/Power_Zone_410.json

Outage log: The outage log is enable if linevoltage, thresholdvoltage and pickupvoltage are defined.

gauges

The gauges member of the JSON object is an array of objects. Each object in the array represents a gauge or graph.

    "gauges": [
      {
          "reg": "0405",
          "mask": "ffff",
          "multiplier": 0.1,
          "type": "float",
          "title": "Battery Voltage",
          "units": "V",
          "sensor": "batteryvolts",
          "nominal": 24,
          "values": [0, 8, 10, 34, 36, 44],
          "maximum": 44
      },
      {
          "reg": "0424",
          "mask": "ffff",
          "multiplier": 1,
          "type": "int",
          "title": "Utility Voltage",
          "units": "V",
          "sensor": "linevolts",
          "nominal": 240
      },
      {
          "reg": "0408",
          "mask": "ffff",
          "multiplier": 1,
          "type": "int",
          "title": "Output Voltage",
          "units": "V",
          "sensor": "linevolts",
          "nominal": 240
      }

The 'sensor' member of each gauge in the list must be one of the following values: batteryvolts, linevolts, current, power, frequency, fuel, level, position, temperature, pressure, powergraph, rpm or wifi.

For a sensor of type "batteryvolts", "linevolts", "power"/"powergraph" or "frequency", the the nominal value is "Unknown" then the unknown value will attempt to be substituted for "nominal_battery_voltage", "rated_nominal_voltage", “rated_max_output_power_kw" or "rated_nominal_freq". If type "current" has a nominal value of "Unknown" then rated_nominal_voltage and “rated_max_output_power_kw will be used to calculate the rated current.

There can only be one gauge with a sensor value of 'powergraph'. The register value of the 'powergraph' must correspond to the power output power of the generator.

The members of each gauge object provide information that helps the software display the gauge data properly. The 'reg', 'mask', 'multiplier' and "type" properties are defined above. The 'units' and 'title' are used to mark the units and label assigned to the gauge. The 'sensor' value is used to set the markings on the graph. The 'nominal' and 'maximum' values along with the 'values' array can override some of the default values for each sensor type to help customize the gauge display for situations where the default values are not appropriate.

buttons

    "buttons" : [
      {
          "onewordcommand" : "stop",
          "title" : "Stop Mode",
          "command_sequence" : [
                                 {
                                   "reg": "1008",
                                   "value": ["8B", "74", "74", "8b"]
                                 }
                               ]
      },
      {
          "onewordcommand" : "auto",
          "title" : "Auto Mode",
          "command_sequence" : [
                                 {
                                   "reg": "0004",
                                   "value": "0000"
                                 },
                                 {
                                   "reg": "0003",
                                   "value": "0001"
                                 }
                               ]
      }

The 'buttons' object defines a list of objects. Each object in the list is a command that can be issued by the software. Each command object in the list has three objects:

  • 'onewordcommand' - used internally by the software to identify the command. This must be a single word (no spaces) and be unique in the list of buttons.
  • 'title' - This defines the text on the button that is displayed on the Maintenance page in the web interface.
  • 'command_sequence' - This is a list that defines write commands that are sent to the controller. The list must have at least one object. Each object in the list defines a single modbus write command. The 'reg' member of each command object contains a hex string that represent the modbus address to write using modubs Write Multiple Registers (0x10) command. This register value does not have to be in the 'base_registers' object listed above since this register is written, not read. The 'value' item in each command object can either be a decimal value (i.e. no quotes) or a quoted hex string (e.g "8b"). The 'value' item can also be a list of decimal or quoted hex strings. The list is used to force the command to be issued in one modbus command (i.e. write multiple registers with more than one 16 bit value written at a time). If the non-list version is used and multiple commands are in the 'command_sequence' each command will be issued back to back, but not as a single modbus transaction. This flexibility is offered since some controllers expect the commands to be issued in different write sequences.

SNMP addon program

SNMP is supported with custom contollers. To allow the custom controller to work with the SNMP genmon add on program, another JSON file must be created in the ~./genmon/data/mib folder. This file must be named the same as the controller file, but the contents is formatted differently. See the file ./genmon/data/mib/Evolution_Liquid_Cooled.json for details on the format and the wiki entry on the SNMP addon for details on SNMP OID numbering.