{"id":24579488,"url":"https://github.com/andrewstuart/sparknode","last_synced_at":"2025-04-23T22:05:57.707Z","repository":{"id":13351748,"uuid":"16039095","full_name":"andrewstuart/sparknode","owner":"andrewstuart","description":"Allows node.js to interface with a sparkcore.","archived":false,"fork":false,"pushed_at":"2014-06-30T20:19:57.000Z","size":616,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-23T22:05:50.560Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrewstuart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-19T03:14:15.000Z","updated_at":"2023-11-09T01:15:40.000Z","dependencies_parsed_at":"2022-09-26T19:10:54.247Z","dependency_job_id":null,"html_url":"https://github.com/andrewstuart/sparknode","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewstuart%2Fsparknode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewstuart%2Fsparknode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewstuart%2Fsparknode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewstuart%2Fsparknode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewstuart","download_url":"https://codeload.github.com/andrewstuart/sparknode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250522300,"owners_count":21444511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-24T00:45:04.683Z","updated_at":"2025-04-23T22:05:56.952Z","avatar_url":"https://github.com/andrewstuart.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"#About\n\nSparknode is built to make it easier for your server-side (or node-webkit) code to communicate with the spark cloud, so that you can do more with your core with less overhead.\n\nIt's designed to be hopefully as easy to use as possible with a low barrier to entry.  All you need to do to get started is provide your access token and sparknode, along with the [Spark Cloud](http://docs.spark.io/#/api), will set everything up for you.\n\nYour cores become part of a collection, accessible by name, and will have their Cloud functions and variables accessible as methods on the 'Core' objects. Hooking into Spark Cloud events is as easy as attaching a listener via the 'on' method for your core. Your callback will be called each time that event, or every event if you pass 'event' as the event name, is fired.\n\n###[Example](#example-1)\n\n#Constructors\n1. [Core](#core)\n2. [Collection](#collection)\n\n##Core\nCreate a new instance of a spark core. First parameter is accessToken, second parameter is deviceId.\n\nAn object can also be used as the first parameter, as follows:\n\n```javascript\nvar spark = require('sparknode');\n\nvar core = new spark.Core({\n  accessToken: \u003cYour Auth_Token\u003e,\n  id: \u003cYour device id\u003e\n});\n```\n\n###Cloud Events\nEach event is accessible to your core (or collection) through the builtin events.  You can simply call `core.on(eventName, function handler(eventData) {/*do something;*/});` to register your handler on the event.  If 'event' is passed to the `on` function as the name, then the handler will be called for every event with an `{event: 'eventName', data: {/*eventData*/}}` object.\n\n```javascript\ncore.on('coffeeBrewed', function(info) {\n  console.log(info);\n  console.log(info.data);\n  //send an email with the number of cups remaining.\n});\n\ncollection.on('event', function(eventInfo) {\n  database.save(eventInfo);\n  //All events for all cores get logged to the database.\n  //API for public events coming shortly.\n});\n```\n\n###Cloud Functions\nEach function accepts a string as the parameter, and a callback to be called upon return.\n\nThe signature of the callback should be `function(err, data)`.\n\n```javascript\ncore.brew('coffee', function(err, data) {\n  console.log(data);\n});\n```\n\n###Cloud Variables\nEach variable (exposed as functions) accepts a callback as its first parameter, with the same signature as above (err, data).\n\n```javascript\ncore.variable1(function(err, data) {\n  console.log(data);\n});\n```\n\nVariables also have a property, autoupdate, that can be set with a timeout in milliseconds between each call, or true to use the default 5 second interval or false to cancel autoupdates. Setting this variable will also start the update cycle.\n\nWhen being used with autoupdate, the variable (not the core) will fire an `'update'` event each time a response is received from the server.\n\n```javascript\n//Start autoupdate\ncore.variable1.autoupdate = 2000;\n\n//Do something on update\ncore.variable1.on('update', function(value) {\n  console.log(value);\n  console.log(core.variable1.value);\n});\n\n//Stop update with any falsy value.\ncore.variable1.autoupdate = false;\n\n```\n\nThe last known value can be retreived as a property (value) of the function.\n\n```javascript\nconsole.log(core.variable1.value);\n```\n\n##Collection\nEven better, get all your spark cores at once, complete with everything they can do.\n\nOnce loaded, the collection instance contains all your spark cores by name.\n\n```javascript\ncollection.core1.doFunction('foo', function(err, data) {\n  //Do something\n});\n```\n\nThe default behavior is to cache the output of the cloud api for all HATEOS calls in a JSON object at your project root.  If you'd like to override this behavior, you can pass an options object (optional, of course) to the constructor.\n\n```javascript\nvar collection = new Collection(myAuthToken, { skipCache: true })\n```\nor\n```javascript\nvar collection = new Collection(myAuthToken, { cacheFile: 'lib/cacheFile.json' } )\n```\n\n##Example\n\nImagine you have some two spark cores, which you've named core1 and core2. Imagine you also like coffee enough to dedicate a sparkcore to brewing coffee. Not hard to imagine, I'd guess.\n\nSo you've set up at least one function, `brew()`,  one variable,  `remainingCoffeeTime`, and one event, `coffeeDone`, on core2. Core1 still has tinker installed, or at least has the digitalWrite function.\n\n```javascript\nvar sp = require('sparknode');\nvar collection = new sp.Collection(myAuthToken);\ncollection.on('connect', function() {\n  //Turn on an led\n  collection.core1.digitalwrite('d7,HIGH');\n\n  //Brew some coffee, then email me.\n  collection.core2.brew('coffee', function(err, timeUntilFinished) {\n    if(err) {\n      throw err;\n    }\n\n    emailMe('' + timeUntilFinished + ' milliseconds until your coffee is ready.');\n  })\n\n  colleciton.core2.on('coffeeDone', function() {\n    emailMe('Your coffee is done. Enjoy!');\n  });\n\n  //Get a variable\n  collection.core2.remainingCoffeeTime(function(err, value) {\n    //Do something with value\n  })\n```\n\nAnd an example of a single core.\n\n```javascript\nvar randomCore = new sp.Core(myAuthToken, deviceId);\n\nrandomCore.on('connect', function() {\n  randomCore.turnOnLights();\n});\n```\n\n#CLI\n\nIf installed globally via `npm install -g sparknode`, sparknode will give you a command line interface mostly useful for debugging, but I suppose it could be used for other scripting applications as well.\n\nThe most important command is probably `sn -h`, as it lets you discover the functionality directly from the command line.\n\nAs for the rest, right now there are three main commands under the main `sn` command: `add`, `fn`, and `var`. Each of these also have help generated with the -h switch.\n\n####add\nSpark add will retreive any cores accessible via the given token. These are saved at your home directory under .sparkrc.\n\nSyntax is `sn add \u003ctoken\u003e`.\n\n####var\nRetreive a variable from the spark cloud. \n\nSyntax is `sn var coreName [varName]`. If no `varName` is included, the list of registered variables will be printed.\n\nOptions include:\n\n-n Number of times to check the variable (--number)\n\n-i Interval, in milliseconds, between checks (--interval)\n\n-c Check continously at interval or 1 second. (will override -n) (--continuous)\n\n####fn\nExecute a remote function and print the return value. If no `functionName` is included, the list of registered functions will be printed.\n\nSyntax is `sn fn \u003ccoreName\u003e \u003cfunctionName\u003e \u003cargument\u003e`.\n\n####events\n\nSyntax: `sn events [coreName]`\n\nPrint a list of events coming from the spark cloud. If a coreName is supplied, then the events are limited to that core's events. Press ctrl-c to interrupt, as usual.\n\nOptions: \n\n-p Show a list of public events.\n-n Only search for events with a specific name.\n\n```bash\nsn events -p\n\n{ data: \n  { data: 'course',\n    ttl: '60',\n    published_at: '2014-03-13T10:42:23.157Z',\n    coreid: '48ff69065067555019392287'\n  },\n  event: 'motion-detected2' \n}\n...\n\n#I have a hard time believing mr. 48ff69065067555019392287 is seeing motion every single second. amirite?\n```\n\n####ls\nGet either a list of cores and their functions or a single core.\n\nYou can optionally pull an update first with the `-u` option in case you want to list new functionality.\n\nSyntax: `sn ls [coreName]`\n\nOutput Example:\n\n```bash\nsn ls\nCore: core1 (1234567890abcdef12345678)\n\nFunctions: \nbrew\ndigitalread\ndigitalwrite\nanalogread\n\nVariables: \ndelay\n\nConnected: true\n\n-----------\n\nCore: core2 (1234567890abcdef12345679)\n\nFunctions: \ngetdata\ndigitalread\ndigitalwrite\nanalogread\n\nVariables: \ndelay\n\nConnected: true\n\n-----------\n\n```\n\n##CLI Examples\n\n  ```bash\n#Go get all the cores.\n  sn add 1234567890abcdef1234567890abcdef\n\n#The following cores were found and saved: \n#core1 1234425432363457d\n#core2 1212532454325acef\n\n  sn fn core1\n\n#Functions available for core 'core1':\n#  brew\n#  digitalread\n#  digitalwrite\n#  analogread\n\n  sn fn core1 brew coffee;\n#1\n\n  sn fn core2\n#  digitalwrite\n\n  sn fn core2 digitalwrite \"A1,HIGH\";\n\n  sn var core1\n\n#Variables available for core 'core1':\n#  brewTime\n#  variable1\n\n  sn var core1 brewTime;\n\n#  120000\n\n  sn var core2\n\n#Variables available for core 'core2':\n#  coffeeStrength\n\n  sn var -i 100 -n 5 core2 coffeeStrength;\n\n#100\n#100\n#98\n#99\n#96\n\n#My current personal favorite:\n  sn var -ci 100 core1 variable1;\n\n#1\n#2\n#3\n#4\n#5\n#...\n  ```\n\n\n##Future\n\n  Future:\n\n  I'd like to write a custom firmware that's CLI flashable and uses TCP directly for faster feedback. You're already using Node, so you have that option. It should be possible to write very powerful client-server code using something like this. I'd also like to keep it modular so it's useful on its own.\n\n  I'm also thinking about writing a custom firmware that lets you add many more than 4 functions, directly from the CLI or even programmatically, using string parsing on the client side. I don't know about anyone else, but I don't need 64 characters of input very often, so I figured they'd be more useful this way. Check out the issues tracker to add feature requests and see some of the plans I have.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewstuart%2Fsparknode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewstuart%2Fsparknode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewstuart%2Fsparknode/lists"}