thiagoralves / OpenPLC_v3

OpenPLC Runtime version 3
1.02k stars 421 forks source link

Attempting to add a REST type API/URL to Webserver.py #243

Open ggiraudon opened 1 month ago

ggiraudon commented 1 month ago

Hi,

I'm playing around with a project that combines OpenPLC with NodeRed. So far, accessing data values from OpenPLC using Modbus is workable but a bit convoluted. In particular, I have to constantly remap the variables I created in OpenPLC to new ones on any other piece of software I connect to user Modbus because the protocol doesnt carry anything like variable names.

To make things a bit simpler, I thought I would add a REST type URL to the webserver component of the runtime. The idea is that it would work a bit like the monitoring page (/monitor-update to be more precise) but output its contents in JSON instead of an HTML table.

My attempt is a bit crude but works (to a certain extent). I added the following to webserver.py :

@app.route('/monitor-json', methods=['GET', 'POST'])
def monitor_json():
    return_str = '{ "modbus" : [ '

    #if (openplc_runtime.status() == "Running"):
    if (True):
        mb_port_cfg = flask.request.args.get('mb_port')
        monitor.start_monitor(int(mb_port_cfg))
        data_index = 0
        for debug_data in monitor.debug_vars:
            if(data_index > 0):
                return_str += ',';
            return_str += '{ "name" : "' + debug_data.name + '", '
            return_str += ' "type" : "' + debug_data.type + '", '
            return_str += ' "location" : "' + debug_data.location + '", '
            return_str += ' "forced" : "' + debug_data.forced + '" ,'
            if (debug_data.type == 'BOOL'):
                if (debug_data.value == 0):
                    return_str += ' "value" : "0" }'
                else:
                    return_str += ' "value" : "1" }'
            else:
                return_str += ' "value" : "' + str(debug_data.value) + '" }'
            data_index += 1

    return_str += ']}'

    return return_str

I do have to issues however :

1 -> I had to disable authentication to make it work. I'm thinking of handling it by either accepting a username and password in a POST payload, or alternatively adding an authentication key system that can be generated in the settings page. What do you think the best approach would be ?

2 -> It seems that after a while, the data I get is stale. I still get the correct JSON structure but the variables values no longer update. However, if I open a browser to the web UI and log in, data starts updating again. I'm not sure why that is since the browser window I opened is not on the same host as the code making the JSON requests so it can't be a session thing. Any ideas on what might be wrong ?

Thanks in advance and kudos again for a great piece of technology.