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
181replies Oldest first
  • Oldest first
  • Newest first
  • Active threads
  • Popular
  • hi Niels, thanks for this yout documentation. Unfortunatly i have got problems at the beginning of the installion process. Please see the attached png. Maybe you have an idee, what is going wrong.

    Thanks an regards

    Fredy

    Reply Like
    • Fredy Koller You need to use neeo-sdk instead of NEEO-SDK npm doesn't allow packages with capital letters!

      Niels de Klerk you should update that in the guide!

      Reply Like 2
    • Markus Mahr thanks a lot, Markus, now it works perfectly.

      regards Fredy

      Reply Like
    • Fredy Koller You Welcome.

      Also welcome back to this Topic!

      Reply Like
    • Markus Mahr Thanks, I have edited the OP

      Reply Like
  • Hi everyone!

    Thx a lot for sharing this knowledge. Since I'm somewhat used to JS I'm looking forward to start coding for NEEO. Did I get it right - the physical NEEO must be in my hands to start? Will the "normal" (non-beta) version do?

    Best regards,

    Bernd-Christoph

    Reply Like
    • Bernd-Christoph Schwede At the moment the SDK Code needs to run outside of the Brain. That means on a RasparryPi or an other Node.JS 6 Compatible device. The SDK is publical Available and is Working with each NEEO.

      But you don't need a NEEO or else to Start Coding. The only thing you need the NEEO Brain is to see if your Code is actually working and to check the Functions out.

      If you are further interested to Start, this Topic is the Best, just take some free time anr read throug it and throug the linksed Topics. If you have further Questions just ask, there are also some really good and Working Drivers allready available, they are really perfect to spy a bit for working code snippets. Elso enjoy the coding!

      Reply Like
    • Markus Mahr Now I got things somewhat up and running on my iMac. node.js installed without problems (I regarded the hint to use lowercase in 'nom install need-sdk' :-).

      Visual Studio Code was already installed, so firing up the first example was a breeze. The debugger warned 'Debugging with legacy protocol because Node.js v6.11.2 was detected.' - in the screeenshots above I see V7.7.1 in use - problem?).

      Next I struggled with the 'NEEO app' until I realized that is the NEEO app on the iPhone which needs to installed from the App Store. Did that. Started it. App tried to connect to a brain. Which I don't have (NEEO brain that is ;-). 

      Is there a way to start a server that acts as a NEEO brain so I can continue? Or do I need to wait for the brain to arrive?. When I start the "SimpleDevice" in Studio Code I run a node server that exhibits this device's interface to a NEEO brain? Or to the NEEO remote?

      Looks like I'm missing some pieces of the big picture...will have to read through the docs a little more.

      Best regards,

      Bernd-Christoph

      Reply Like
    • Bernd-Christoph Schwede as the Original gitHub SDK Page shows the following:

      Prerequisite

      you should not mention the Version think.

      The NEEO app is needed to Link your Driver to the Brain. Actual there is no Simulation of the NEEO Brain Available. Therfor to implement and Test you code the full way, you need a NEEO Brain and the App on a mobile Phone.

      The NodeServer is communicating allways to the Brain. The Brain is the Main Unit handling everything. The Remote is just the Remote!

      Reply Like
  • Impressed by the write-down Niels. Cant wait to start developping. With this topic and the good sdk it Will be very very doable. The fun is already starting and the devices arent even in yet!

    Reply Like 1
    • Harry Buurman Thanks for the kudos! I must warn you writing integrations is addictive....

      Reply Like 1
  • I've started to follow Niels his tutorial, because I'm curious I've I can make myself understand this world of coding/developing. Sadly I can not make it pass the 'F5' execute.
    Is this because I don't have an actual NEEO brain and remote yet?!
    Am I correct in understanding that this is necessary to be able to go ahead with the
    'getting started'?!
    Best regards, Jeroen

    Reply Like
    • Hi Jeroen and welcome to the new world of coding/developing ;-).
      All the sdk examples i've seen do indeed depend on having a brain reachable in the network.
      They look for a brain and once connection is established, the driver/integration/code is registered with the brain to have it executed.

      I don't know if anything can be done without a brain besides brushing up on some coding skill ;-) but maybe someone else can give some more information.

      Reply Like 1
    • Bjorn Vandenbilcke Thank you for your quick reply and clear answer! It's good to know, because otherwise I would have been trying for the rest of the day without any chance of succes. It's clear now that I'll have to wait to get things going ;) 

      Reply Like
    • Jeroen den Dunnen hi Jeroen, what do you mean with I can't make it pass the F5? You should atleast be able to run your code. Even though your unable to test it with the remote.

      to start with coding I would advice to pick a project you want to automate. Let's say it's your TV, go search if there is a node package allready made for that. Chances are there is one. The start simple tasks like if you run your code the next channel command is sent to your TV. Just as a tech preview of what you want to accomplish. When you received your neeo brain then you can include the NEEO SDK code to actually make a driver. Hope this helps you get started without having your neeo yet

      Reply Like
    • Niels de Klerk Okay Niels, this changes things. Can't pass the 'F5' portably because I'm on an Mac and the Microsoft Visual Studio looks a lot different and the 'right mouse' isn't available on Mac. So I started with setting up an new project and dragging the 'simpleDevice' files in it, even called the project the same. But nothing has worked so far. Also because I'm inexperienced, this doesn't help in the beginning. So I'm trying to take baby steps ;) Thank you for the extensive reply, much appreciated! Greets from a fellow Dutchman.

      Reply Like
    • Niels de Klerk My install of the 'need sdk' looks like this in my macOS terminal

      Reply Like
    • Jeroen den Dunnen maybe there is a green play button?! I'm sorry I never used a mac. Would love to have one one day but that's a different story. You can also start your code using the console. At the place where the code is you can type node nameOfScript.js to run it.

      Reply Like
    • Jeroen den Dunnen should there be an image included?

      Edit: now I see an image. Lol

      in the image I can see you have installed the neeo SDK node package. This is just that, you have installed the SDK. You now need to open for instance a example code and run it either with code or on commandline with node scriptName.js

      Reply Like 1
    • Niels de Klerk Thank you for the two reply's. I've tried to start the node in the terminal (see screenshot image). I keep getting the same error as I'am getting in a couple of code editors (been trying out; brackets, atom and visual studio). Been trying several editors because I couldn't find out the problem. So I thought let's try another editor to see I've that makes life easier. Sadly, this isn't the case ;) 

      Reply Like
    • Jeroen den Dunnen To be able to use the Visual Studio Code as descriped in the Topic here, just do the following:

      1. Start the Programm by clicking on the Icon.

      2. go anywhere with the Finder and add a Folder called NEEO (as example)

      3. open up the Terminal

      4. type cd (direction to your NEEO folder) or drap&drop the folder on the Terminal window

      5. now type in the folder directory in the terminal window npm install neeo-sdk and hit enter

      6. after the first one is finished type npm install neeo-sdk-examples and hit enter

      knwo you should see two new folders inside of the NEEO folder in the Terminal, one should called neeo-sdk-master and one neeo-sdk-examples-master these are the Two you installed previously.

      To Check the Code from the Examples go to the Visual Studio code window and drag and drop the examples folder in it. You know see the following:

      That is the way it is done on WIndos with the right click and Open with Code entry. You know see on the left every file contained in the folder. As you might see there are three example codes (discoverable light device, simple device and lifx) to run one of them you need to select the index.js file under each of the entrys then hit F5 to start the Code. Down in the screen you should see the Output in the consol!

      Reply Like
    • Jeroen den Dunnen This is actually good news. Its node that throws an error on your script. It says it cant find the node module neeo-sdk. You should install it in the working directory so it can find the modules.

      Reply Like
  • Just installed SDK + Visual Studio for mac and simple device sample code worked. Instructions were very good, it took something like 10-15 minutes to get this work and most of the time I spent to look alternatives for mac... until I realized that I dont need alternative software because both nodejs and visual studio code offered also mac versions :)

    Next I will try to get my Dahua security cameras working with my remote.

    My coding skills is almost zero. But I'm able to create damn good copy-paste code! :D

    Reply Like
    • Onni Manninen Hi onni,

      did you work on your dahua camera's i have also this one

      Reply Like
    • Serdar Güntekin Sorry for late answer! I did managed to get picture from my camera directly (not via NVR) but I have not got time to test things after that.  I was able to get image from camera with http://camera-ip-address/cgi-bin/snapshot.cgi url but it needs to modify url every time you want to refresh because brain will use cached image if url is the same.

      All I need to complete this is to code remote to use url like http://camera-ip-address/cgi-bin/snapshot.cgi+date like http://camera-ip-address/cgi-bin/snapshot.cgi+190917_0039 or something similar where time is different every time you press refresh.

      Still trying to figure out how to do this :)

      Reply Like 2
    • Onni Manninen it's great to see you also pulled it off. 👍

      Reply Like
    • Onni Manninen Could you share the code with me? Would be a good starting point!

      Reply Like
    • Sander Bottema I'm sorry for late answer, I was able to pull out still pictures from camera with http://<cameraIPaddress>/cgi-bin/snapshot.cgi command but like Niels de Klerk has commented earlier Brain will cache that picture and will display the same old picture later if you don't create some kind of change to that address (like add timestamp to the url). I used SDK sample with two different kitten pictures and replaced original image url with new url pointing to Dahua camera.

      Reply Like
  • I've been able to code my first custom device and it was working nicely, but after rebooting the computer, it won't go beyond "discover one NEEO Brain...".  

    The box is a Raspberry Pi running Linux raspberrypi 4.9.41-v7+.  It does run a VPN client that changes IP address on a regular basis, I suspect it has something to do with it.  

    Is there a automatically generated config file somewhere that stores the brain location after its first discovery that I could delete? Or is there a way to specify the IP address of the brain?

    Reply Like
    • If I reboot the brain and restart the service it finds the brain again.  The bigger problem is that I also need to rediscover the device in the NEEO app.  Any thoughts?

      Reply Like
    • I can confirm that it is related to the VPN.  If I don't use it everything is fine.  It's my problem then... 

      Reply Like
    • Ian Delisle As you allready discover by yourself, here a little "behind" view.

      The Driver is sending out IP and Port of itself to the Brain, the Brain does the same to the Driver, they both store this and listen allways on the both Ports, if something inbetween changed, there is no possibility to get it back.

      Short question from my side, why you coose your Internal IP (inside you Homenetwork) to be changed? or did you change your External IP?

      If the second aply, this normaly should not take effect on the SDK Driver, this is all handled internally. If you use the Same IP on the Raspberry, you don't need to rediscover the Device, you only need to restart the SDK Code on the Raspberry.

      Reply Like
    • Markus Mahr The internal IP doesn’t change but the VPN certainly does weird things with the network connection. I use the box to bypass some country-based content restrictions (we don’t get all the good stuff in Canada). I have another Pi I can use for this. Thanks for confirming my hypothesis.

      Reply Like
  • Niels de Klerk maybe a dumb question, but what happens if you create an initial version of your index.js and controller.js that just does an addButtonGroup('POWER') and you extend this with new methods, does this get picked up by Neeo automatically?

    Reply Like
    • Gilles van den Hoven you’ll need the re add the driver. Then yes

      Reply Like
    • Niels de Klerk Thanx.

      Patrick can a 'update details' button be added for the SDK so you can reload the device description? E.g. if you are developing that you don't have to remove the device and add all devices once more? Or is a brain reboot enough?

      Reply Like
      • Patrick@NEEO
      • Community Manager
      • Patrick
      • 2 yrs ago
      • Reported - view

      Gilles van den Hoven As far as I have understood, rebooting is not enough. I will check with our developers since I do not have a lot of experience with our SDK myself. 

      Reply Like
    • Patrick Gilles van den Hoven My previous check also says that a reboot of the Brain is bringing up the new functions. Sadly (at this state of the SDK) you need to delete and readd your device when you anhance the features, or if you only need to test some things.

      To keep you happier:

      But hey, you can now sort your recipes, that make it much easier then in the state were i coded my Dreambox driver, in the previous firmware you can't change the recipe listing. means, your last added device was your last recipe...

      Reply Like 1
  • I'm just trying to play with the SDK ... where is the "simpleDevice" in the current version ( v0.47.8) of the neeo-sdk-examples?

    Reply Like
  • I can't seem to make the examples work using latest examples from github (0.47.8).  😐

    I'm using windows, Bonjour installed, latest nodejs (was previously on 6.11 but it did not work).

    The script runs fine, no error, it finds the brain automatically or when I give it the IP address, but in the app I never find the new custom device.

    Is there something to activate in the brain or in the app to force it to add the custom devices in the search like a developer mode or something ?

    I know node an Javascript, but I'm totally clueless regarding how the node server communicates with the brain.

     

    Thank you for your help :)

     

    PS: with the latest examples, the name of the simple device has changed to "Simple Accessory" and to run it, if you don't use the debug feature of VS Code, you have to run "npm run server:accessoire", all the scripts commands can be found in package.json but it can be confusing for newcomers.

    Reply Like
    • Romain Prevost They don't change the instructions to the new names. Patrick can you let this be changed?

      Reply Like
    • Romain Prevost  I'm experiencing the same thing. Just got my Brain the other day, and as the Plex integration isn't done yet, I wanted to experiment on creating a simple driver for Plex, using their HTTP API instead of the IR controls currently supported.

      However, when running the simple example on my Mac, I get the following, but I can't find the device from the app:

      I'm used to working with Node, and as far as I can see, the service runs fine on my machine, the device is registered internally in Node, and the SDK connection gets registered on the Brain - my theory would be, however, that the Brain never actually queries the local service I'm running though.

      Reading some of the issues other people have had, I've tried to shutdown my local Docker/Virtualbox to avoid networking problems, but that hasn't helped either.

      Reply Like
    • Jesper Rasmussen Also, I did some further debugging - it seems the neeo-sdk on my machine runs Express on port 6336, which again exposes the API and the routes the Brain uses. By running through the code I would expect this to be the endpoint the Brain uses to find any devices available:

      http://<my local ip>:6336/db/search?q=foo

      The endpoint works perfectly, giving back a JSON structure for the simple accessory device - so again, my theory would be that the Brain just never actually calls the service for device search 😥

      Reply Like 1
    • Jesper Rasmussen Same here, the express server works, search works  in browser (from the host but also from a smartphone in the same network), adapter registers in the app but nothing on the brain. Brain firmware is 0.46.5 so latest.

      Other plugins don't work either (I've tried Kodi and Squeezebox) so it's not related to the example, maybe in the sdk dependency?

      Reply Like
    • Romain Prevost I have a Debian machine used for home automation, so I tested it on it and it worked on the first try, so it must have something to do with windows. (I tried with a fixed brain IP as multicast wasn't install on this machine)

      Reply Like
    • Jesper Rasmussen Thanks to the DEBUG library included in the sdk (use the environment variable DEBUG=* or DEBUG=neeo:*) I have found our issue which should not be widespread.. 😉

      I use Docker on my machine and therefore I have my main network card bridged to a virtual one (DockerNAT) with another IP. 

      The SDK is generating the URI to connect the brain to your machine automatically, but it did not used the normal local ip address but the bridged one.

      To overcome this, in index.js, under the startSdkExample function, change the options given to neeoapi.startServer and add a baseurl option set as 'http://YOUR_IP_ADDRESS:EXPRESS_PORT'. Afterwards it should work fine, I know it did for me 😀

      Reply Like
    • Romain Prevost Thanks for the tip on the debug mode - I figured out the issues was elsewhere on my setup though :)

      For some reason, the IP reported to the Brain was the correct one, and my Docker network wasn't running, but for some reason my local network could not reach the port remotely, only locally on my laptop. However, I ran a few tests on my local NAS, which is hardwired to the network, and the Brain was able to discover the driver running there - and I could get started on the driver :)

      Reply Like
    • Romain Prevost Thanks a lot! I was facing the same issue. Just recently got a Windows notebook, of course with Docker and Hyper-V, and the SDK wasn't working at all. Brain discovery still doesn't work, even with iTunes installed and 'pingable' by name (running on Windows, not Docker), but I can live with setting a static IP on my mobile development machine...

      On Linux everything works fine though, including Brain discovery.

      Reply Like
    • Markus Zehnder  Romain Prevost

      If you have multiple interfaces, the SDK will only listen on one of them (and if you're like me - it's usually the wrong one).  Awhile back, I submitted a patch that would get it to listen on all interfaces - but it hasn't been merged yet (and may not even be valid with the latest SDK iterations).

      The workaround is to disable all the other interfaces and try it again - I'm betting it will work.  You can check out the patch in the pull requests of the NEEO sdk...

      Reply Like
  • Niels de Klerk Patrick First of all thanks for all your contributions here. I received my NEEO yesterday and it's fully up and running. Good stuff, lots of features that come to mind though that I'm missing but this should keep me busy for now :). The SDK is also running on a Raspberry to control my VU+ Ultimo, all good. Now I want to take this to the next level and add my ip camera's & Netatmo Presence that I currently have in Homekit (through Homebridge).

    I'm not much of a developer and cannot figure out how to add an image. Hopefully you or someone else can share some example code:

    .addImageUrl( { name: 'albumcover', label: 'Cover for current album', size: 'small' }, controller.getImageUri )

    Reply Like
    • Sander Bottema what you want to do is to see if there is an url that you can use to obtain a jpg image from your camera. Not all cameras support this and without it you won’t be able to  create a driver.

      Reply Like
    • Niels de Klerk Thanks, but that I know. I have all the URL's as I use the camera's in Homebridge. Looking the use the JPG snapshot URL's but I can't figure out how to do the code to use the actual URL.

      Reply Like
    • For example: http://homekit:xxx@192.168.1.116/cgi-bin/snapshot.cgi?loginuse=homekit&loginpas=xxx which returns the snapshot.cgi.jpg

      or from the Netatmo Presence (created token through Fibaro LUA script): http://192.168.1.123/84440abf1103f83625e89bec999a0d4e3/live/snapshot_720.jpg

      Reply Like
    • Niels de Klerk  Never mind, got it! :) 

      Reply Like 1
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      Sander Bottema can you plase explain what you did?

      Reply Like
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      Sander Bottema I was able to add the image by adding...

      this in index.js

      .addImageUrl({ name: 'albumcover', size: 'small' },controller.GetImageUrl)

       

      and this in controller.js

      module.exports.GetImageUrl = function(deviceid) {
      return 'http://192.168.XXX.XXX/xxxxx/xxxxx/xxxxx.jpg';
      };

       

      How can this image be updated!?

      Reply Like
    • Markus M for every call, you need to change the image name, if you don't do this, the image is used out of the cache.

      Reply Like
    • Markus Mahr Markus M I was wondering the same thing as it kept displaying the first image. 

      Maybe write it to a temp folder first with a time/date stamp and refresh it every 5 sec’s or so. Also a good step to resize the image first instead of using the full 4K JPG coming from my Dahua cameras.

      I suck at coding but will give it a go...

      Reply Like
    • Markus M  Here's what I've got so far. This updates the images every time the script is started. Now I just need to find a way to update the images on a set interval. It writes the images to the temp folder and deletes the old. These images are then served by a webserver so the I can use the URL to update the images. 

      There's probably a much better way though...

       

      'use strict';

      const BluePromise = require('bluebird');
      var request = require('request');
      var http = require('http'),
      fs = require('fs');
      let RootPath= '/home/pi/neeo-driver-cam/temp/';
      /* SERVE IMAGES */
      var express = require('express')
      var serveStatic = require('serve-static')
      var app = express()
      app.use(serveStatic(RootPath, {'index': ['default.html', 'default.htm']}))
      app.listen(3000)

      var hours = (new Date()).getHours();
      var minutes = (new Date()).getMinutes();
      var seconds = (new Date()).getSeconds();
      var day = (new Date()).getDay();
      var month = (new Date()).getMonth();
      var year = (new Date()).getYear();
      let filename = day + '-' + month + '-' + year + '_' + hours + '-' + minutes + '-' + seconds + '.jpg';
      let netatmocamurl = 'http://xxxxx/snapshot_720.jpg';
      let garagecamurl = 'http://xxxxxx/cgi-bin/snapshot.cgi?loginuse=homekit&loginpas=xxx';
      let textlabelValue = 'Netatmo Presence';
      let textlabelValue2 = 'Dahua Garage';
      let sendComponentUpdate;

      var request = http.get(netatmocamurl, function(response) {
          if (response.statusCode === 200) {
              var file = fs.createWriteStream(RootPath + "N" + filename);
              response.pipe(file);
          }
          // Add timeout.
          request.setTimeout(5000, function () {
              request.abort();
          });
      });

      fs.readdir(RootPath, (err, files)=>{
         for (var i = 0, len = files.length; i < len; i++) {
            var match = files[i].match(/(N|G).*.jpg/);
            if(match !== null)
                fs.unlink(RootPath+''+match[0]);
         }
      });

      var request = http.get(garagecamurl, function(response) {
          if (response.statusCode === 200) {
              var file = fs.createWriteStream(RootPath + "G" + filename);
              response.pipe(file);
          }
          // Add timeout.
          request.setTimeout(5000, function () {
              request.abort();
          });
      });

      module.exports.getExampleText = function() {
        console.log('Set Cam1: ' + textlabelValue);
        return textlabelValue;
      };

      module.exports.getExampleText2 = function() {
        console.log('Set Cam2: ' + textlabelValue2);
        return textlabelValue2;
      };

      module.exports.getImageUriNetatmo = function() {  console.log('Downloading image N' + filename);
        return 'http://192.168.1.114:3000/N' + filename;
      };


      module.exports.getImageUriGarage = function() {  console.log('Downloading image G' + filename);
        return 'http://192.168.1.114:3000/G' + filename;
      };

      Reply Like
    • Sander Bottema you don’t need to change the image name. But the url to the image needs to be different every time you want an updated image.

       

      if the image url is http://camera/pic.jpg

      all you got to do is request http://camera/pic.jpg?1

      next time

      http://camera/pic.jpg?2

      and so on...

      a date and time representation would be more easy btw.

      Reply Like
    • Niels de Klerk Thats interessting, i don't know that, else i had  given this info earlier. Thanks for the Update, should be considered to be added to the API Documentation! Michael Vogt Patrick

      Reply Like
    • Markus Mahr I don’t think so. It’s a workaround to overcome caching images. Typically you want all images cached that where grabbed by the brain.

      the image feature is meant to display now playing items and such. Viewing camera images is more a hack then a feature.

      Reply Like
    • Niels de Klerk But it should be a feature ;-p

      But if there is a solution to get such things to work, it should be visible in the documentation. I know that it is currently no feature, that is "wanted" by NEEO. But if you can, you want! (At least i do so)

      Reply Like
    • Markus Mahr Onni Manninen Niels de Klerk  Niels, thanks for the update, that helps. Driver is now working. It doesn't update dynamically but it does when opening the shortcut so you'll see the latest snapshot. I will create a new topic for it.

      Reply Like
    • Sander Bottema what you can do is adding a “send component update” that informs neeo there is a change to the component. What I did is I added a button named refresh that updates the image state to a new url. This way I’m in charge of a reloading the image. I also chang the url on a Power On so when I start the recipe I have the latest image.

      Reply Like 1
  • Hi guys,

    I have been playing a little with the SDK and noticed a couple of things.

    Reg. ImageUrl: The implementation seem to be quite different when running on a phone or on the remote.

    I am using a doorBird ( http://www.doorbird.com ) as video door intercom so was trying to create a simple driver for it.

    reading through the previous threads, I implemented a simple node.js web service to wrap the doorBird API so I could "alter" the imageURL whenever I wanted a refreshed image.

    This worked directly with the neeo IPhone app but was not giving consistent results on the remote itself.

    while debugging I noticed that the remote is asking for the URI much more that the IPhone app; since these requests can be quite close to each other, the result was that the image was never displayed on the remote.

    What I have done for now is make sure the URL is not updated more than once every 20 seconds and it seem to do the trick.

    Reply Like 1
    • gerald carosati Thank you, I've got the same issue for the Netatmo Presence driver.
      Now that I know where the problem is, I change the URL every 5 seconds in a background setInterval instead of returning a dynamic image uri on the getter. And it works much better !

      Reply Like
  • Hi guys, since last brain firmware update (0.47.9) the sdk don't want to discover the brain anymore and i must set the ip manually. I am the only one to have the problem?

    Regards

    Reply Like
    • Jean-christophe Vermandé working for me ... did you try to restart the brain ? (Real power cycle)

      Reply Like
  • gerald carosati thanks... Finally discovered after two reboot 👍

    Niels de Klerk Hello, can you tell me if the SDK will support soon new object for the interface as a list (ideally customizable)? I finish a driver for a french ISP IPTV Player through TCP and it would be great if i could add TV guide: channels list with channel logo, program name etc.

    Reply Like
  • Seems like quite a good intro although incredibly basic. Seems that you are trying to teach people how to use git, vs code, npm and node all in one tutorial!!

     

    Did I miss the step where you installed VS Code? It seems that you assume everyone has it on their computer.

     

    I am not sure that referring to line number in a file that will probably change (the folder name is already different from what you refer to here) is no the best way of demonstrating code. Snippets of code in the blog post will probably be better.

     

    Lastly I can't find a simple explanation of what the API can do anywhere. This tutorial seems to be for the brain / controller to control a new device defined in software. I want to control the brain from a different device.

     

    i.e. I want to write some code in node to turn everything off - when I leave my living room press my flic button that is linked to node red to turn all the lights off, this will also talk to the brain to turn off the tv, dvd, amp ect ect.

    I assume that is possible? Are there any tutorials on that?

    Reply Like
    • Giles Roadnight There is a documentation (really basic) you can find it over here: https://neeoinc.github.io/neeo-sdk/

      Reply Like 1
    • Giles Roadnight The toturial have let multiple users that never ever coded one word in their lives to make their first driver. So I think I keep it this way.

      The more advanced users should be able to figure out the API calls quite easily as I’m not a coder and I was able to find them in under 5 minutes. But for the API beginners I’ve also made an API starting guide so even the non techies can call some API calls and start their recipes and such, all basic stuff though.

      Reply Like
  • .setType('AVRECEIVER') makes problems.. when i run the script. 

    .setType('ACCESSOIRE') works without a problem. Same script.

    Log: 

    result undefined

    WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
    WARNING: no input commands defined! Your device might not work as desired, check the docs

    Reply Like
    • Björn Müsing If you are using an AVR it must have commands named "input xxx".

      Reply Like
      • hansk
      • Hansk
      • 9 mths ago
      • Reported - view

      Niels de Klerk Does this mean that all buttons defined in e.g. index.js need the text "input xxx"?

      What if I want to map the volume toggle to the mute hard key of the remote? Then I need the text MUTE TOGGLE. I suppose INPUT MUTE TOGGLE does not work and does not make any sense.

      Thanks

      Reply Like
    • hansk no it must have at least some inputs. For naming convention you can view follow https://planet.neeo.com/t/k9tnlp#capability-names-button-names

      Reply Like
      • hansk
      • Hansk
      • 9 mths ago
      • Reported - view

      Niels de Klerk Thanks a lot for the quick response. It works.

      Reply Like
  • I'm working on some extensions via the SDK, but ran into an issue if you want to run them simultaneously because the port number is hardcoded (in your examples). Based on node's modules it would be nice to run multiple modules alongside each other. Anyone figured out an solution for this?

    Reply Like
    • Peter Meijer you can set a different port for each driver.

      Reply Like
    • Niels de Klerk Hi Niels, thanks for your quick reply! However, this requires a (tedious) manual input every time you install a driver. I would be nice to get a plug-and-play feeling when installed a driver via NPM.

      Reply Like
    • Peter Meijer I agree, but for now this is the way to go.

      Reply Like 1
    • Niels de Klerk This could be something: https://github.com/indexzero/node-portfinder . When starting for the first time, an available port number is found and stored in a text file. When started for a second time, the node module checks for a stored port...

      Reply Like
    • Peter Meijer Niels de Klerk in the NEEO Examples there is a Example 😬 how to use multiple drivers in one instance. You can find it over here:

      https://github.com/NEEOInc/neeo-sdk-examples/tree/master/lib/device/multipleDevices

      Reply Like
    • Markus Mahr Hi Markus, thanks for pointing this out. But in the NPM style, you normally install the modules next to each other. Your solution requires lots of copy paste. Ideally, you would use "npm -g install module_name" to install all required NEEO modules. This is now not possible due to the overlapping ports.

      Reply Like
    • Peter Meijer The server should be separated from the SDK. that's known. for now all we got are these alternatives.

      Reply Like
    • Peter Meijer it is not my solution, it is the solution that is provided from neeo! Actually the best solution would be to import a driver to the Brain, via search and find or via a upload solution. But this needs time to be implemented and the current solutions are helps to get everything working. Not more, not less!

      Reply Like 1
    • Markus Mahr Niels de Klerk  Since you start the node script by hand, I decided to go with CLI parameters: 

       

      function startController(brain, port) {
        console.log('- Start server on port ' + port);
      
        neeoapi.startServer({
          brain,
          port: port,
          name: 'osx-spotify-controller',
          devices: [osxSpotify]
        })
        .then(() => {
          console.log('# READY! use the NEEO app to search for "NEEO Accessory".');
        })
        .catch((error) => {
          //if there was any error, print message out to console
          console.error('ERROR!', error.message);
          process.exit(1);
        });
      }
      
      //Fetch the optional port number via the path argument variable
      const portnumber = parseInt(process.argv.slice(2));
      
      //START Brain discovery
      const brainIp = process.env.BRAINIP;
      if (brainIp) {
        console.log('- use NEEO Brain IP from env variable', brainIp);
        startController(brainIp, portnumber);
      } else {
        console.log('- discover one NEEO Brain...');
        neeoapi.discoverOneBrain()
          .then((brain) => {
            console.log('- Brain discovered:', brain.name);
            startController(brain, portnumber);
          });
      }
      
      Reply Like
    • Peter Meijer that’s also a way to do it. I haven’t used the SDK for quite some time now. I wasn’t even aware of the example that Markus Mahr pointed out. There could be more options but I’m fully focused on my NEEO app for homey and for that I wrote my own ”SDK” so I could Change drivers (add, remove, change capabilities, etc) without the need of stopping and starting code.

      Reply Like 1
  • Niels de Klerk 

    Thank you for all examples and tutorial!!! 

    I need some help, i can't find device on neeo app! How to test that server is running? It seems to be discovered in neeo logs.

    All seems to be installed brain discovered but dose not work, could it be version missmatch?

    BTW example devices is different in new sdk and not like on your tutorial.

    Reply Like
  • For windows 10 Users and this error ("property '0' of undefined") while installing NEEO-SDK:

    npm install neeo-sdk -save
    
    npm ERR! Cannot read property '0' of undefined

    This seems to be a bug with NPM 5.3.0

    npm -v
    
    5.3.0
    

    Installing NPM 5.2.0 will solve this:

    npm install -g npm@5.2.0
    
    + npm@5.2.0
    added 506 packages in 14.159s
    
    Reply Like
  • Good morning, a question, once I have finished my program controller.js and index.js, to use it permanently, how can I save it? I have to always have a server on (my computer)? I also use dependencies, specifically the "request".

    Reply Like
    • Victor 

      Yes - you'll need some type of always on device to run the plugin (PI, NAS, NUC, etc)

      Reply Like 1
  • I'm exploring the possibilities to add a driver to control/ get information from Yamaha AVRs.

    I hope somebody can help me. Probably it is only due to my low programming skills...

    There's a node module for Yamaha devices from PSeitz on github. https://github.com/PSeitz/yamaha-nodejs

    I want Neeo to show the album art. So i added some code to simpleCommands.js (of the node module):

    Yamaha.prototype.getPlayInfo = function() {
     var command = '<YAMAHA_AV cmd="GET"><SERVER><Play_Info>GetParam</Play_Info></SERVER></YAMAHA_AV>';
     return this.SendXMLToReceiver(command).then(xml2js.parseStringAsync);
    };
    
    Yamaha.prototype.getShortAlbumArtURL = function() {
     return this.getPlayInfo().then(function(info) {
      var PlayInfo = [];
      var PlayInfoXML = info.YAMAHA_AV.SERVER[0].Play_Info[0].Album_ART[0].URL[0];
      return PlayInfoXML;
     });
    };

    Now i can print the URL to the Console with this code:

    yamaha.getShortAlbumArtURL().then(function(result){
     console.log("URL is:"+result);
    })

    Console:

    URL is:/YamahaRemoteControl/AlbumART/AlbumART3489.jpg

    But if i want to add the IP Adress:

    var ShortAlbumArtURL = yamaha.getShortAlbumArtURL()
    var FullAlbumArtURL = 'http://' + yamaha.ip + ShortAlbumArtURL;
    console.log(FullAlbumArtURL);

    The output of the console is:

    http://192.168.178.39[object Promise]

     

    Can somebody please help me with this?

    Reply Like
    • Markus M follow your first code snippet. There the .then is included. This means that when the function is ready it will execute the code. 

      Cant type it out now on my phone.

      Reply Like
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      Niels de Klerk Hi Niels, PSeitz helped me to write the URL the Console with:

      yamaha.getShortAlbumArtURL().then(function(url) {
          var FullAlbumArtURL = 'http://' + yamaha.ip + url;
          console.log(FullAlbumArtURL);
      })

      Unfortunately i cannot use the code like this (the image is then undefined):

      module.exports.GetImageUri = function(deviceid) {
       return yamaha.getShortAlbumArtURL().then(function(URL) {
       var FullAlbumArtURL = 'http://' + yamaha.ip + URL;
       console.log(FullAlbumArtURL);
       })
      };

      I suspect that has something to do with the ".then" you mentioned.

      Maybe i sould just wait for a little longer until someone takes care of a driver for Yamaha ^^

      PS: the code above can also be modified to display/ obtain other information such as the artist, album or even settings of the AVR.

      Reply Like
    • Markus M in the second code part add

      return FullAlbumArtURL;

      just after the console.log line. This way you return the data. Now the uri is set in a variable and logged to console but no data is returned, hence the undefined.

      using .then is used with a promise. You could read into that and probably get more confused lol. I’m having a hard time grasping that as well so don’t let that stop you from making something nice.

      Reply Like
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      Niels de Klerk Thank you Niels

      My Code now is:

      SimpleCommands.js:
      
      Yamaha.prototype.getPlayInfo = function() {
       var command = '<YAMAHA_AV cmd="GET"><SERVER><Play_Info>GetParam</Play_Info></SERVER></YAMAHA_AV>';
       return this.SendXMLToReceiver(command).then(xml2js.parseStringAsync);
      };
      
      Yamaha.prototype.getShortAlbumArtUrl = function() {
       return this.getPlayInfo().then(function(info) {
        var PlayInfo = [];
        var PlayInfoXML = info.YAMAHA_AV.SERVER[0].Play_Info[0].Album_ART[0].URL[0];
        return PlayInfoXML;
       });
      };

       

      controller.js:
      
      module.exports.getInfo = function(deviceid) {
       return yamaha.getShortAlbumArtUrl().then(function(Url) {
        var FullAlbumArtUrl = 'http://' + yamaha.ip + Url;
        console.log(FullAlbumArtUrl);
        return FullAlbumArtUrl
      })
      };
      
      module.exports.getImageUri = function(deviceid) {
       return yamaha.getShortAlbumArtUrl().then(function(Url) {
        var FullAlbumArtUrl = 'http://' + yamaha.ip + Url;
        console.log(FullAlbumArtUrl);
        return FullAlbumArtUrl
      })
      };

       

      index.js:
      
      .addImageUrl({ name: 'Albumcover_small', size: 'small', label: 'Albumart_small' },controller.getImageUri)
      .addTextLabel({ name: 'info_server', label: 'Info' },controller.getInfo)

       

      This Displays the Albumart as well as the URL as an info label. The URL gets also written to the Console and is refreshing every few seconds (why? Edit: This seems to be be due to grabbing the Remote).

      And some cosmetics need to be done as the first time the URLs are written to the console there is just the IP adress. Edit: This maybe to be due to actually not playing anything

      But it works :)

      Reply Like
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      The node module from PSeitz allready supports a lot of commands. For the additional Playback Info i can now add somthing like this:

      SimpleCommands.js:
      Yamaha.prototype.getArtist = function() {
       return this.getPlayInfo().then(function(info) {
        var PlayInfo = [];
        var PlayInfoXML = info.YAMAHA_AV.SERVER[0].Play_Info[0].Meta_Info[0].Artist[0];
        return PlayInfoXML;
       });
      };
      
      controller.js:
      module.exports.getArtist = function(deviceid) {
       return yamaha.getArtist()
      };
      index.js
      .addTextLabel({ name: 'info_artist', label: 'Artist' },controller.getArtist)
      Reply Like
      • Markus M
      • Markus_M
      • 1 yr ago
      • Reported - view

      Andy Niels de Klerk

      Markus M said:
      This Displays the Albumart as well as the URL as an info label. The URL gets also written to the Console and is refreshing every few seconds (why? Edit: This seems to be be due to grabbing the Remote).

       I wanted to tinker with the driver again. Are the labels and images no longer updated automatically when grabbing the remote?

      (My firmware is 0.50.13 and i have updated the sdk to the latest version. )

      Reply Like
  • Not sure what it is I'm doing wrong here, I followed the guide and came unstuck VERY early on. I have never coded a thing in my life other than basic Pi stuff which I copied and pasted, no idea what i did literally copied and pasted. Now where I'm getting to is this: 

     

    I get to the part were I open VS and select index.js there is a description of what each line is, mine stops at line 24, when pressing F5 I get nothing about my Brain being discovered. 

     

    I have Bonjour, it works as I find other devices using this for work, I can ping the brain and Remote i.e. in CMD ping its IP. What i cant find is the other ping peope have described where they have some from of ID?!? Whre do you even gt this info? (NEEO-xxxx.local) what is that? literally no clue, to me ping is open CMD type ping 192.168.1.1 for example. 

    What am I doing wrong?

    Reply Like
    • Alex Martin  try this,  (stolen from above, but something i had to do early on)

      Change

       

      
       
        neeoapi.startServer({
      
          brain,
      
          port: 6336,
      
          name: 'simple-adapter-one',
      
          devices: [complexDeviceLite, complexDeviceFull]
      
        })
      

      Into

       

      
       
        neeoapi.startServer({
      
          brain: '10.10.10.10',
      
          port: 6336,
      
          name: 'simple-adapter-one',
      
          devices: [complexDeviceLite, complexDeviceFull]
      
        })
      

       

      Where 10.10.10.10 is your brain IP 

      Reply Like
    • Stuart Trout I cant though, I dont even have that, all I get it this:

       

      'use strict';
      
      
      const neeoapi = require('neeo-sdk');
      
      const controller = require('./controller');
      
      
      /*
      
      * Adapter - an Adapter contains one or more DEVICES. In this case we only use a single very
      
      * simple device.
      
      */
      
      
      // first we set the device info, used to identify it on the Brain
      
      const customLightDevice = neeoapi.buildDevice('Simple Accessory')
      
      .setManufacturer('NEEO')
      
      .addAdditionalSearchToken('foo')
      
      .setType('ACCESSORY')
      
      
      // Then we add the capabilities of the device
      
      .addButton({ name: 'button-a', label: 'Button A' })
      
      .addButton({ name: 'button-b', label: 'Button B' })
      
      .addButtonGroup('Color Buttons')
      
      .addButtonHandler(controller.onButtonPressed);
      
      
      module.exports = customLightDevice;

      It stops here where I am expecting to see the Brain details etc. I followed the guide above to the letter (other than my C: drive user location) and it come up with different results. Like I said I'm totally new to JS coding and if it differs from the expected results I've no idea where to go from here

      Reply Like
  • Ive build a simple driver that should be easy to start with.
    I removed everything unnessesary.

    https://github.com/nklerk/neeo_driver-simple

    Have fun.

    Reply Like
      • Anders Tao
      • Anders_Tao
      • 9 mths ago
      • Reported - view

      Niels de Klerk Thanks for all your work

      I am using your neeo_driver-simple to get startet with my Indigo devices. I will update, and add commands to the devices all the time, and as it is right now, I need to remove, and add the devices back everytime.

       

      Is there a way to add the Check for update function to my devices with this project?

      I did find this issue on github https://github.com/NEEOInc/neeo-sdk/issues/18 but I am not sure how to implement with your project, or if it need the new CLI to work

      Reply Like
    • Anders Tao currently it’s not possible. With the next SDK version this becomes possible, with some limits (Requires upcoming firmware as wel)

      see: https://github.com/NEEOInc/neeo-sdk/tree/next

      and:

      https://github.com/NEEOInc/neeo-sdk-examples/tree/next/lib/updateableDevice

      for more info.

      Reply Like
      • Anders Tao
      • Anders_Tao
      • 9 mths ago
      • Reported - view

      Looking forward to the 0.52 update 🎉

      Thanks for your reply Niels de Klerk 🎅

      Reply Like
      • Andrew
      • Andrew
      • 9 mths ago
      • Reported - view

      Niels de Klerk I have tried this out and I get the console to display something like " READY! use the NEEO app to search for: My first driver" but when I go to the NEEO app and search for "My first driver" it doens't find anything.  I tried changing the text to something like "drew" and still nothing.  What am I missing?

      Thanks,

      Drew

      Reply Like
    • Andrew could you share the output of your console?

      Reply Like
      • Andrew
      • Andrew
      • 9 mths ago
      • Reported - view

      Niels de Klerk 

       

      Reply Like
      • Andrew
      • Andrew
      • 9 mths ago
      • Reported - view

      Andrew I am seeing that under SDK Intergration in the iPhone app it is showing something after I run this; just when I search for "drew" under devices I am not seeing it. I am very new to this, is that even where I am suppose to be searching?

      Reply Like
    • Andrew do you have firewall software installed that's interfearing? looks like the driver can contact the brain. but when searching for a device the driver is unable to connect to your driver to search there.

      Reply Like
      • Andrew
      • Andrew
      • 9 mths ago
      • Reported - view

      Niels de Klerk I have just tried this morning after turning off all the Windows Defender Firewall settings and it worked!  I turned all the firewall settings back the default and it is still finding it, so I am unsure if that was it or if it was a timing issue.  Should the device be discover-able pretty much immediately?

      Thanks for your timely replies and help figuring this out,

      Drew

      Reply Like
    • Andrew When you see "READY! use the NEEO app to search for:" then the SDK started the server that is hosting the driver and informed your neeo brain to include your driver when adding a new device. When you are searching for a device in the App it will send a queery to the NEEO servers and to your SDK driver. In case you have multiple drivers then they will also be queeried. I suspect the brain wasn't able to connect to your computer and thus not returning a driver. usually this is due to a firewall. You can open up the port on your computer. the port number is the one you provided in the index.js. (my example has it set to 1104 but you are free to change that)

      Reply Like
  • I'm trying to migrate to the new @neeo/cli driver method on OSX, but the local server won't start because it cannot find the brain. I saw a comment from Paul Spee  from one year ago, but I have managed to run drivers the old fashioned way before, and can resolve/ping my local NEEO brain... Any recommendations?

    Info: - Brain discovered: NEEO Living Room

    Info: Start server, connect to NEEO Brain: { brain: 'NEEO Living Room', host: 'NEEO-xxxxxx.local' }

    Error: BRAIN_NOT_REACHABLE

     

    Update with extensive debug logging I get the following:

      neeo:driver:express IGNORE_REQUEST_EXPRESS_SERVER_ALREADY_RUNNING +13s

      neeo:device:index ERROR: Could not connect to NEEO Brain { attemptCount: 9, error: 'Request failed with status code 500' } +13s

      neeo:device:index maximal retry exceeded, fail now.. +0ms

    Error: BRAIN_NOT_REACHABLE

     

    Looks exactly the same like this error: https://gist.github.com/barnabycourt/2d2347391894878560439a63f654864a

     

    Update 2: I can use the driver until the BRAIN timeout of 5000ms kicks in. So everything is working fine, but the timeout is killing the start of the server for some reason...

     

    Update 3: FIXED! After cleaning up the NEEO SDK connections in the NEEO app, the BRAIN didn't time out anymore.... Published the packages to NPM (neeo-driver-osx-volume & neeo-driver-osx-remotebuddy)

    Reply Like 1
Like39 Follow