Skip to content

Commit

Permalink
added more typings (#17)
Browse files Browse the repository at this point in the history
version 1.0.5

- added typings of config and commands
- fixed #15 and #16
- updated dependencies
  • Loading branch information
AirBorne04 authored Sep 18, 2018
1 parent 027595e commit a0f59a8
Show file tree
Hide file tree
Showing 36 changed files with 680 additions and 235 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules/
.idea/
/testing
/.vscode
/examples-build
5 changes: 5 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Copyright (c) 2018 Daniel Freese

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 changes: 9 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# harmonyhub

`harmonyhub` is a Node.JS library which wants to consolidate functions around interaction with a Logitech Harmony Hub from various different libraries from the community (the original authors and repos can be found in the Readme of each of the contained packages).
The library contains the following packages:
1. [client](/packages/client) (interacting with the hub)
2. [discover](/packages/discover) (find a hub in your network)

Package | Status
------------ | -------------
[client](/packages/client) (interacting with the hub) | [![npm](https://img.shields.io/npm/v/%40harmonyhub/client.svg)](https://npmjs.com/%40harmonyhub%2Fclient) [![npm](https://img.shields.io/npm/dw/%40harmonyhub%2Fclient.svg)](https://npmjs.com/%40harmonyhub%2Fclient)
[discover](/packages/discover) (find a hub in your network) | [![npm](https://img.shields.io/npm/v/%40harmonyhub/discover.svg)](https://npmjs.com/%40harmonyhub%2Fdiscover) [![npm](https://img.shields.io/npm/dw/%40harmonyhub%2Fdiscover.svg)](https://npmjs.com/%40harmonyhub%2Fdiscover)

I recommend to use typescript since this helps to use this code without digging to much into the documentation in code :)

## Installation
```bash
Expand All @@ -17,13 +21,5 @@ Development efforts are integrated with the `develop` branch first. Changes get

Thank you for your contribution!


## License

Copyright (c) 2018

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## User base
The library is currently used in the [node-red-contrib-harmony](https://github.com/Aietes/node-red-contrib-harmony) by [aietes](https://github.com/Aietes) through which some bugs could be discovered and fixed!
35 changes: 35 additions & 0 deletions examples/client/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
var getHarmonyClient = require("../../packages/client/dist").getHarmonyClient;

function test() {
getHarmonyClient('192.168.0.31').then(
(harmonyClient) => {
return harmonyClient.getAvailableCommands().then((commands) => {

// Look for the first device and pick its "power" control group, pick
// there the "poweron" function and trigger it:
var device = commands.device[0];

var powerControls = device.controlGroup
.filter(function (group) { return group.name.toLowerCase() === 'power' })
.pop();

var powerOnFunction = powerControls['function']
.filter(function (action) { return action.name.toLowerCase() === 'poweron' })
.pop();

if (powerOnFunction) {
var encodedAction = powerOnFunction.action.replace(/\:/g, '::');
harmonyClient.send('holdAction', 'action=' + encodedAction + ':status=press');
} else {
throw new Error('could not find poweron function of first device :(');
}
})
.then( () => harmonyClient.end() );
})
.catch(
(err) => console.log(err)
);
}

test();

24 changes: 24 additions & 0 deletions examples/client/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { getHarmonyClient } from "../../packages/client/dist";

async function run(): Promise<void> {
const harmonyClient = await getHarmonyClient("192.168.0.31");

const encodedAction = `{"command"::"VolumeUp","type"::"IRCommand","deviceId"::"27633596"}`;
const dt_press = `action=${encodedAction}:status=press`;
const dt_release = `action=${encodedAction}:status=release`;

try {
const commands = await harmonyClient.getAvailableCommands();
console.log('commands', commands);
await harmonyClient.send('holdAction', dt_press);
await harmonyClient.send('holdAction', dt_release);

harmonyClient.end();
} catch(error) {
console.error('Error', error.message);
}
}

run().catch(
err => console.log(err)
);
30 changes: 30 additions & 0 deletions examples/client/example_es6.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var getHarmonyClient = require("../../packages/client/dist").getHarmonyClient;

async function testAsync() {
var harmonyClient = await getHarmonyClient('192.168.0.31');

var commands = await harmonyClient.getAvailableCommands();

// Look for the first device and pick its "power" control group, pick
// there the "poweron" function and trigger it:
var device = commands.device[0];

var powerControls = device.controlGroup
.filter(function (group) { return group.name.toLowerCase() === 'power' })
.pop();

var powerOnFunction = powerControls['function']
.filter(function (action) { return action.name.toLowerCase() === 'poweron' })
.pop();

if (powerOnFunction) {
var encodedAction = powerOnFunction.action.replace(/\:/g, '::');
harmonyClient.send('holdAction', 'action=' + encodedAction + ':status=press');
} else {
throw new Error('could not find poweron function of first device :(');
}
}

testAsync().catch(
err => console.log(err)
);
26 changes: 26 additions & 0 deletions examples/discover/example.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
var Explorer = require("../../packages/discover/dist").Explorer;

const discover = new Explorer(51000);

console.log(
Explorer.Events
);

discover.on(Explorer.Events.ONLINE, function (hub) {
console.log(hub);
console.log('discovered ' + hub.ip);
});

discover.on(Explorer.Events.OFFLINE, function (hub) {
console.log('lost ' + hub.ip);
});

discover.on(Explorer.Events.UPDATE, function (hubs) {
const knownHubIps = hubs.reduce(function (prev, hub) {
return prev + (prev.length > 0 ? ', ' : '') + hub.ip;
}, '');

console.log('known ips: ' + knownHubIps);
});

discover.start();
26 changes: 26 additions & 0 deletions examples/discover/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Explorer, HubData } from "../../packages/discover/dist";

const discover = new Explorer(51000);

console.log(
Explorer.Events
);

discover.on(Explorer.Events.ONLINE, function (hub: HubData) {
console.log(hub);
console.log('discovered ' + hub.ip);
});

discover.on(Explorer.Events.OFFLINE, function (hub: HubData) {
console.log('lost ' + hub.ip);
});

discover.on(Explorer.Events.UPDATE, function (hubs: Array<HubData>) {
const knownHubIps = hubs.reduce(function (prev, hub) {
return prev + (prev.length > 0 ? ', ' : '') + hub.ip;
}, '');

console.log('known ips: ' + knownHubIps);
});

discover.start();
8 changes: 7 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "index.js",
"dependencies": {},
"devDependencies": {
"@types/node": "^4.2.23",
"chai": "^4.1.2",
"mocha": "^5.2.0",
"typescript": "^2.7"
Expand All @@ -14,7 +15,8 @@
"build:client": "cd packages/client && tsc",
"build:discover": "cd packages/discover && tsc",
"build:homebridge": "cd packages/homebridge && tsc",
"build": "npm run build:discover && npm run build:client",
"build:examples": "tsc",
"build": "npm run build:discover && npm run build:client && npm run build:examples",
"postinstall": "(cd packages/client/ && npm install) && (cd ../../packages/discover/ && npm install)"
},
"repository": {
Expand All @@ -25,7 +27,9 @@
"harmony",
"harmonyhub",
"api",
"xmpp"
"xmpp",
"discover",
"home automation"
],
"author": "Daniel Freese",
"license": "ISC",
Expand Down
2 changes: 1 addition & 1 deletion packages/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Enhancements over the harmonyhubjs-client package are the following
* update of dependencies to newer packages (0 security issues by npm audit)
* incorporation of [@patters](https://github.com/patters) bug fix of [MAX_CLIENTS=6 error](https://github.com/swissmanu/harmonyhubjs-client/pull/43)

## Usage
## Usage
```javascript
var harmony = require('@harmonyhub/client').getHarmonyClient;

Expand Down
90 changes: 74 additions & 16 deletions packages/client/dist/harmonyclient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { EventEmitter } from "events";
* @param xmppClient
*/
export declare class HarmonyClient extends EventEmitter {
_xmppClient: any;
_responseHandlerQueue: Array<any>;
private _xmppClient;
private _responseHandlerQueue;
constructor(xmppClient: any);
handleStanza(stanza: any): void;
private handleStanza;
/**
* The state digest is caused by the hub to let clients know about remote updates
* @param {message} stateDigest
Expand All @@ -17,13 +17,13 @@ export declare class HarmonyClient extends EventEmitter {
/**
* Returns the latest turned on activity from a hub.
*
* @returns Promise
* @returns Promise<string>
*/
getCurrentActivity(): Promise<{}>;
getCurrentActivity(): Promise<string>;
/**
* Retrieves a list with all available activities.
*/
getActivities(): Promise<{}>;
getActivities(): Promise<HarmonyClient.ActivityDescription[]>;
/**
* Starts an activity with the given id.
*/
Expand All @@ -36,20 +36,20 @@ export declare class HarmonyClient extends EventEmitter {
* Checks if the hub has now activity turned on. This is implemented by checking the hubs current activity. If the
* activities id is equal to -1, no activity is on currently.
*/
isOff(): Promise<{}>;
isOff(): Promise<boolean>;
/**
* Acquires all available commands from the hub when resolving the returned promise.
*/
getAvailableCommands(): Promise<{}>;
getAvailableCommands(): Promise<HarmonyClient.ConfigDescription>;
/**
* Builds an IQ stanza containing a specific command with given body, ready to send to the hub.
*
* @param command
* @param body
* @returns {Stanza}
*/
buildCommandIqStanza(command: string, body: string): any;
defaultCanHandleStanzaPredicate(awaitedId: string, stanza: any): boolean;
private buildCommandIqStanza;
private defaultCanHandleStanzaPredicate;
/**
* Sends a command with the given body to the hub. The returned promise gets resolved as soon as a response for this
* very request arrives.
Expand All @@ -66,16 +66,74 @@ export declare class HarmonyClient extends EventEmitter {
* @param expectedResponseType
* @param canHandleStanzaPredicate
*/
request(command: string, body?: any, expectedResponseType?: string, canHandleStanzaPredicate?: (string: any) => boolean): Promise<{}>;
private request;
/**
* Sends a command with given body to the hub. The returned promise gets immediately resolved since this function does
* not expect any specific response from the hub.
* Sends a command with given body to the hub. The returned promise gets resolved
* with a generic hub response without any content or error (eg. device not existing).
*/
send(command: string, body: string): Promise<{}>;
send(action: string, body: string | {
command: string;
deviceId: string;
type?: string;
}): Promise<{}>;
/**
* Closes the connection the the hub. You have to create a new client if you would like to communicate again with the
* hub.
* Closes the connection the the hub. You have to create a new client if you would like
* to communicate again with the hub.
*/
end(): void;
}
export declare namespace HarmonyClient {
enum Events {
STATE_DIGEST = "stateDigest"
}
class ConfigDescription {
activity: Array<ActivityDescription>;
device: Array<DeviceDescription>;
}
class ActivityDescription {
id: string;
type: string;
label: string;
isTuningDefault?: boolean;
activityTypeDisplayName: string;
rules: Array<any>;
activityOrder?: number;
KeyboardTextEntryActivityRole?: string;
ChannelChangingActivityRole?: string;
VolumeActivityRole?: string;
enterActions: Array<any>;
fixit: Array<any>;
zones?: any;
suggestedDisplay: string;
isAVActivity: boolean;
sequences: Array<any>;
controlGroup: Array<any>;
roles: Array<any>;
isMultiZone?: boolean;
icon: string;
baseImageUri?: string;
imageKey?: string;
}
class DeviceDescription {
label: string;
deviceAddedDate: string;
ControlPort: number;
contentProfileKey: number;
deviceProfileUri: string;
manufacturer: string;
icon: string;
suggestedDisplay: string;
deviceTypeDisplayName: string;
powerFeatures: Array<any>;
Capabilities: Array<any>;
controlGroup: Array<any>;
DongleRFID: number;
IsKeyboardAssociated: boolean;
model: string;
type: string;
id: string;
Transport: number;
isManualPower: boolean;
}
}
export default HarmonyClient;
Loading

0 comments on commit a0f59a8

Please sign in to comment.