Getting started with Node.js, Code And the NEEO-SDK (v0.6)

To get started and write your own integrations you might think where do i start?! or looking up and have that "Hmmm that's quite a mountain to climb" feeling. Just a few weeks ago i had the same feeling, I never wrote a word in javascript and just looking at it gave me headaches. hopefully i can take that away and have you started building your own killer integration.

  • Initial post.
  • Changed dutch sentences in code snippets to english.
  • Changed some wording in the first SDK Installment (about the warnings)
  • Added "start a new project"
  • Added namings chapter with device type and button names.
  • Changed some typo's
  • Updated based on the SDK changes.
  • Added an image to represent buttons on a TV device.
  • Added NodeJs installation on Raspberry Pi, thanks to Gilles van den Hoven

 

Some basic knowledge about programming would definitely help you but do not hold back if you have never done any real programming. If a dyslexic like me can do it you certainly can to. The SDK used Javascript or more precise Node.JS. also called Node or Nodejs.

This youtube video will learn you what Node is about and provides some examples to inform you about what it blocking code and what is non blocking code. Don't expect to be able to recreate his examples though, just soak up the idear. (you might want to view it later on again, it might make more sense later on. Unfortunately i can't find another video that helped me out with some of the "if this than else loop basics". When i start learning a language that's new to me i use a text document where i place some code snippets. You might want to do the same. view some youtube videos about javascript and or node and write some of these code snippets in. I'll share mine, they might help you.

So to be able to actually run your code and the SDK you will need to install node. I'm coding and running things on my windows computer but any computer including a raspberry will do. Go to https://nodejs.org/en/download/ download and install node. after installation start your command line. On windows: (start, run, type in CMD and click ok)
  

in the command line type in node -v to see if node is successfully installed. you will see Node's installed version number like  v#.#.# when you have installed it.

 

This section of the tutorial is related to the installation of Node.js on a Raspberry Pi. It requires a Pi system based on the newer ARMv7 or ARMv8 chip such as the Pi 2 or Pi 3.

NodeSource provides Node.js binaries for these newer ARMv7+ architectures, but not for Raspberry Pi systems based on the older ARMv6 architecture such as the Raspberry Pi Model B/B+ or the Raspberry Pi Zero.

Read the writing carefully on your Raspberry Pi circuit board to confirm is says something like “Raspberry Pi 3 Model B” or “Raspberry Pi 2 Model B”. If in doubt, run the following command in the terminal:

$ uname -m

If the result returned starts with “armv6”, you are running a Raspberry Pi based on the older ARMv6 chipset and the next Node.js installation step will not work; otherwise, you are ready for the next step.

Let’s proceed with an installation of the long term support version of Node at the moment which is Node v8.9.2.

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -

The previous command updates our Debian apt package repository to include the NodeSource packages.

Note: It’s generally a good idea from a security perspective to know what commands you are invoking on your system, especially since the command above invokes the script as the root user. If you want the technical details behind this script, you can launch the URL ( https://deb.nodesource.com/setup_8.x ) in your browser and review the code. The script carries out some ceremony to determine the Linux distribution you are running and instructs the Debian apt package system to add the NodeSource package repository as a trusted source for obtaining Debian packages. This enables us to install Node.js now and upgrade to more recent versions of Node.js when they become available.

Now that we have added the NodeSource package repository, we can move on and install Node.js!

$ sudo apt install nodejs

We can then test and see what version of Node we are running and launch the Node REPL as we discussed in the previous article as a quick test to confirm the installation was successful.

$ node -v
v8.9.2

To be able to write some actual code you could use any notepad like application, but i strongly advise you to use a IDE. an IDE is an application that is aware of what you are coding and you can directly start your code. and more importantly pause your code at a specific location so you will be able to look inside variables. As i have written every node code in Microsoft visual Code. i'll advice you to do the same. Download Visual Studio Code

First download the examples here. click on the "Clone or download"  button to download the examples. Extract the files to /Documents/Code/NEEO/examples/ or any other place but i'll use this as a reference. when you have your examples extracted open your command line (as seen in Get node JS). and go to your code/neeo directory.
 

Now lets install the NEEO-SDK !!! :-)
Type in "npm install neeo-sdk" without the quotes and all in lowercase.
 Don't mind the warnings for now (read the topic "start a new project" to learn how you should do this. without the warnings.)

Start your file explorer and browse to your examples directory, up to the following directory "neeo-sdk-examples-master\device\simpleDevice" right mouse click somewhere on empty space and select the option "Open with Code"
 
 

