Skip to content

Commit

Permalink
Merge pull request #34 from ldhertert/ozw-auto-windows-install
Browse files Browse the repository at this point in the history
[windows] Install Open Z-wave dependency
  • Loading branch information
ekarak committed Oct 16, 2015
2 parents 8ccc107 + a1de8e5 commit 82d5901
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 11 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ OZW_Log.txt
build
zwcfg*
zwscene.xml
lib/open-zwave
node_modules
20 changes: 12 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ This also means that you need to be careful if you upgrade your
OZW library: you might need to rebuild this addon, otherwise you'd might
get api mismatch exceptions.

## Install
## Prerequisites

The module currently builds only on Linux (and Windows, but its untested).
On Linux you will need to ensure the OpenZWave library and headers are
installed first.
### Linux/OSX

You will need to ensure the OpenZWave library and headers are
installed first. You can do this one of two ways.

- Manually compiling OpenZwave involves the usual dance of 1) downloading its source tarball
([latest code from GitHub](https://github.com/OpenZWave/open-zwave/archive/master.zip) or
Expand All @@ -54,16 +55,19 @@ and then 2) compiling it and installing on your system (`make && sudo make insta
**Notice:** Be sure to install *BOTH the binary (libopenzwave-x.y) AND the development
package (libopenzwave-dev).*

### Windows

Since there is no standard installation location for Open Z-Wave on Windows, it will be automatically downloaded, compiled, and installed when you install this module.

## Installation

**Node.JS >= 3.0 users**: please send me reports if the addon works or breaks.
I've had very bad experience with the NodeJS API quicksand already, and NAN
appears to not be able to keep up. The NodeJS API is truly a wizard's tribute to Ctrl+Z.

It should also compile in Windows, but you need to edit binding.gyp
to set the paths for the OpenZWave library sources and libraries.

Whenever you have OpenZWave installed in your machine, then all you need to do is:
```
$ sudo npm install -g openzwave-shared
$ npm install openzwave-shared
```

## Development documentation
Expand Down
2 changes: 1 addition & 1 deletion binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
}],
['OS=="win"', {
"variables": {
"OZW_HOME": "<!(node -p -e \"process.env.OZW_HOME.replace(/\\\\/g, '/')\")"
"OZW_HOME": "<!(node lib/install-ozw.js --get-ozw-home)"
},
"include_dirs": [
"<!(node -e \"require('nan')\")",
Expand Down
219 changes: 219 additions & 0 deletions lib/install-ozw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
//This file will download the most recent version of open zwave, build it, copy it to
//~\AppData\Local\OpenZwave, and set the environment variable OZW_HOME
//USAGE: node install-ozw-windows.js [node-gyp-args]

var fs = require('fs');
var ChildProcess = require('child_process');
var path = require('path');
var request, unzip, gyp, wrench; //these are dynamically required later on

var originalPath = process.cwd();
var tempPath = path.resolve(require('os').tmpDir() + 'ozwinstall/' + Math.random().toString(36).substring(7));
var installPath = path.resolve(process.env.HOMEPATH + '/AppData/Local/OpenZWave/');
var ozwSourceUrl = "https://github.com/OpenZWave/open-zwave/archive/master.zip";
var gypOptions = [];

var ozwGyp = {
"targets": [
{
"target_name": "openzwave",
"type": "static_library",
"sources": [], //these are populated dynamically by looking at the source code files
"include_dirs": [
"cpp/hidapi/hidapi",
"cpp/src",
"cpp/src/command_classes",
"cpp/src/platform",
"cpp/src/value_classes",
"cpp/tinyxml"
],
"configurations": {
"Release": {
"cflags": [
"-Wno-ignored-qualifiers",
"-Wno-tautological-undefined-compare",
"-Wno-unknown-pragmas"
],
"xcode_settings": {
"OTHER_CFLAGS": [
"-Wno-ignored-qualifiers",
"-Wno-tautological-undefined-compare",
"-Wno-unknown-pragmas"
]
},
'msvs_settings': {
'VCCLCompilerTool': {
'ExceptionHandling': 1
}
},
}
},
"conditions": [
['OS=="linux"', {
"include_dirs": [ "cpp/src/platform/unix" ],
"sources": [
"cpp/hidapi/linux/hid.c",
],
"sources/": [
['exclude', 'cpp/src/platform/windows/']
]
}],
['OS=="mac"', {
"include_dirs": [ "cpp/src/platform/unix" ],
"sources": [
"cpp/hidapi/mac/hid.c",
],
"sources/": [
['exclude', 'cpp/src/platform/windows/']
],
"defines": [
"DARWIN"
]
}],
['OS=="win"', {
"include_dirs": [ "cpp/src/platform/windows" ],
"sources": [
"cpp/build/windows/winversion.cpp",
"cpp/hidapi/windows/hid.cpp",
],
"sources/": [
['exclude', 'cpp/src/platform/unix/']
]
}],
]
}
]
};



function init() {
console.log('Temp Path:', tempPath);
console.log('Install Path:', installPath);

wrench.rmdirSyncRecursive(installPath, true);
wrench.mkdirSyncRecursive(installPath);
}

function download(url, dest, cb) {
//doesn't handle error response codes
request({uri: url})
.pipe(fs.createWriteStream(dest))
.on('close', cb)
.on('error', cb);
}

function build(gypArgs, cb) {
try {
fs.unlinkSync('./cpp/build/windows/winversion.cpp');
} catch (e) { }

ChildProcess.execFile('GIT-VS-VERSION-GEN.bat',
['../../', 'winversion.cpp'],
{ cwd: './cpp/build/windows' },
function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error code: '+error.code);
console.log('Signal received: '+error.signal);
}
});

var args = ['node','.'];
if (gypArgs) {
args = args.concat(gypArgs);
}
gyp.parseArgv(args);

gyp.commands.clean([], function(err) {
if (err) return cb(err);
gyp.commands.configure([], function(err) {
if (err) return cb(err);
gyp.commands.build([], cb);
});
});
}

function copyFiles() {
wrench.copyDirSyncRecursive(tempPath + '/ozw/open-zwave-master/config', installPath + '/config');
wrench.copyDirSyncRecursive(tempPath + '/ozw/open-zwave-master/cpp/src', installPath + '/include', { filter: /^.*\.(?!h)[^.]+$/ });
wrench.copyDirSyncRecursive(tempPath + '/ozw/open-zwave-master/build/Release', installPath + '/bin');
}

function handleError(err) {
throw err;
}

module.exports = function(opts) {
if (/^win/.test(process.platform)) {
if (process.env.OZW_HOME) {
return;
}
console.log('Installing Open Z-Wave');
} else {
return; //this script only currently implements the install process for windows
}

fs.mkdirSync(tempPath);

process.chdir(tempPath);
console.log('Installing dependencies to ' + tempPath);
ChildProcess.execSync('npm install request unzip node-gyp wrench');
request = require(tempPath + '/node_modules/request');
unzip = require(tempPath + '/node_modules/unzip');
gyp = require(tempPath + '/node_modules/node-gyp')();
wrench = require(tempPath + '/node_modules/wrench');



gypOptions = opts.gyp || gypOptions;
init();
console.log('Downloading open zwave source.');

download(ozwSourceUrl, tempPath + "/ozw.zip", function(err) {
if (err) { return handleError(err); }

console.log('Extracting open zwave source.');
fs.createReadStream( tempPath + "/ozw.zip")
.pipe(unzip.Extract({ path: tempPath + '/ozw' }))
.on('close', function() {
var sources = wrench.readdirSyncRecursive(tempPath + '/ozw/open-zwave-master/cpp');
sources = sources.filter(function(f) {
return f.match(/^(src|tinyxml)/) && f.match(/\.(c|cpp)$/);
}).map(function(f) {
return 'cpp/' + f.replace(/\\\\/g, '/').replace(/\\/g, '/');
});
ozwGyp.targets[0].sources = sources;
fs.writeFile(tempPath + '/ozw/open-zwave-master/binding.gyp', JSON.stringify(ozwGyp, null, 4), function(err) {
if(err) handleError;

console.log('Building open zwave');
process.chdir(tempPath + "/ozw/open-zwave-master");
build(gypOptions, function(err) {
if (err) handleError(err);
process.chdir(originalPath);
copyFiles();
//set environment variable
ChildProcess.exec('SETX OZW_HOME "' + installPath + '"',function(error, stdout, stderr) {
//this isn't working for the build of node-ozw-shared immediately after,
//I think because it doesn't effect the parent environment, which is what propagates to npm install
process.env.OZW_HOME = installPath;
});
});
});
})
.on('error', handleError);
});
}

if (require.main === module) {
if (process.argv[2] === "--get-ozw-home") {
if (process.env.OZW_HOME) {
console.log(node.env.OZW_HOME);
} else {
console.log(installPath);
}
} else {
module.exports({ gyp: process.argv.slice(2) });
}
}
1 change: 0 additions & 1 deletion ozw-windows-install.ps1

This file was deleted.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"scripts": {
"test": "node test.js",
"preinstall": "node lib/install-ozw.js",
"install": "node-gyp rebuild"
},
"repository": {
Expand Down

0 comments on commit 82d5901

Please sign in to comment.