-1

I am coding an app with Flask python that allows me to manage 2 different motors. One for a solid silos, another one for a liquid silos.

To connect to these motors I am using an OPCUA connection. On my python file, I was repeating the code twice because it's exactly the same process, only the nodeId is changing. For the solid it is ua.NodeId(13,4) and for the other it's ua.NodeId(23,4).

I tried to write the following code:

from flask import Flask 
from flask import request 
from flask import render_template
from opcua import Client
from opcua import ua

client = Client("opc.tcp://{ip}:4840/freeopcua/server/".format(ip='10.1.5.xxx')) 
root = client.get_root_node()
objects = client.get_objects_node()
client.connect()
client.load_type_definitions()

app = Flask(__name__)

drive_state = 'Off'
if request.endpoint == 'solid_silos':
   statusId = client.get_node(ua.NodeId(13, 5))
elif request.endpoint == 'liquid_silos':
    statusId = client.get_node(ua.NodeId(23, 5))
statusId_val = statusId.get_value() 
if statusId_val == 1:
    drive_state = 'On'
if statusId_val == 2:
    drive_state = 'Off'
print(statusId_val)

opc_state = 0

@app.route('/solid_silos/', endpoint='solid_silos')
@app.route('/liquid_silos/', endpoint='liquid_silos')
def form():
    global drive_state
    if request.endpoint == 'solid_silos':
        statusId = client.get_node(ua.NodeId(13, 5))
    elif request.endpoint == 'liquid_silos':
        statusId = client.get_node(ua.NodeId(23, 5))
    statusId_val = statusId.get_value() 
    if statusId_val == 1:
        drive_state = 'On'
        function_id = 101
    if statusId_val == 2:
        drive_state = 'Off'
        function_id = 100
    print(statusId_val)
    if request.endpoint == 'solid_silos':
        return render_template('solid_silos.html',drive_state=drive_state, function_id=function_id) 
    elif request.endpoint == 'liquid_silos':
        return render_template('liquid_silos.html',drive_state=drive_state, function_id=function_id) 

but i end up with this issue raise AssertionError( AssertionError: View function mapping is overwriting an existing endpoint function: liquid_silos

Also, the two different pages are separated with tabs that i created in the html files like this:

<div id="menu">
        <ul id="onglets">
            <li><a href="/solid_silos/"> Solid Silos </a></li>
            <li class="active"><a href="/liquid_silos/"> Liquid Silos </a></li>
        </ul>
</div>
Camille BOUQUET
  • 445
  • 1
  • 6
  • 18

1 Answers1

2

The error implies that when giving the second annotation flask tries to override the endpoint defined by the first annotation and this is not supported by Flask and seems to miss the purpose of what you were trying to achieve here.

And more generally, endpoints are most commonly used for revers lookup and do not seem to be meant for the use case here.

for more info - What is an 'endpoint' in Flask?

If I understand your goal correctly, this might do the trick:

@app.route('/solid_silos/')
def form_solid_silos():
   return form(client.get_node(ua.NodeId(13, 5)), 'solid_silos.html')

@app.route('/liquid_silos/')
def form_liquid_silos():
   return form(client.get_node(ua.NodeId(23, 5)), 'liquid_silos.html')

def form(statusId, template_file):
    global drive_state    
    statusId_val = statusId.get_value() 
    if statusId_val == 1:
        drive_state = 'On'
        function_id = 101
    if statusId_val == 2:
        drive_state = 'Off'
        function_id = 100
    print(statusId_val)
    return render_template(template_file, drive_state=drive_state, function_id=function_id)
Assaf
  • 316
  • 2
  • 6
  • I tried your code with `return form(1)` and `return form(2)` and `statusId_val = statusId`. I am not connected to the motors, so I wanted to test with simple values. And I got the following issue when i go on `http://localhost:5000/liquid_silos/`: `raise TypeError(TypeError: The view function for 'form_liquid_silos' did not return a valid response. The function either returned None or ended without a return statement.` and the same when I go on `http://localhost:5000/solid_silos/`: same error with ` 'form_liquid_silos' did not return a valid response.` – Camille BOUQUET Aug 19 '21 at 09:36
  • Sorry, my bad, I did not notice that the endpoint name was being used when returning the template. I edited the code, it should be fine now. – Assaf Aug 19 '21 at 12:12