Now the Code application will start. You want to start with the index.js file by clicking "index.js" in the filebrowser on the left side of Code.

The index.js file is where you define your device and its capabilities.

Line 3, references to the NEEO-SDK nodejs library.
Line 4, references to the other file named controller.js.

From line 15, the device and its properties is defined.
From line 21, you see that two buttons are defined.

From line 26, the the SDK will discover a neeo brain and start its server.
 

Lets just start this code. by pressing F5 in Code.
notice that a debug window will popup with feedback.

 

now open your NEEO app and add a new device.
Use this to search for your example driver

  1. Simple
  2. buttons
  3. NEEO
  4. foo

Notice that these are all defined in index.js and you can find your driver with this.
Now select the driver and actually add it.

 

Accessory devices do not have their own recipes like you are used with other type of devices. this is not a limitation of the sdk but rather the accessory device type.

Start one of your recipies for instance TV. then go to the menu and tap edit shortcuts. now tap Add shortcut, select your device driver (when you haven't provided a name its defaultly named Accessory. then select both Button A and Button B. Go back to the TV recipe, slide to the shortcuts and use the buttons while watching the debug output of code.

Note you will see a text appearing when you press one of the buttons. This is what the driver currently does. it displays text on your computer.

Stop your code and open the controller.js file. the onButtonPressed function is called when you press a button.

Now pres just in front of line number 8, a red dot should show just in front of line 8.
Select the index.js file and start your code again by pressing F5.

Now see what happens when you press either Button A or Button B on the remote or APP.

The code will stop at line 8. Placing the red dot will pause the code every time it hits that part of the code. You are now able to see what values the variables deviceid and name contain by hovering your mouse pointer above these variables. Note the content of deviceid and lets place some code to Button A and Button B.

Change the code in controller.js to this:

module.exports.onButtonPressed = function onButtonPressed(deviceid, name) {
  console.log('[CONTROLLER]', name, 'button was pressed!');

  if (deviceid === "button-a") {
    console.log("Add some code here that you want to execute when button A is pressed.");
  }

  if (deviceid === "button-b") {
    console.log("Add some code here that you want to execute when button B is pressed.");
  }

};

Run the code again and use button A and B.

 

Strings

var first_name = 'Niels';
var middle_name = "de";
var last_name = "Klerk";
var full_name = first_name + ' ' + middle_name + ' ' + last_name; // Variables with '' or ""

 

Numbers

var age = 36;
var cost = 2.30;

 

Boolean

var true_or_false = true;
var true_or_false = false;

 

Null

var empty_var = null;

 

Array

var myarry1 = [1,2,3,4,5,6]; //0,1,2,3,4,5
var myarry2 = ['rood','zwart','geel']; //0,1,2
console.log(myarry2[1]); // zwart

 

Objects

var myobject = {"name" : "Niels de Klerk", "age" : 36, "awesome": true};

var myobject = {name: "Niels de Klerk", age: 36, awesome: true};

var myobject = {};
myobject.name = 'Niels de Klerk';
myobject.age = 36;
myobject.awsome = true;

 

var number1 = 30;
var number2 = 80;
var number3 = 100;
console.log(number3 - number2);
console.log((number1 + number2) - number3);

number3++;
console.log("nummer " + (number3 + number2));

// -=min +=plus *=keer /=delen %=modulus

var number4 = number2++;
var number4 = ++number2
console.log("nummer " + number4);

var x = 10.345;
var x = x % 4 //% = mudulus
console.log(x);

x+=5; //x = x + 5;
var myobj = {
  name: "My object",
  value: 7,
  getname: function(){ return this.name; }
}

console.log (myobj.getname());

 

var user = new Object();
user.first = "Niels";
user.last = "de Klerk";
user.getname = function() { return this.first + ' ' + this.last; };

console.log (user.getname())

 

console.log ("\n\n// Objects");
var x = new Number("6");
console.log(x);

var s = myobj.name;
myobj.name = "New name";
console.log (myobj.name);
console.log (myobj.getname());

var name = myobj.getname();
myobj.getname = function() {return this.name;}
console.log (myobj.name);
console.log (myobj.getname());

 

function my_function(){
  console.log("Hello World!");
}

my_function();

 

function cl(debug_log_text) {
  console.log(debug_log_text)
}

cl("print this text");

 

cl(format("I'm 1337", " So "));
function cl(debug_log_text) {
  console.log(debug_log_text)
}

function format(text, moretext){
  text = "-~= " + text + moretext + " =~-";
  return text;
}

 

x="10";
console.log("\n\n");
if (x==10){
  console.log("x has vallue 10");
} else {
  console.log("x is not 10");
}

if (x===10){ //type comparison
  console.log("x is an integer with value 10");
} else {
  console.log("x is no integer or not value 10");
}

if (x==9) {
  console.log("x is 9")
} else if (x==10){
  console.log("x is 10")
} else {
  console.log("x is not 9 and not 10")
}

if (x!=8){ console.log("x is not 8 not even a string 8"); }

if (x!==8){ console.log("x is not 8 or is no integer"); } //type comparison

if (x>=8){ console.log("x is 8 or greater"); }

if (x<11){ console.log("x is smaller then 11"); }

if (x>8 && x<11){ console.log("x is greater than 8 and smaller then 11"); }

if (x==10 || x==11){ console.log("x is 10 or 11"); }

if (!(x==11)){ console.log("x is not 11"); }


//////////////////////

// switch (case)

//////////////////////

x = 10;

switch (x) {
  case 9:
    console.log ("x = 9");
    break; // zonder break zou de vergelijking door alle cases gaan vergelijken.
  case 10:
    console.log ("x = 10");
    break;
  case 11:
    console.log ("x = 11");
    break;
  default:
    console.log("x is geen 9, 10 of 11");
 }

 

//////////////////////
// while loop
//////////////////////

console.log ("\n// while loop");
x = 10;
while (x>0){
  console.log("Nummer: " + x);
  x--;
}

//////////////////////
// Do while loop
//////////////////////

console.log ("\n// Do while loop");
  var names = ["Siska", 'Niels', 'Pelle', 'Spiderman', 'Batman'];
  var i=0;
do {
  console.log (names[i++]);
} while (names[i] != "Batman");

//////////////////////
// for loop
//////////////////////

console.log ("\n// for loop");
var names = ["Siska", 'Niels', 'Pelle', 'Spiderman', 'Batman'];
var i=0;
for (var i=0; i<=10; i++) {
  console.log (names[i]);
}

//////////////////////
// for loop array
//////////////////////

console.log ("\n// for loop array");
var names = ["Siska", 'Niels', 'Pelle', 'Spiderman', 'Batman'];
for (var i in names) {
  console.log (names[i]);
  if (names[i] == "Pelle") {break;}
}

 

Lets start a project from scratch. this doesn't mean you can't still copy or use the example code to your new project so please don't hold back.

First open your command line and add a new directory for your project. as a reference i'll name it myProject. head into the directory and init your project by using "npm init".

This will ask you some basic questions to get your project started.

  • The project name must be fully lowercase as shown in the code above.
  • type in a version number of the code. i have chosen 0.0.1 in this example.
  • provide your project with a description.
  • provide the entry point. this is the name of the file that starts your project. default is index.js so i've kept it.
  • test command: This is used to start automated testing of your code. my example makes no sense, just leave it blank for now. but remember to give it some attention later on.
  • git repository, well i had to start with either the init or the git. leave it blank for now or if you know how to use git then add it. we can add it later on.
  • Provide some keywords that match your project.
  • Provide the author name, fill in your own name.... not mine....
  • licensr: provide a license i.e. ISC or MIT
  • Is this ok? well review your answers if your happy with it then enter yes.

Now you have created a package.json file with the minimal required parameters set. this file is just a json formated text file so feel free to edit it.

Now lets create an account on github so you can publish your project.

When you have your account, create a new repository for your project. in this case i named it myProject.

 

When you have created the repository install git on your computer. go to this website and chose the version for your OS follow the installation instructions.

When you have git installed, enter the command line again and go back to your myProject directory.

Now enter the following commands step by step to connect and push your project to git. dont forget to change the git URL to your git URL.

echo "# myProject" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/<your username>/myProject.git
git push -u origin master

Now your empty project is pushed to your git repository.

Packages are small or large portions of code that are shared so everyone can reuse the code for his project. the neeo-sdk is a package so we use this as an example. We want to use the neeo-sdk in myProject so you need to get it and link it to your project as a dependency.

open your command line tool and go inside the project directory. now install the sdk like this:

npm install neeo-sdk -save

the -save part makes sure the dependency for neeo-sdk is added to your package.json. now you don't deed to include the actual neeo-sdk in your code. when someone uses your code they only have to enter "npm install" and the packages that you have used will also be installed without providing them as code to your project.

If you want to automate a specific product with your code, have a search on the internet for a node package, chances are that a package already exists. Install these packages just like the neeo-sdk with the -save option included to have the dependency added to your package.json.

with the npm init command the entrypoint of your code is made index.js. open visual code inside the myProject folder. add index.js as a file and start coding.

after you made some changes to your code you will see that your code is different from the git code:

 

To commit your code you can enter a message, (this will be visible to git) like fixed bug x. or added feature y. you will commit it by using Ctrl + Enter.

Now you need to push the code changes to git.:

 

Now check your git to see the changes you have made.

 

Naming is very important with NEEO. Based on the device type and button names the physical buttons will be mapped and control widgets will be made available.

The following device types are supported by the SDK, They are all in UPPERCASE.

  • ACCESSOIRE

  • AVRECEIVER

  • DVB

  • DVD

  • GAMECONSOLE

  • LIGHT

  • MEDIAPLAYER

  • PROJECTOR

  • TV

  • VOD

The following devices can be hacked in the SDK to add a device with this type to NEEO. Using these device types will result in drivers that have parts that won't work as expected or even cause serious issues. Be aware that these issues will NOT be supported.
 

  • AUDIO
    I haven't tested it but expect some issue could occur.

  • SOUNDBAR
    I haven't tested it but expect some issue could occur.

  • TUNER
    I haven't tested it but expect some issue could occur.

  • THERMOSTAT
    Expect major issues. Don't use this one unless you really know what you're doing.

  • CLIMA
    Doesn't do much, can be used for shortcuts. but expect issues.

  • SONOS
    Expect major issues. Don't use this one unless you really know what you're doing.

 

There are reserved button names that will be bound to specific widgets or hard buttons.
The following image displays the buttons that will automatically mapped to the hard buttons when the devicetype is TV.
 
(Might be the same or different for other device types.)

 

Mediacontrol button names

  • PLAY
  • PAUSE

  • STOP

  • SKIP BACKWARD

  • SKIP FORWARD

  • FORWARD

  • PREVIOUS

  • NEXT

  • REVERSE

  • PLAY PAUSE TOGGLE

  • INFO

 

Color button names

  • FUNCTION BLUE
  • FUNCTION GREEN
  • FUNCTION ORANGE
  • FUNCTION RED
  • FUNCTION YELLOW

 

Digit button names

  • DIGIT 0

  • DIGIT 1

  • DIGIT 2

  • DIGIT 3

  • DIGIT 4

  • DIGIT 5

  • DIGIT 6

  • DIGIT 7

  • DIGIT 8

  • DIGIT 9

  • DIGIT SEPARATOR

  • DIGIT ENTER

 

Direction button names

  • CURSOR DOWN

  • CURSOR LEFT

  • CURSOR RIGHT

  • CURSOR UP

  • CURSOR ENTER

 

Additional buttons

  • ENTER

  • EXIT

  • HOME

  • GUIDE

 

Menu buttons

  • MENU
  • BACK

 

Power button names

  • POWER OFF
  • POWER ON

  • POWER TOGGLE

 

Tuner button names

  • CHANNEL UP
  • CHANNEL DOWN

 

Format button names

  • FORMAT 16:9
  • FORMAT 4:3

  • FORMAT AUTO

  • FORMAT SCROLL

 

Volume button names

  • VOLUME UP
  • VOLUME DOWN

  • MUTE TOGGLE

 

Input button names

  • INPUT 1
  • INPUT 2
  • INPUT AM
  • INPUT AUX 1
  • INPUT HDMI 1

 

All button names i could find.
These are not necessarily known as a 'special' button by the remote. these are just those that i could find in my API/configuration

  • #
  • *
  • 3D
  • ALT-F4
  • AUDIO
  • BACK
  • CANCEL
  • CAP LOCK
  • CHANNEL DOWN
  • CHANNEL UP
  • CLEAR
  • CLEAR QUEUE
  • CLR
  • CURSOR DOWN
  • CURSOR ENTER
  • CURSOR LEFT
  • CURSOR RIGHT
  • CURSOR UP
  • DELETE
  • DIGIT 0
  • DIGIT 1
  • DIGIT 10
  • DIGIT 10+
  • DIGIT 11
  • DIGIT 12
  • DIGIT 2
  • DIGIT 3
  • DIGIT 4
  • DIGIT 5
  • DIGIT 6
  • DIGIT 7
  • DIGIT 8
  • DIGIT 9
  • DIGIT ENTER
  • DIGIT SEPARATOR
  • DIMMER
  • DIRECT TUNE
  • DISPLAY
  • DVD ANGLE
  • DVD AUDIO
  • E MANUAL
  • EXIT
  • FORMAT 16:9
  • FORMAT 4:3
  • FORMAT AUTO
  • FORMAT SCROLL
  • FORWARD
  • FUNCTION BLUE
  • FUNCTION GREEN
  • FUNCTION ORANGE
  • FUNCTION RED
  • FUNCTION YELLOW
  • GUIDE
  • HOME
  • INFO
  • INPUT 1
  • INPUT 10
  • INPUT 11
  • INPUT 12
  • INPUT 13
  • INPUT 1394
  • INPUT 14
  • INPUT 15
  • INPUT 16
  • INPUT 17
  • INPUT 18
  • INPUT 19
  • INPUT 2
  • INPUT 20
  • INPUT 21
  • INPUT 22
  • INPUT 23
  • INPUT 3
  • INPUT 4
  • INPUT 5
  • INPUT 6
  • INPUT 7
  • INPUT 8
  • INPUT 9
  • INPUT AM
  • INPUT AUX 1
  • INPUT BD/DVD
  • INPUT BLUETOOTH
  • INPUT CABLE/SATELLITE
  • INPUT COMPONENT 1
  • INPUT COMPONENT 2
  • INPUT COMPOSITE 1
  • INPUT COMPOSITE 2
  • INPUT DVI 1
  • INPUT FM
  • INPUT GAME
  • INPUT HDMI 1
  • INPUT HDMI 2
  • INPUT HDMI 3
  • INPUT HDMI 4
  • INPUT NET
  • INPUT PC
  • INPUT PHONO
  • INPUT S VIDEO 1
  • INPUT SCART 1
  • INPUT SCROLL
  • INPUT STREAM BOX
  • INPUT TUNER 1
  • INPUT TV
  • INPUT TV/CD
  • INPUT USB 1
  • INPUT VGA 1
  • INPUT VGA 2
  • KIOSK
  • LANGUAGE
  • LIVE TV
  • MENU
  • MENU DISC
  • MENU DVD
  • MENU MAIN
  • MENU POP UP
  • MENU SMART HOME
  • MENU TOP
  • MESSENGER
  • MODE
  • MODE GAME 1
  • MODE MOVIE/TV
  • MODE MUSIC
  • MODE STEREO
  • MOUSE
  • MUTE TOGGLE
  • MUTE UNMUTE
  • MY APPS
  • MY DISTRIBUTED AUDIO
  • MY HOME
  • MY LIGHTS
  • MY MUSIC
  • MY PICTURES
  • MY SECURITY
  • MY THERMOSAT
  • MY TV
  • MY VIDEOS
  • NEXT
  • NEXT TRACK
  • OEM1
  • OEM2
  • ONLINE SPOTLIGHT
  • ONLINE SPOTLIGHT PARTNER SPECIFIC APP
  • OPEN/CLOSE
  • OPTIONS
  • OUTPUT RESOLUTION
  • PAUSE
  • PLAY
  • PLAY PAUSE
  • PLAY PAUSE TOGGLE
  • POWER OFF
  • POWER ON
  • POWER TOGGLE
  • POWER_ALL_OFF
  • POWER_OFF
  • POWER_ON
  • PRESET DOWN
  • PRESET UP
  • PREVIOUS
  • PREVIOUS CHANNEL
  • PREVIOUS TRACK
  • PRINT
  • RADIO
  • RANDOM
  • REBOOT
  • RECORD
  • RECORDED TV
  • REPEAT
  • REPEAT TOGGLE
  • REPLAY 10 SEC
  • REVERSE
  • SEARCH
  • SHUFFLE TOGGLE
  • SKIP BACKWARD
  • SKIP FORWARD
  • SLEEP
  • SMART HUB
  • SPEAKER A
  • SPEAKER B
  • STOP
  • SUBTITLE
  • TELETEXT
  • TITLE
  • TONE
  • TONE +
  • TONE -
  • TOOLS
  • TUNING DOWN
  • TUNING UP
  • UN PAIR
  • VOLUME DOWN
  • VOLUME UP
  • WINDOWS
  • WRITE
Reply
168replies Oldest first
  • Oldest first
  • Newest first
  • Active threads
  • Popular
  • Thanks Niels de Klerk

    Reply Like
  • Niels de Klerk thank you very much. That was faster then expected! Give it a try later.

    Reply Like 1
  • Niels de Klerk Well shit, it looks like you (and NEEO) got me to invest time into this topic 😳 (take it as a compliment 😜)

    I have two stupid questions (really just started so please bear with me):

    1.) Controlling my Neato Botovac Connected
    I found the following two node modules:

    - https://www.npmjs.com/package/node-botvac
    - https://www.npmjs.com/package/homebridge-neato

    Assuming that they work, I should be able to control my Netao Botovac Connected (a cleaning robot for those who wonder) via NEEO Remote, correct? And if yes, what would I need to do (I guess something like a short overview of steps & involved components would be great)?

    2.) Homey
    How would Homey play into this, if at all?

    Again, please excuse my ignorance but I feel some of you could help me to get a kick-start into HA😊

    Reply Like
  •  Tom Schneider You want to use the https://www.npmjs.com/package/node-botvac   one.
    The other one is made for Apple Homekit nodeJS app homebridge.

     

    I wanted to include this in this guide but i couldn't edit it further as there is an edit timer.
    I chose to wait until i have some lifx lights so i could use them as an example. anyway, this should help you out.

    First you want to install the package. Go to the same directory where you installed the NEEO-SDK package. as described in my guide and use the explained install method as described on the node-botvac page. "npm install node-botvac".

    Now the node_modules directory in the /code/NEEO/ folder should also include the modules needed for your cleaner.

     

    make a copy of the Simpledevice and open it in Code.
    Change the index.js as follow:

    // first we set the device info, used to identify it on the Brain
    const customLightDevice = neeoapi.buildDevice('Botovac Connected')
      .setManufacturer('Netao')
      .addAdditionalSearchToken('cleaning')
      .setType('ACCESSOIRE')
    
      // Then we add the capabilities of the device
      .addButton({ name: 'clean-start', label: 'Start cleaning' })
      .addButton({ name: 'clean-stop', label: 'Stop cleaning' })
      .addButtonHander(controller.onButtonPressed);
    

    Now open the controller.js and include the example code as described on the node-botvac page.
    This example should work, atleast i hope so ;-). Dont forget to include your username and password at 'Typein@youremail.here','P@ssword'

     

    'use strict';
    
    //These are added to include the botvac module.
    var botvac = require('node-botvac');
    var client = new botvac.Client();
    
    module.exports.onButtonPressed = function onButtonPressed(deviceid, name) {
        //authorize
        client.authorize('Typein@youremail.here','P@ssword'falsefunction (error) {
            if (error) {
                console.log(error);
                return;
            }
            //get your robots
            client.getRobots(function (errorrobots) {
                if (error) {
                    console.log(error);
                    return;
                }
                if (robots.length) {
                  switch (deviceid) {
                    case 'clean-start': //Button clean-start is pressed
                      console.log ("Command to start cleaning.");
                      robots[0].startCleaning() 
                      break; 
                  
                    case 'clean-stop': //Button clean-stop is pressed
                      console.log ("Command to stop cleaning.");
                      robots[0].stopCleaning() 
                      break;
        
                    default: //Button unknown is pressed
                      robots[0].getState(function (errorresult) {
                        console.log(result);
                      });
                   };
                };      
            });
        });
    };
    
    

     

    i used the switch (deviceid) {} method to catch what button is pressed and what code it should run. could have also been a simple If but this way you can more easaly add features. and buttons. to play with.

    Reply Like 1
  • Tom Schneider said:
    2.) Homey How would Homey play into this, if at all?

    About Homey, If you own one then you could use my app to create a driver by just clicking without the need of any coding knowledge or coding experiance. Like Oswin Peters described in his post, we build IP support togetter for most of his devices using my NEEO app on homey. including a full functional kodi driver. This is all cool and im verry happy and enthousiastic about it, unfortunately the focus got to much on Homey where my intention was to share how i integrated all my stuff. (yes homey is now an essential part in it) and hopefully someone will take my idea and build similar features for other widely supported automation hubs. Like for instance Domoticz already supports a lot of IP controll out of the box i am hoping that someone will build somthing similar. In your case i've just checked there isn't a botvac app on homey so my app wouldn't help you there.

    So long anser short No you will never need or require Homey. i'm sorry if it looked that way.

    Reply Like 1
  • Niels de Klerk maybe you can give me a hint, trying to perform this code with node:

    echo -n "AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu36Lfog==" | base64 --decode | nc -v $IP 9999

    used this in Terminal it is functional, but i'm not really able to recode this for Node. I Know just copy and paste is not giving a function. but all i was trying doesn't work...

    If you don't have a hint maybe one of the NEEO node guys can give me a hint?

    Reply Like
  • Niels de Klerk Thanks a lot! Will dig into it later tonight! Regarding Homey: no, you did not make it look like one is needed - just me trying to figure out were it fits in (I don't have one)

    Reply Like
  • Markus Mahr 

    Markus Mahr said:
    echo -n "AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu36Lfog==" | base64 --decode | nc -v $IP 9999
    var b64string = "AAAAKtDygfiL/5r31e+UtsWg1Iv5nPCR6LfEsNGlwOLYo4HyhueT9tTu36Lfog==";
    var buf = Buffer.from(b64string, 'base64'); // Ta-da
    Reply Like
  • Niels de Klerk Thanks, i will give it a Try tomorrow. maybe now i will get it to work.

    at this time node is not really mine, but i will give node a few more changes.

    Reply Like
  • Niels de Klerk It's working and I can now start & stop my Neato with the NEEO Remote, very cool 😎

    Thanks a lot for your detailed help, this made things very easy 🍻

    Reply Like 2
  • Tom Schneider I expect a little show off video :-) 

    Reply Like

  • Niels de Klerk he has posted it on this Topic:

    https://planet.neeo.com/t/m2t22z/neeo-sdk-announcement#80tnw0

    Reply Like
  • Niels de Klerk You're right 😀 (I attached the video in the 'NEEO SDK Announcement' already, but quickly created a vimeo account now).

    Reply Like 5
  • Tom Schneider wow! This is so cool!

    Reply Like 2
  • Niels de Klerk Thanks for the Hint with the Code. It is Working! 🤗

    Reply Like 2
  • I managed to change my code to use a switch instead of the buttons using the example code from "discoverableLightDevice" and it's actually working 👍

    Though I struggle a bit (and this is just me having never realy programmed anything since a little bit of Java ~12 years ago) to achiev the following:

    1.) Get and set the real switch status (e.g. if the cleaning robot got started manually): I assume this is achieved with 'getter: controller.switchGet'?

    2.) Display if the robot got succssfully started/stoped (using the callback value from robot.startCleaning([eco], [callback]))

    3.) Display the current charge value (using the robot.getState function)

    Question:
    If someone happens to have time for some additional input would be great!

    Available Neato Botvac Functions:
    https://www.npmjs.com/package/node-botvac

    My current code:

    index.js:
    
    'use strict';
    
    const neeoapi = require('neeo-sdk');
    const controller = require('./controller');
    
    console.log('NEEO SDK Example "discoverableLightDevice"');
    console.log('------------------------------------------');
    
    const complexDeviceFull = neeoapi.buildDevice('Botovac Connected v2')
      .setManufacturer('Neato')
      .addAdditionalSearchToken('cleaning')
      .setType('ACCESSOIRE')
    
      .addSwitch({ name: 'power-switch', label: 'Power Switch' },
        { setter: controller.switchSet, getter: controller.switchGet })
    
      .addButton({ name: 'pro-button', label: 'Pro Bonus Button' })
      .addButton({ name: 'pro-button2', label: 'Pro Bonus Button2' })
      .addButtonHander(controller.button)
    
      .addTextLabel({ name: 'status-text', label: 'Status' }, controller.getExampleText)
    
      .registerSubscriptionFunction(controller.registerStateUpdateCallback);
    
    function startSdkExample(brain) {
      console.log('- Start server');
      neeoapi.startServer({
        brain,
        port: 6336,
        name: 'simple-adapter-one',
        devices: [complexDeviceFull]
      })
      .then(() => {
        console.log('# READY, use the mobile app to search for your newly added adapter!');
      })
      .catch((error) => {
        //if there was any error, print message out to console
        console.error('ERROR!', error.message);
        process.exit(1);
      });
    }
    
    const brainIp = process.env.BRAINIP;
    if (brainIp) {
      console.log('- use NEEO Brain IP from env variable', brainIp);
      startSdkExample(brainIp);
    } else {
      console.log('- discover one NEEO Brain...');
      neeoapi.discoverOneBrain()
        .then((brain) => {
          console.log('- Brain discovered:', brain.name);
          startSdkExample(brain);
        });
    }
    

     

    controller.js
    
    'use strict';
    
    const BluePromise = require('bluebird');
    
    //These are added to include the botvac module.
    var botvac = require('node-botvac');
    var client = new botvac.Client();
    
    /*
     * Device Controller
     * Events on that device from the Brain will be forwarded here for handling.
     */
    
    const UPDATE_FREQUENCY_MS = 2000;
    const COMPLEX_DEVICE_TEXTLABEL_NAME = 'example-text';
    const COMPLEX_DEVICE_UPDATE_ENTRY = 'unique-device-id-001';
    
    let textlabelValue = 'initial value';
    let switchValue = false;
    let sendComponentUpdate;
    
    /**
     * One button handler for each registered button
     */
    module.exports.button = function(deviceid, name) {
      console.log(`[CONTROLLER] ${name} button pressed on ${deviceid}!`);
    };
    
    /**
     * Getters and setters:
     * - The getters are used to send the current Values through the SDK (read)
     * - The setter allow changing values on the Brain and handling the changes here (write)
     */
    
    module.exports.switchSet = function(deviceid, value) {
      console.log('[CONTROLLER] switch set to', deviceid, value);
      switchValue = value;
      //authorize
        client.authorize('EMAIL','PW', false, function (error) {
        if (error) {
                console.log(error);
                return;
            }
            //get your robots
            client.getRobots(function (error, robots) {
                if (error) {
                    console.log(error);
                    return;
                }
                if (robots.length) {
                  switch (switchValue) {
                    case 'true': // Switch on
                      console.log ("Command to start cleaning.");
                      robots[0].startCleaning()
                      break;
    
                    case 'false': // Switch off
                      console.log ("Command to stop cleaning.");
                      robots[0].stopCleaning()
                      break;
    
                    default: //Button unknown is pressed
                      robots[0].getState(function (error, result) {
                        console.log(result);
                      });
                   };
                };
            });
         });
    };
    
    module.exports.switchGet = function(deviceid) {
      console.log('[CONTROLLER] return switch value', deviceid, switchValue);
      return BluePromise.resolve(switchValue);
    };
    
    module.exports.getExampleText = function(deviceid) {
      console.log('[CONTROLLER] get example text', deviceid);
      return BluePromise.resolve(textlabelValue);
    };
    
    
    /**
     * Sending updates to Brain:
     * If the device value can change, the updated values should be sent to the Brain.
     *
     * - Upon registration the SDK will provide an updat callback to the adapter.
     * - That function can be called with sensor updates
     */
    module.exports.registerStateUpdateCallback = function(updateFunction) {
      console.log('[CONTROLLER] register update state for complicatedDevice');
      sendComponentUpdate = updateFunction;
    };
    
    /**
     * Send random updates to the NEEO Brain. This is just for illustration purpose,
     * idealy those events would be sent of a device
     */
    setInterval(() => {
      if (!sendComponentUpdate) {
       console.log('update function not yet registered');
       return;
      }
    
    
      textlabelValue = 'Update ' + parseInt(Math.random()*200, 10);
      const updateTextlabelPayload = {
       uniqueDeviceId: COMPLEX_DEVICE_UPDATE_ENTRY,
       component: COMPLEX_DEVICE_TEXTLABEL_NAME,
       value: textlabelValue
      };
      sendComponentUpdate(updateTextlabelPayload)
       .catch((error) => {
         console.log('failed to send text notification', error.message);
       });
    
    }, UPDATE_FREQUENCY_MS);
    
    
    Reply Like
  • Tom Schneider try the module documentation. I haven't checked but I thing you have to periodically check the status.

    for changing and informing about status changes you can inspect the discoverable device there is an example code that puts random values.

    Reply Like 1
  • QNAP has node.js V4 available as a package and it is very easy to install. Unfortunately, that is how far I got. Anyone using node.js on a QNAP?

    Reply Like
  • If you do want to run node.js on your QNAP, you may want to read this blog post https://techblog.dorogin.com/running-nodejs-app-on-qnap-nas-via-pm2-3bdb838524e4

    Reply Like
  • When getting node.js for your QNAP, make sure whether your OS requires the 32-bit or 64-bit version.

    I was able to get node.js running and the NEEO SDK installed.

    Reply Like
  • Niels de Klerk

    I have two questions regarding your tutorial:

    (1) In your tutorial, you execute your code directly from Code. How would I start the simpleCustomDevice adaptor from node.js?

    (2) If I have multiple devices, would I put them all into a single index.js and controller.js or can I have multiple instances of these files?

    Reply Like
  • Paul Spee with the command line you can start your app with "node index.js"

     

    i havent started two drivers at the same time. It's something I wanted to test but haven't done yet. I want to know this to because my guess would be that it's not working without changing the SDK's server port. 

    Reply Like
  • Thanks Niels de Klerk

    How about checking the status while running or stopping the device?

    Reply Like
  • That didn't go as expected. I am getting an error message: BRAIN_NOT_REACHABLE". Anyone have any thoughts?

    Reply Like
  • Paul Spee On Windows you'll need bonjour. you can install itunes. on linux you probably need avahi.

    Reply Like 1
reply to topic
Like39 Follow