• Stars
    star
    132
  • Rank 265,209 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 9 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JavaScript client library for controlling and subscribing to Wemo Devices

Wemo Client for Node.js

Low-level client library for controlling recent Wemo devices including Bulbs. Supports event subscriptions to get live updates from devices.

Build Status codecov

Supported Devices

  • Wemo Switch
  • Wemo Motion
  • Wemo Insight Switch
  • Wemo Maker
  • Wemo Humidifier
  • Wemo Heater
  • Wemo Link
    • Wemo LED Bulb
    • OSRAM Lightify Flex RGBW
    • OSRAM Lightify Tunable White (untested)
    • OSRAM Gardenspot Mini RGB (untested)
  • Wemo Light Switch
  • Wemo Dimmer

Install

$ npm install wemo-client

Usage

import Wemo from 'wemo-client'
const wemo = new Wemo()

wemo.discover((err, deviceInfo) => {
  console.log('Wemo Device Found: %j', deviceInfo)

  // Get the client for the found device
  const client = wemo.client(deviceInfo)

  // You definitely want to listen to error events (e.g. device went offline),
  // Node will throw them as an exception if they are left unhandled
  client.on('error', err => {
    console.log('Error: %s', err.code)
  })

  // Handle BinaryState events
  client.on('binaryState', value => {
    console.log('Binary State changed to: %s', value)
  })

  // Turn the switch on
  client.setBinaryState(1)
})

API

Wemo

new Wemo([opts])

Create the Wemo instance. An optional object containing options can be specified. Available options include port which will provide a port to bind to for listening to UPnP events (the default is to listen on any available randomly selected port.) Discovery options for node-ssdp can also be specified as discover_opts. The listen_interface option can be used to specify which network interface to listen on. If listen_interface is not specified then by default the server will listen on all interfaces, however, Wemo subscription messages will only be sent to the first non-internal IPv4 address returned by os.networkInterfaces() after being sorted by compatible network which may or may not be what you want.

Example of options:

{
  port: 1234,
  discover_opts: {
    unicastBindPort: 1235
  },
  listen_interface: 'wlan0'
}
  • Object options Options

DEVICE_TYPE

Static map of supported models and device types.

  • Bridge
  • Switch
  • Motion
  • Maker
  • Insight
  • LightSwitch
  • Dimmer
  • Humidifier
  • HeaterB

discover(cb)

Discover Wemo devices via UPnP. A deviceInfo will be passed to cb that can be used to get a client for the device found.

  • Callback cb Callback called with for every single device found.

Due to the nature of UPnP it may be required to call this method multiple times to discover actually all devices connected to the local network.

The callback will only be called for newly found devices (those that have not been detected by a previous call to discover). Except for devices that have been lost in an error state as those will reappear again when coming back online (e.g. because their IP/port have changed).

load(setupUrl, cb)

API breaking in: v0.13

