particle-iot / particle-api-js Goto Github PK
View Code? Open in Web Editor NEWJS Library for the Particle API
License: Apache License 2.0
JS Library for the Particle API
License: Apache License 2.0
Add test for the SSE Stream parser EventStream
. See #86
If including https://cdn.jsdelivr.net/particle-api-js/5/particle.min.js on a site that already has executed "require('babel-polyfill');", the script won't load and the API is not available.
The issue has been raised over at babel a few times (e.g. babel/babel#4019), but the issue seems to still exist.
A quick solution would likely be to do
if (! window._babelPolyfill) {
require("babel-polyfill");
}
in Particle.js to avoid requiring babel twice.
I currently have the problem that my particle events stream socket seems to be closed after a while without any notification if no events are happening.
I use an implementation similar to this one:
https://github.com/spark/sparkjs/blob/master/examples/node/get-event-stream-forever.js
New events will just not be sent to the client. Meanwhile, the client's 'end' event is not triggered, so there is currently no way for the client to know and no reconnection happens. This can be an issue with a user's network infrastructure, too. I need to find a way to ensure the channel still works after keeping it open for a longer while.
Is there already heartbeat/keepalive mechanism that allows the client to find out if the connection is still open? Or do I have to send events from my node client periodically to keep the subscription channel open and find out if I have to reconnect?
I'm trying to subscribe to my devices' event stream using the JS SDK from an Angular app I'm building with the Ionic framework. I am successfully able to use the SDK to do things like login and retrieve an access token, and get a list of devices. However, when I use the getEventStream
function, I get the following error:
Fetch API Cannot Load
http://api.particle.io/v1/devices/123456/events/spark/status
Request header field cache-control is not allowed by Access-Control-Allow Headers in preflight response.
(Of course, 123456 is not my real device ID, but I checked the number and it is correct.) If I use the promise response to catch the error I get:
TypeError: Failed to fetch at TypeError (native)
Network error from [url I typed above]
If I go into EventStream.js
and comment out the part where the cache-control
header is specified (around line 30), i.e. /*'Cache-Control': 'no-cache',*/
then it seems to work fine. (Actually, I commented this out in particle.min.js
but in the pre-minified version it's in EventStream.js
).
Any ideas why this isn't working? I'm testing it using the ionic serve
process in Google Chrome (Version 48.0.2564.103 (64-bit)) on OSX. I guess it's possible it could be a browser issue, and that the problem will go away when I compile for my mobile device...
If you'd like to check out my code, the part that launches the listener is in app.js around line 23.
NOTE: in the version in my repo, the cache-control
part is commented out of particle.min.js
There is presently an issue performing npm install particle-api-js
due to a known npm bug which, if I understand it correctly, is due to setting the 'latest' release as 5.3.0-develop.1
As an end-user, you can work around this by doing npm install [email protected]
. It is worth noting that the 5.3.0-develop.1 release is generally broken and while I'm not sure it is the appropriate solution, I have forked the repo and made some fixes.
Today I noticed a very weird problem where my servers cpu was maxed out when I added the particle event stream listener.
A device is sending every 10seconds a notification on an eventstream named 'test' and my cpu goes higher every time the device sends. After 4 or 5 messages it reaches 100% and everything stops working.
code is copied from the documentation https://docs.particle.io/reference/javascript/#get-event-stream
//Get all events
particle.getEventStream({ auth: token}).then(function(stream) {
If I change the code to listen on only one named event stream everything works fine.
//Get test events
particle.getEventStream({ auth: token, name: 'test'}).then(function(stream) {
Does anyone have an idea or a possible solution to support all events without blocking?
Particle.request() and downloadFirmwareBinary() explicitly set the 'User-Agent' string. This isn't allowed in the web browser (see http://stackoverflow.com/questions/7210507/ajax-post-error-refused-to-set-unsafe-header-connection). The API calls works fine if this code is removed.
Currently particle-api-js sends User-Agent: node-superagent/1.8.3
The default should be particle-api-js/${version}
. For different applications it would be useful to be able to set this value.
I would like to push events and listen to event streams from a server inside a corporate proxy. From what I can gather from the code, there's no current way to define proxy settings for the requests the lib is doing to the particle cloud api.
It seems like for normal functions within the Particle module, superagent-proxy (https://github.com/TooTallNate/superagent-proxy) and a configurable flag could solve it, since it uses superagent for the requests.
For EventStream it will be trickier since it uses default node http/https libraries. I've implemented the EventStream solution using request and setting the proxy there.
There may be a bug in the particle API js library in the handling of activateSIM. I always get:
{ ok: false, error: 'You must pass an ISO 3166-1 Alpha-2 country code to import SIM cards' }
In the file Particle.js when importing SIMs to a product. The code reads:
var data = product ? { sims: iccids, countryCode: countryCode } : { countryCode: countryCode, promoCode: promoCode, action: 'activate' };
However, looking at the cloud API docs, the country should be in country
, not countryCode
.
Changing the line of code to:
var data = product ? { sims: iccids, country: countryCode } : { countryCode: countryCode, promoCode: promoCode, action: 'activate' };
results in successful completion of the call.
The same problem probably exists for non-products as well, but I didn't test that.
GitHub reports a vulnerability in particle-api-js because the Coveralls node modules we to measure test coverage includes a vulnerable dependency. This module is not used in the runtime build so it does not affect customers.
Update the coveralls dependency when they release a new version.
nickmerwin/node-coveralls#188
The way that babel-polyfill is being used pollutes the runtime environment with feature polyfills that may not be wanted or needed by app developers. For instance, polyfilling Promises when Node 4 and 5 have them natively.
This article is a good explanation on the difference between babel-polyfill
and babel-runtime
.
The recommended solution is to depend on babel-runtime
and use the transform-runtime Babel plugin.
Using the particle-api-js library in my website I came across a particularly hard to debug issue. When I was trying to send data, I was passing it to the callFunction
function as an integer but the error I was receiving was saying their was no function found for the name I had used -- very confusing. It wasn't until I used to toString()
method on the integers that the function calls were completing successfully.
I'm just wondering if there's a way to maybe specify that more directly in the docs or maybe provide a more helpful error message?
Thanks!
Are you guys considering adding timeouts to the requests made in the library? My understanding is that there is no timeouts in superagent
, and therefore some requests might never end, which is something that I am seeing happening in mobile env with not a great connectivity.
A possibility would be to extend the Defaults
with a timeout, that would be applied to the request in the _request()
, and that I could override when creating the Particle object in my app:
particle = new Particle({
baseUrl: 'https://api.particle.io',
clientSecret: 'particle-api',
clientId: 'particle-api',
tokenDuration: 7776000, // 90 days
timeout: 5000
});
I've tried to use particle.function
const fnPr = particle.callFunction({ deviceId, name: 'syncDis', argument: count, auth: token });
And it keeps returning 404, function not found. I know this is wrong because I can use this exact same function with the Console, Postman, and have resorted to an Axios request to the API. I think something in the wrapper must be messed up.
I'm in a bit of a rush (making a Christmas gift for my mom) so I'm just using the API and it works but it'd be nice to get this fixed.
Functioning work around
const callParticleFunction = ({deviceId, name, argument, auth}) => {
var axios = require('axios');
var qs = require('qs');
var data = qs.stringify({
'arg': ''+argument
});
var config = {
method: 'post',
url: `https://api.particle.io/v1/devices/${deviceId}/${name}`,
headers: {
'Authorization': `Bearer ${auth}`,
'Content-Type': 'application/x-www-form-urlencoded'
},
data : data
};
return axios(config)
}
I am getting an error while attempting to flash a cpp file to my device. The error received is:
stream.js:74
throw er; // Unhandled stream error in pipe.
^
TypeError: Invalid non-string/buffer chunk
at validChunk (_stream_writable.js:186:14)
at Transform.Writable.write (_stream_writable.js:213:12)
at FormData.ondata (stream.js:31:26)
at emitOne (events.js:90:13)
at FormData.emit (events.js:182:7)
at FormData.CombinedStream.write (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:118:8)
at FormData.CombinedStream._pipeNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:106:8)
at FormData.CombinedStream._getNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:79:10)
at FormData.CombinedStream._pipeNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:107:8)
at FormData.CombinedStream._getNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:79:10)
at FormData.CombinedStream._pipeNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:107:8)
at FormData.<anonymous> (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:91:10)
at FormData.<anonymous> (/Users/ethanmcgee/git/clemson/das-provider/node_modules/superagent/node_modules/form-data/lib/form_data.js:201:5)
at FormData.CombinedStream._getNext (/Users/ethanmcgee/git/clemson/das-provider/node_modules/combined-stream/lib/combined_stream.js:84:3)
at emitNone (events.js:85:20)
at DelayedStream.emit (events.js:179:7)
The code which generates the error is:
var fullCode = "<cpp code here>";
fs.writeFile("./" + deviceId + ".cpp", fullCode, function(err) {
var ccPr = particle.compileCode({files: {"temp.cpp": "./" + deviceId + ".cpp"}, platformId: 6, auth: authToken});
ccPr.then(function(data) {
var flashPr = particle.flashDevice({
deviceId: deviceId,
files: {"temp.cpp": "./" + deviceId + ".cpp"},
auth: authToken
});
flashPr.then(function (data) {
//magic goes here
}, function (err) {
//something bad happened with flash
});
}, function(err) {
//something bad happened with compile
});
});
I am using the latest version of the API, 5.2.3.
The downloadFirmwareBinary
method doesn't support piping the data and doesn't have another documented way to save the downloaded file.
Raised in the community:
https://community.particle.io/t/working-example-of-downloadfirmwarebinary-method-in-particle-js-api/25549
Calling Particle.function()
fails, see here
Hi there. We got 429 errors (rate limit reached) and tried to print err.body.error
but that was undefined. We then just printed the entire err
object and found out that err.body
is a stringified object. That was why the fields inside err.body
cannot be accessed directly. Shouldn't it be converted to an object like other errors?
As far as I can tell version 7.1.0 has not been published to the npm registry yet, as 7.0.1 is still listed as the latest version there. Would it please be possible to publish the updated version?
inherits.js:21 Uncaught TypeError: Super expression must either be null or a function, not undefined
The compileCode method currently doesn't compile projects with a folder hierarchy correctly (#include etc)
The root cause is form-data runs path.basename(filename) which strips the folder from the path.
I see that particle-cli uses a fork of form-data that bypasses this. However particle-api-js doesn't use form-data directly it uses superagent which depends on form-data.
What would be the solution for this? Create a fork of superagent that uses the fork of form-data? Or is there something else planned?
I was hoping that fixing this in particle-api-js would be the first step to fixing particle-dev's build behavior (by migrating from the older SparkJS to particle-api-js)
Summary of which build methods support subfolders:
Web IDE: Yes
particle-cli: Yes
particle-dev: No (uses old SparkJS api)
particle-api-js: No
Hi,
Just tried to test the library, i installed it via npm. With the latest version(6.0.0) I got HTTP 400 for login, and it says:
HTTP error 400 from https://api.particle.io/oauth/token - Method must be POST with application/x-www-form-urlencoded encoding
After rolling back to 5.3.1 everything worked fine.
I was not able to install the tests for 6.0.0 version as well.
we should support this in addition to tokens, since the console only supplies client_id / client_secret for product creators.
Hey,
Is there any reason why responseTemplate
and responseTopic
are not arguments on the webhook creation call? https://github.com/spark/particle-api-js/blob/master/src/Particle.js#L331
Happy to open up a pull request to add them there - but I wanted to follow up with you guys on this before doing so.
Thanks.
Closed: Already documented in #42
This issue only applies to 6.0.0 and may extend to all methods that receive arguments but I've only tested callFunction. I don't know if its worth it to go back and fix, but I figured I'd bring it up to hopefully save someone the frustration if they have 6.0.0 installed.
//returns 0 in 6.0.0, returns 4 in all other versions
var Particle = require('particle-api-js');
var particle = new Particle();
var devicesPr = particle.callFunction({
deviceId: MY_DEVICE,
name: 'len',
argument: 'four',
auth: MY_TOKEN
});
devicesPr.then(
function(devices){
console.log('Devices: ', devices);
},
function(err) {
console.log('List call failed: ', err);
}
);
I have successfully used node.js to execute the following code to load a tinker.bin file in versions 5.3.1, 6.0.0, 6.01 and 6.0.2, however it fails in version 6.0.3. Looks like this commit which changed dir handling in Agent.js may be the source of the problem: Support nested directories when compiling sources
/*jslint node: true */
"use strict";
var auth = require('./auth.js');
var Particle = require('particle-api-js');
var particle = new Particle();
particle.login({
username: auth.username,
password: auth.password
}).then(
function(data) {
console.log('Login success');
var flashPr = particle.flashDevice({
deviceId: auth.device,
files: {
'tinker.bin': './tinker.bin'
},
auth: auth.token
});
flashPr.then(
function(data) {
console.log('Device flash result:', JSON.stringify(data));
process.exit();
},
function(err) {
console.log('An error occurred while flashing the device:', err);
});
},
function(err) {
console.log('Login failed: ', err);
}
);
When I execute it the following is logged:
Login success
Device flash result: {"body":{"id":"<device id>","status":"Update started"},"statusCode":200}
But shortly after in Particle Console I see a 'spark/flash/status' event with data 'failed'.
To run this you will need an auth.js file with your credentials, like:
module.exports = {
username: '<your email>',
password: '<password>',
device: '<deviceId>',
token: '<auth token>'
};
This issue was originally raised in the Particle Community forum: flashDevice() fails in Particle JS API [SOLVED]
Hello,
When an event is published with the name 'error' it triggers the error hook on the event stream object. I think this is an issue since only event names starting with 'spark-' are declared as reserved on the api docs. Possible fix is changing this line:
https://github.com/spark/particle-api-js/blob/master/src/EventStream.js#L150
to
if (this.eventName !== 'event' && this.eventName !== 'error') {
Thanks,
Arian
Received this as a feature request from a customer, I think right now this library is fairly user-centric, and doesn't provide features for Orgs. Happy to answer any questions offline if I can, thank you!
Hi there,
Just trying to covert my spark stuff over to this new library and ran into 404 errors because the default baseUrl has a trailing slash on it.
Managed to get logged in fine when I passed in the url without the trailing slash.
Cheers,
Grant
in the documentation:
options.file Object Path or Buffer of the new firmware file
Either a path or Buffer of the file contents in Node, or a File or Blob in the browser.
test parameter appears to only set file to a buffer, and not a path
file: new Buffer('ELF...'),
discovered because upload with path appears to not work as expected during testing / development.
was expecting the promise to return:
[ fw_1, fw_2, ... etc]
instead promise returns:
{ statusCode: 200, body: [fw_1, fw_2, ... etc] }
whichever we use, we should document it
observed behavior: added a device of non-matching platform to a product, no error, resolves normally.
expected behavior: addDeviceToProduct rejects with an error, since the API request did not succeed
Hi. I want to detect the moment when the Photon Board is deconnected. Maybe there are a function to do this. Somebody can help me, please?
it appears both of these calls are probably broken, they use this.prefix (most other calls use this in request builder which checks to see if it's defined). Bringing the check from build request to those calls to fix the download functions.
Hey,
I have installed:
pi@pi3:~/.node-red/node_modules/particle-api-js $ npm -v
10.3.0
And a NodeRed installation.
I try to install the https://flows.nodered.org/node/node-red-contrib-nspanel-lui package.
the I get the error:
2024-01-21T00:26:44.201Z npm install --no-audit --no-update-notifier --no-fund --save --save-prefix=~ --production --engine-strict [email protected]
2024-01-21T00:26:45.803Z [err] npm
2024-01-21T00:26:45.805Z [err] WARN
2024-01-21T00:26:45.805Z [err] config production Use `--omit=dev` instead.
2024-01-21T00:26:59.811Z [err] npm ERR! code EBADENGINE
2024-01-21T00:26:59.824Z [err] npm ERR! engine Unsupported engine
2024-01-21T00:26:59.824Z [err] npm ERR!
2024-01-21T00:26:59.826Z [err] engine Not compatible with your version of node/npm: [email protected]
2024-01-21T00:26:59.826Z [err] npm ERR! notsup Not compatible with your version of node/npm: [email protected]
2024-01-21T00:26:59.826Z [err] npm ERR!
2024-01-21T00:26:59.827Z [err] notsup Required: {"node":">=12.x","npm":"8.x"}
2024-01-21T00:26:59.827Z [err] npm ERR! notsup Actual: {"npm":"10.3.0","node":"v20.5.1"}
2024-01-21T00:26:59.841Z [err]
2024-01-21T00:26:59.842Z [err] npm
2024-01-21T00:26:59.842Z [err] ERR! A complete log of this run can be found in: /home/pi/.npm/_logs/2024-01-21T00_26_45_582Z-debug-0.log
2024-01-21T00:26:59.881Z rc=1
My npm and my node version are higher then the required.
But your npm version is hard set to 8. not ">=8.0" like node version.
And directy via cli:
pi@pi3:~/.node-red/node_modules $ npm update particle-api-js
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '[email protected]',
npm WARN EBADENGINE required: { node: '>=12.x', npm: '8.x' },
npm WARN EBADENGINE current: { node: 'v20.5.1', npm: '10.3.0' }
npm WARN EBADENGINE }
Is it possible to change the version of npm?
'use strict'
const Particle = require('particle-api-js')
const particle = new Particle();
class DeviceController {
* index(request, response){
const token = request.cookie('token')
const devicesPr = yield particle.listDevices({ auth: token })
devicesPr.then(
function(devices){
console.log('Devices: ', devices);
},
function(err) {
console.log('List devices call failed: ', err);
}
);
yield response.sendView('devices', {devices: devicesPr})
console.log(devicesPr)
}
}
module.exports = DeviceController
This is returning that devicesPr is not a function
When calling the loginAsClientOwner function it only returns tokens with the default token duration of 7776000 seconds. It should have a parameter for tokenDuration like login has that will either use the given value or the tokenDuration member value.
The EventStream
returned from Particle#getEventStream
doesn't reconnect if the connection is dropped because of network issues. Instead, the stream remains open but doesn't receive any events.
Reproduction
You can easily reproduce this issue with the Particle CLI (see particle-iot/particle-cli#256) . Run particle subscribe
in a terminal, disable WiFi/remove your Ethernet cable, wait for ~2 minutes (depending on the operating system) until the underlying socket is closed on the server, reconnect to the Internet, and run particle publish e --private
in a second terminal. No event will be logged in the first terminal.
Details
I think there are currently two problems that prevent automatic reconnects from working:
req.on('response', โฆ)
callback:res.socket.setTimeout(10000);
res.socket.on('timeout', () => {
// This will trigger the 'end' event on the response:
res.socket.destroy();
});
'end'
event is triggered. If the first attempt to reconnect after reconnectInterval
milliseconds fails (likely to be the case if the disconnect is caused by network issues), an error will be emitted and the stream won't try to reconnect again.According to the Node.js LTS schedule Node v4's maintenance period ended March 31st, 2018. We should be safe to remove the checks from the build process.
I have been attempting to get the list of events for my devices, using the below code.
particle.login({ username : "USERNAME", password : "PASSWORD" }).then(function(data) {
particle.getEventStream({ deviceId: 'mine', auth: data.body.access_token }).then(function(data) {
console.log("Event: " + data);
});
});
I can see events from my devices by viewing the following web address, so events do appear to be firing correctly.
https://api.particle.io/v1/devices/events?access_token=TOKEN
However using the getEventStream
I have not seen any events being logged, I've tried this a few different ways but in no case have I been able to receive events.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.