Appendix C Interfacing Generator Monitor to External Applications - jgyates/genmon GitHub Wiki

GenMon supports multiple ways to export information to external applications. Applications can interface via TCP/IP. The ClientInterface.py python module is a wrapper for TCP/IP communications to GenMon. In addition the web server application genserv.py is an additional layer that uses ClientInterface module internally to expose a web based interface. Both the ClientInterface and the web interface support exporting data in ASCII and JSON format. The ClientInterface supports many commands to export data which are documented in the Genmon documentation. In addition JSON specific commands have been added. These JSON commands mimic existing GenMon commands in the type of data that is exported, however the format of the data is JSON instead of ASCII. The JSON commands are:

  • status_json - export generator status
  • status_num_json - export generator status in numeric format
  • outage_json - export outage information
  • maint_json - export maintenance information
  • monitor_json - export information about genmon
  • logs_json - export generator logs
  • registers_json - export primary registers of the generator controller
  • allregs_json - export primary registers and raw log registers

The following repository items are examples of how to interface to Genmon:

  • Web UI - genserv.py, /static/genmon.js. These modules show how to interface to genmon via the web interface.
  • Web UI = /static/internal.js. This modules uses JSON formatted data to display registers.
  • ClientInterface.py - This command line application uses the myclient.py python module to make socket calls. See the genmon documentation for use.
  • ClientInterface.java - This java module is the java equivalent of myclient.py. It has had minimal testing but is provided as an example of interfacing to genmon via java If there are any questions regarding how to interface to genmon, feel free to open a thread in the issues section of this project.

Displaying External Information in the Web UI

The Generator Monitor can display end user data on the Monitor page in the Web Interface. Data is imported into the Generator Monitor by storing JSON formatted data in a file named "userdefined.json" in the genmon directory. The directory can be changed via the advanced settings (double click the gear icon in the upper right). For example you could create a python program that will read the pi's GPIO pins every 5 seconds. If the GPIO changed the program could re-write the userdefined.json file to show the GPIO status.

Home Automation

There are a few folks who have integrated Genmon with some home automation software like NodeLink and Home Assistant. For more info search the issues in this project for the "automation" label. To better integrate with home automation software, the program genmqtt.py was created to import genmon data into a MQTT broker. MQTT is a transport protocol that is used in "Internet of Things" (IoT) and Home Automation applications.

Web API

If you have setup secure http with a username and password you can login like this:

import requests
url = 'https://192.168.1.10'    # change to your pi IP address
values = {'username': 'myusername',   # change myusername to your username
          'password': 'mypassword'}   # change mypassword to your password

try:
    session = requests.Session()
    # disable SSL checking for self signed keys
    # remove if using user generated keys
    session.verify = False  
    r = session.post(url, data=values)
    #print r.text
    # get the status data via the same session we used to login
    r = session.get(url + "/cmd/status_json")
    print r.text
except Exception as e1:
    print ("Error: " + str(e1))

You can make calls to the web server. For example if you pi is at IP address 192.168.1.10 you can make use this url:

    http://192.168.1.10:8000/cmd/status_json

The different commands are listed in the code at this location

Another command of interest would be the "getbase" command:

    http://192.168.1.10:8000/cmd/getbase

This is command is used to change the colors of the menu on the web interface. It returns one of the following states:

    ALARM, SERVICEDUE,EXERCISING, RUNNING,RUNNING-MANUAL,OFF, or READY

You can get all the info that is displayed in the web app with these commands:

     status_json, maint_json, outage_json, logs_json, monitor_json

If you enter the url with your ip address in your browser you will see the output in JSON format. This can easily be used in most programming languages hat support sockets and JSON. From the Linux command line you can use the curl utility like this:

     curl http://192.168.1.10:8000/cmd/status_json

Extend genserv.py

You can also extend the server urls provided by the internal web server (Flask server).

genserv.py will look for a file in the genmon folder named genservext.py, if it is present it will import that file.

The file genservext.py should look something like this:

 from __future__ import print_function
 from __main__ import app
 from genserv import ServePage

 #-------------------------------------------------------------------------------
 @app.route('/testit', methods=['GET'])
 def testit():
     return ServePage("myhtml.html")

This will load the file myhtml.html from the ./genmon/static folder if you use the http://192.168.1.10:8000/testit URL.

From here you can create a new html (myhtml.html) in the ./genmon/static folder that loads a javascript (also in the static folder) file and add additional python commands (GPIO, etc) to genservext.py.

Extend genmon.py

Similar to the above method, this approach allows you to extend genmon by monitoring and acting on commands sent to genmon by the socket interface. genmon.py will look for a file in the genmon folder named genmonext.py, if it is present it will import that file and load a python class named GenmonExt. For external command received on the socket interface, genmon will call the GenmonExt member function named PreProcessCommand. Here is an example genmonext.py:

from genmonlib.mysupport import MySupport


#------------ GenmonExt class --------------------------------------------------
class GenmonExt(MySupport):
    def __init__(self,
        log = None):

        self.log = log

        self.LogError("GENMONEXT Loaded")
        # init class

    #-------------------------------------------------------------------------------
    # called before any command is processed
    def PreProcessCommand(self, command_string):

        try:
            # parse command
            if not isinstance(command_string, str):
                # invalid command
                return
            if not (command_string.lower().startswith == "generator:"):
                return

            if not "setremote=" in  command_string.lower():
                return
            if "=starttransfer" in command_string.lower():
                return
            if "=start" in command_string.lower():
                # start command
                self.LogError("Set remote start")
                return
            if "=stop" in command_string.lower():
                # stop command
                self.LogError("Set remote stop")
                return
        except Exception as e1:
            self.LogErrorLine("Error in PreProcessCommand: " + str(e1))
        return

NOTE: This interface does not allow commands to be changed, only monitored.