Pregunta

I have asked a few questions about this before, but still haven't solved my problem.

I am trying to allow Salesforce to remotely send commands to a Raspberry Pi via JSON (REST API). The Raspberry Pi controls the power of some RF Plugs via an RF Transmitter called a TellStick. This is all setup, and I can use Python to send these commands. All I need to do now is make the Pi accept JSON, then work out how to send the commands from Salesforce.

Someone kindly forked my repo on GitHub, and provided me with some code which should make it work. But unfortunately it still isn't working.

Here is the previous question: How to accept a JSON POST?

And here is the forked repo: https://github.com/bfagundez/RemotePiControl/blob/master/power.py

What do I need to do? I have sent test JSON messages n the Postman extension and in cURL but keep getting errors.

I just want to be able to send various variables, and let the script work the rest out.

I can currently post to a .py script I have with some URL variables, so /python.py?power=on&device=1&time=10&pass=whatever and it figures it out. Surely there's a simple way to send this in JSON?

Here is the power.py code:

# add flask here
from flask import Flask
app = Flask(__name__)
app.debug = True
# keep your code
import time
import cgi
from tellcore.telldus import TelldusCore
core = TelldusCore()
devices = core.devices()

# define a "power ON api endpoint"
@app.route("/API/v1.0/power-on/<deviceId>",methods=['POST'])
def powerOnDevice(deviceId):
    payload = {}
    #get the device by id somehow
    device = devices[deviceId]
    # get some extra parameters 
    # let's say how long to stay on
    params = request.get_json()
    try:
        device.turn_on()
        payload['success'] = True
        return payload
    except:
        payload['success'] = False
        # add an exception description here
        return payload

# define a "power OFF api endpoint"
@app.route("/API/v1.0/power-off/<deviceId>",methods=['POST'])
def powerOffDevice(deviceId):
    payload = {}
    #get the device by id somehow
    device = devices[deviceId]
    try:
        device.turn_off()
        payload['success'] = True
        return payload
    except:
        payload['success'] = False
        # add an exception description here
        return payload

app.run()
¿Fue útil?

Solución

Your deviceID variable is a string, not an integer; it contains a '1' digit, but that's not yet an integer.

You can either convert it explicitly:

device = devices[int(deviceId)]

or tell Flask you wanted an integer parameter in the route:

@app.route("/API/v1.0/power-on/<int:deviceId>", methods=['POST'])
def powerOnDevice(deviceId):

where the int: part is a URL route converter.

Your views should return a response object, a string or a tuple instead of a dictionary (as you do now), see About Responses. If you wanted to return JSON, use the flask.json.jsonify() function:

# define a "power ON api endpoint"
@app.route("/API/v1.0/power-on/<int:deviceId>", methods=['POST'])
def powerOnDevice(deviceId):
    device = devices[deviceId]

    # get some extra parameters 
    # let's say how long to stay on
    params = request.get_json()
    try:
        device.turn_on()
        return jsonify(success=True)
    except SomeSpecificException as exc:
        return jsonify(success=False, exception=str(exc))

where I also altered the exception handler to handle a specific exception only; try to avoid Pokemon exception handling; do not try to catch them all!

Otros consejos

To retrieve the Json Post values you must use request.json

if request.json and 'email' in request.json:
    request.json['email']
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top