Allows to skip discovery if the setupUrl of a Wemo is already known. A deviceInfo will be passed to cb that can be used to get a client for the device found. The err field will be non-null in the event of an error.

  • String setupUrl Must point to setup.xml of the requested device (http://device_ip:device_port/setup.xml).
  • Callback cb cb(err, deviceInfo)

client(deviceInfo)

Get a single instance of WemoClient for the device specified by deviceInfo.

  • Object deviceInfo The deviceInfo as returned by the discovery.

WemoClient

Event: error (err)

An error occured while handling the event subscriptions or calling a device action. When err.code is one of ECONNREFUSED, EHOSTUNREACH or ETIMEDOUT the device likely went offline.

  • Object err

When using any subscriptions, make sure to also listen to error events. Node will throw an exception if error events are left unhandled. See also: Building Robust Node Applications: Error Handling

Event: binaryState (value)

Binary state of a device has been updated, e.g. a motion sensor detected motion or a plug is switched on.

  • String value The state of the binary switch/sensor. 1 = on/closed/motion, 0 = off/open/quiet
client.on('binaryState', value => {
  console.log('Device turned %s', value === '1' ? 'on' : 'off')
})

Event: statusChange (deviceId, capabilityId, value)

Capability of a device connected via Wemo Bridge changed its status.

  • String deviceId Id of the device connected to the bridge
  • String capabilityId Capability
  • String value Status

Event: attributeList (name, value, prevalue, timestamp)

Attribute of a device has changed. This applies to Wemo Maker, Wemo Humidifier, and Wemo Heater (may not be exhaustive).

  • String name Name of the attribute, e.g. Switch
  • String value Current value
  • String prevalue Previous value
  • String timestamp Timestamp of the change

Event: insightParams (binaryState, instantPower, data)

Wemo Insight Switch sent new power consumption data.

  • String binaryState 1 = on, 0 = off, 8 = standby
  • String instantPower Current power consumption in mW
  • Object data Aggregated usage data

endDeviceInfos = await client.getEndDevices()

Get bulbs connected to a Wemo Bridge. An endDeviceInfo for every device paired is returned as an array, e.g.:

[{
  friendlyName: 'Color Bulb',
  deviceId: 'EA103EA2B2782FFF',
  capabilities: {
    '10006': '1',
    '10008': '121:0'
  },
  deviceType: 'dimmableLight'
}]

Device groups are treated as if they were single devices – a sole endDeviceInfo is returned per group.

Notice: The capabilities property may represent outdated values due to some odd behavior of the device API. Please refer to getDeviceStatus or Event: statusChange to obtain the current state of the device.

const state = client.getBinaryState()

Get the device's binary state.

The state (1 = on, 0 = off).

response = await client.setBinaryState(value)

Turn the device on or off. Will also cause a binaryState event to be triggered.

  • String value 1 = on, 0 = off

brightness = await client.getBrightness()

Get the device's brightness level (0 - 100).

response = await client.setBrightness(value)

Set the device brightness level. Will also cause a binaryState event to be triggered.

  • Integer value 1 - 100

attributes = await client.getAttributes()

Get the device attributes of a Wemo Maker.

deviceStatus = await client.getDeviceStatus(deviceId)

Gets the device Status of a device connected via Wemo Bridge, e.g. a bulb.

  • String deviceId Id of the device connected to the bridge (determined by calling getEndDevices)

The deviceStatus is a map of device capabilities and values, e.g.:

{
  '10006': '1', // on = 1, off = 0, offline = empty
  '10008': '121:0', // brightness 0-255
  '30008': '0:0', // no sleep timer active
  '30009': '', // unknown
  '3000A': '' // unknown
}

response = await client.setDeviceStatus(deviceId, capability, value)

Controls a capability of a device connected via Wemo Bridge, e.g. a bulb.

  • String deviceId Id of the device connected to the bridge (determined by calling getEndDevices)
  • String capability Capability
  • String value Value

Known capabilities (depends on device):

  • 10006 Turn bulb on/off. Values: 1 = on, 0 = off
  • 10008 Dim bulb. Value: brightness:transition_time, where brightness = 0-255
  • 30008 Sleep timer. Value: seconds*10:current_unixtime
  • 10300 Color. Value: X:Y:transistion_time
  • 30301 Color Temperature. Value: ct:transition_time, where ct = 170-370

response = await client.setLightColor(deviceId, red, green, blue)

Convenience function for setting the color of a RGB light.

  • String deviceId Id of the light connected to the bridge (determined by calling getEndDevices)
  • Number red 0-255
  • Number green 0-255
  • Number blue 0-255

const insight = await client.getInsightParams()

Get power consumption data for a Wemo Insight Switch

awiat client.setAttributes(attributes)

Sets attributes on a device (Heater, Humidifier), used for setting FanMode, Mode, TimeRemaining, and SetTemperature (not exhaustive) to a value.

  • Object attributes
{
  SetTemperature: '73.0',
  TimeRemaining: '120'
}

You can set any number of attributes in this manner, and if you do not specify an attribute, it is left unchanged on the device.

Debugging

Wemo Client uses debug, so just run with environmental variable DEBUG set to wemo-client.

$ env DEBUG=wemo-client node examples/index.js

Known Issues

There are some quirks and oddities to be aware of when working with the devices supported by this library.

General

  • The deviceInfo returned from the discovery may contain a device state property (e.g. binaryState) which has an outdated value most of the time. Just don't use it.

Wemo Link

  • The capabilities property of the endDeviceInfo may represent outdated values. Please use the getDeviceStatus method or subscribe to statusChange events to obtain the current state of the device.

  • Setting capability 10008 (level/brightness) to > 0 will turn the light on, but won't update capability 10006 (on/off). In other words, a light turned on by dimming it, will still be reported as off by the deviceStatus.

  • Setting capability 10008 to 0 will turn the light off, but won't cause any update of the deviceStatus. That is the light will still be reported as on and dimmed.

Contributing

Contributions are very welcome! Please note that by submitting a pull request for this project, you agree to license your contribution under the MIT License to this project.

Credits

Credit goes to Ben Hardill for his research on Belkin Wemo devices.

License

Published under the MIT License.

More Repositories

1

StreamSaver.js

StreamSaver writes stream to the filesystem directly asynchronous
JavaScript
3,873
star
2

native-file-system-adapter

File system, based on the spec reference implementation
JavaScript
446
star
3

FormData

HTML5 `FormData` polyfill for Browsers and nodejs
JavaScript
359
star
4

ofc

Online font converter
CSS
133
star
5

webtorrent-server-browser

test torrent.createServer using service worker
JavaScript
21
star
6

Screw-FileReader

For those who don't like the FileReader
JavaScript
21
star
7

you-might-not-need-typescript

Goes to show how much i don't want to use typescript
HTML
20
star
8

ga-api

Google Analytics API access
JavaScript
16
star
9

fetch-headers

fetch headers polyfill
JavaScript
14
star
10

not-a-log

A tiny console interface that returns everything as a string
JavaScript
12
star
11

node-domexception

An implementation of the DOMException class from NodeJS
JavaScript
9
star
12

cache-polyfill

cache polyfill, Offline storage, Wraps IndexedDB, without https/ssl
JavaScript
9
star
13

browser-su

JavaScript
8
star
14

lazy-resolver

Skip hoops with promises, make async code sync-ish looking (it is still async)
JavaScript
7
star
15

fetch-event

FetchEvent outside Service Worker
JavaScript
3
star
16

zip-go

Small, zero dependent, cross friendly zip tool
JavaScript
3
star
17

stream-consumers

a user-land copy of the node:stream/consumers library from Node.js
JavaScript
3
star
18

to-uint8array

Convert anything to Uint8Array without a copy
JavaScript
3
star
19

await-sync

Perform async work synchronously using web worker and SharedArrayBuffer
JavaScript
3
star
20

fetch-cachestorage

html5 CacheStorage for node
JavaScript
2
star
21

3th-party-structured-clone-wpt

JavaScript
2
star
22

update-notifier-go

Minimal dependency free update notifier
JavaScript
1
star
23

missing-dom-events

The missing DOM events for backends that doesn't support them
JavaScript
1
star
24

highlight-saas

Highlight.js as a service
HTML
1
star
25

mediquerie

Angular directive that allows you to use css media query on any element
JavaScript
1
star
26

abortcontroller

AbortController for node
JavaScript
1
star
27

diezyweb

Take a different look at your hard drive with your browser
JavaScript
1
star
28

itty-compressor

A tiny compression library that leverages (De)CompressionStream and Response
JavaScript
1
star
29

sw-renderer

Offline first streaming ES6 template engine
HTML
1
star
30

groupby-polyfill

small zero dependent polyfill for `Object.groupBy` and `Map.groupBy`
JavaScript
1
star