Debug Logs for api.particle.io

photon
Tags: #<Tag:0x00007fe2233c6858>

#1

If TL;DR, go to question at bottom.

I’ve got a very unique project I’ve developed that has no real practical real-world application, but it involves curling https://api.particle.io/v1/devices/device_id/function_name to call a photon function from PHP. This is the application:

I have a small chicken coop with cameras that stream 24/7 on YouTube so people can watch the chickens live their best lives, lay eggs and run around. Viewers can also feed the chickens by using YouTube SuperChat (pay a buck, the chickens get a treat, fully automatic - like a virtual zoo but without having to leave your house - totally integrated into YouTube’s payment flow - lots of fun for everyone). There’s a photon powering the feeder, it’s been working flawlessly for 5 months.

Recently I added a second photon to control the gate on the coop so that moderators (viewers around the world who are hand selected to also moderate comments) can click a button on a website and close the gate at night once all the chickens go in to roost.

That flow looks like this:

-Mod pushes button on web page.
-Javascript sends command via Ajax to PHP to close the gate
-PHP script logs this action into a MySQL database
-PHP sends a pushover notification to my phone to let me know a mod closed the door
-PHP cURLs https://api.particle.io/v1/devices/device_id/function_name - this calls the closeGate() function in the photon.

This feature has only been turned on for three days, but today, for some reason everything in the above PHP script fired properly, but the gate didn’t close. So it could be that there was an error with the PHP connecting to the Particle cloud, or it could have been that the photon was offline at that moment, or a number of other things.

My question is: is there a log some place that shows all of the calls to the API for a specific device that I could look through? It’s only happened once, but this has only been used 3 times. So there’s no telling what the stats are on failure rate.

And if you want to see the project, it’s here. They’re all asleep now but they get up early and the photon automatically opens the gate at sunrise: https://www.youtube.com/watch?v=n0E_aZ5C0x8


#2

The calls may be logged in the background but these logs are not “publicly” available.
You may be able to ask Particle to look into the logs when they know the exact time and device ID.
But knowing what happend wouldn’t realy solve anything.
Your setup should be resilient against any likely case like temporary loss of connection. For that you’d usually not just fire and forget a function call but actually wait for the response of the API call and act accordingly (open vs. closed loop control).


#3

Got it! For now I’ll try to log the response into my database and see if I get anything useful. Hopefully it doesn’t happen too often. Additionally, I’ll add a few attempts in PHP that will fire until we get a positive response. I also have a UI response that I can throw an error to the user to let them know success or failure (I also block the user from making repeated requests to close the gate for ten minutes so I will only do this if a successful function call has been made so they can try again). Unfortunately with PHP unless I have a separate script running, I don’t think it’s possible to have it continue to try indefinitely without holding up the user, so I will need to have a small finite number of attempts.


#4

When this keeps happening a lot the first thing to investigate would be your code for any potential pitfalls.
You may also want to test the function via console.particle.io/devices and see whether this also misbehaves.
If your code is clean and it also happens a lot via console you can request for someone to look into your logs.

BTW, have you considered a server side JS script instead of PHP to allow for asynchronicity?


#5

What Scruff said. Use PHP to lodge a job. Queue processor comes along and processes job.

My favourite way to do this is simply push a target device ID into firebase. Have a google cloud function watching for writes that fires up and processes. Don’t even need to delete if you want to keep a track of the original requests as a form of log trail.

I’ve hacked this quickly together from bits of our code to show you how to write a google cloud function to call Particle

var rp = require('request-promise');
var functions = require('firebase-functions');

/* do your firebase initialisation */

var settings = {};
let serviceAccount = "";

serviceAccount = require("./serviceAccountKey.json");
settings.credential = admin.credential.cert(serviceAccount); //admin.credential.applicationDefault(); //admin.credential.cert(serviceAccount);
settings.databaseURL = "YOURURL"
admin.initializeApp(settings);

var fs = admin.firestore();
var db = admin.database();


exports.processJob = functions.database.ref('/jobs/{newRow}').onCreate((change, context) => {

	return rp({
		method: 'POST',
		url: particleApiUrl + message.coreid + '/closeDoor',
		form: {
			access_token: particleAccessToken,
			args: 1
		},
		timeout: 5 * 1000

	})
		.then(function (body) {
			console.log(body);

			let temp = JSON.parse(body);

			console.log(temp);

			// Mark done
			let successMsg = {
				result: "Success",
				coreid: message.coreid,
				returned: temp['return_value']
			}
			console.log('From api:', successMsg);

			// return the requirement to finish all the updates in the array. sneaky!
			return res.status(200).send(successMsg);


		})
		.catch(function (err) {
			// POST failed...

			var error = 'ParticleAPI cancelLidOpen (cancelLidOpenMode) failure ' + err;
			console.error(error);
			//throw new Error('requestpromise error ', err);


			return res.status(500).send(error);

		});

});

#6

Hey @joevitale I love this app! Hopefully this helps with debugging the responses of those Particle API calls. I’m attaching a link to the docs on calling a function via the API.

As for connectivity, what’s the possibility of checking that the device is online before publishing an event?

As for storing the API response info into your database, I would avoid that. If there’s a way for you to read the response of the API call in PHP and handle things there, that might be more efficient. If you fall into cases where you can’t handle the API response, I would use tools like Loggly or Sentry to capture those edge cases so you can debug them later. It also makes for a very good way to identify where things are going wrong in the flow. You can also just send the API response to those services as well.

Hopefully some of this helps :smiley:

Call Function Docs: https://docs.particle.io/reference/device-cloud/api/#call-a-function
Ping Device Docs: https://docs.particle.io/reference/device-cloud/api/#ping-a-device
Read API Response in PHP: https://weichie.com/blog/curl-api-calls-with-php/