I have a Raspberry Pi setup, that needs to be able to receive JSON (from Salesforce). I'm not very familiar with JSON, but I believe this is possible with the REST API.
Anyway, I have downloaded Flask which should capable of doing this for me. When it receives this JSON, I need it to work with a Python script, or work in the same way as this script I already have setup. (This is the script: here). The script remotely controls some power outlets, and I would like Salesforce to be able to turn one one, when triggered. So far, I can control the Power from a web interfaces, using either URL variables, or a POST from a form. This all works well.
I'm just at the last stage, and also the one I have least experience in. What will the JSON Salesforce can send look like? How do I parse this and make it control the Power Outlets via Python?
Your plan is the following:
[Salesforce] <---> [Flask API] <--> [Raspberry PI]
Salesforce will be creating JSON messages that must be sent to your Flask API that interacts with the raspberry.
I see you have the interaction with Raspberry PI ready so you should create endpoints with Flask to be triggered from the outside.
As an example of a couple of flask endpoints:
# 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.get(deviceId)
# get some extra parameters
# let's say how long to stay on
params = request.get_json()
try:
device.turn_on(params['durationinminutes'])
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.get(deviceId)
try:
device.turn_off()
payload['success'] = True
return payload
except:
payload['success'] = False
# add an exception description here
return payload
In the salesforce side you need to create an object structure to keep track of devices, but I want to show what would be the APEX code needed to send a JSON message to your Flask API.
You'll have a DevicesController class that will have methods that will be triggered from a visualforce page let's say Devices.page
As an example you'll have a method that turns on a device:
// this should return something but for the sake of simplicity
public void turnDeviceOn(String externalDeviceId, Integer durationInMinutes){
# generate json message
JSONGenerator gen = JSON.createGenerator(true);
gen.writeStartObject();
gen.writeIntegerField('durationinminutes', durationInMinutes);
gen.writeEndObject();
# generate http request
HttpRequest req = new HttpRequest();
req.setMethod('POST');
# this endpoint must be added as a remote endpoint in Salesforce org setup!
req.setEndpoint('http://yourapiurl/API/v1.0/power-on/'+externalDeviceId);
req.setBody(gen.getAsString());
HTTPResponse res = h.send(req);
}
Please note that this is a basic Salesforce <--> Flask API example.
You'll need to add an authentication mechanism and more control on the entire flow.
EDIT:
Since you asked if this can be added to your code I've forked your repo and integrated that flask endpoint code to your power.py file.
The best solution is that you should put it on a separated class and handle routes on a different file, but can be all together so you get the idea.
You can clone it, install Flask module:
pip install flask
And execute it with:
python power.py
Then test the endpoints with:
curl -X POST http://localhost:5000/API/v1.0/power-on/<deviceid>