wms-js v0.0.3
WMS-JS
A JavaScript interface to a Warema WMS network using a Warema WMS Stick.
Usage
import {SerialPort} from "serialport";
import WaremaWMS from "./lib/WaremaWMS.js";
import WaremaWMSFrameHandler from "./lib/WaremaWMSFrameHandler.js";
const port = new SerialPort({
path: '/dev/ttyUSB0',
baudRate: 128000,
})
const wms = new WaremaWMS(port);
console.log(wms.getName());
console.log(wms.getVersion());
console.log(await wms.configureNetwork(11, 'ABCD'));
console.log(await wms.configureEncryptionKey('012345678ABCDEF012345678ABCDEF01'));
wms.frameHandler.on(WaremaWMSFrameHandler.MESSAGE_TYPE_BROADCAST_WEATHER, console.log);
wms.frameHandler.on(WaremaWMSFrameHandler.MESSAGE_TYPE_BROADCAST_NETWORK_PARAMETERS_CHANGE, console.log);
wms.frameHandler.on(WaremaWMSFrameHandler.MESSAGE_TYPE_SCAN_REQUEST, console.log);
wms.frameHandler.on(WaremaWMSFrameHandler.MESSAGE_TYPE_NETWORK_JOIN, console.log);
console.log(await wms.wave('ABCDEF'));
console.log(await wms.getDeviceStatus('ABCDEF'));
console.log(await wms.moveToPosition('ABCDEF', 50, 0));
console.log(await wms.stop('ABCDEF'));
wms.frameHandler.on(WaremaWMSFrameHandler.MESSAGE_TYPE_SCAN_RESPONSE, console.log);
console.log(await wms.scan('ABCD'));Protocol details
The protocol has been reversed by some kind folks from the IoBroker forum. Additional information is available from the warema-wms-venetian-blinds npm package.
The radio communication is encrypted, the USB stick takes care of all the encryption details, and provides a serial interface that can be easily used to communicate with the WMS network.
Frame structure
Frames are the basic unit of communication with the USB stick. Frames are enclosed in curly braces, and the first character defines the frame type and the direction (uppercase -> host to USB, lowercase -> USB to host).
-> {G}
<- {gWMS USB-Stick}
-> {V}
<- {v12345678 }
-> {R01ABCDEF7021FFFF02}
<- {rABCDEF7080000010FFFFFFFAC8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}Frames, regardless of their direction, might include a payload. The payload might contain information from the USB stick to the host, configuration for the USB stick, or messages to/from the network.
The following frame types are known:
| Frame type | Content |
|---|---|
G/g | Stick name request/response |
V/v | Stick version request/response |
R/r | Network message request/response |
M | Stick network parameters configuration |
K | Stick network encryption key configuration |
a | Stick ACK |
Stick name request/response
-> {G}
<- {gWMS USB-Stick}Stick version request/response
-> {V}
<- {v XXXXXXXX ___}XXXXXXXXis the version reported by the stick. It's not known whether there are multiple versions, or if it's possible to upgrade___are blank spaces in the response
Stick network parameters configuration
-> {M X CC PPPP}
<- {a}Xcan be either%or#, depending on whether we want to receive network broadcast messages, or not.CCis the channel number, between11and26PPPPis the PAN ID, between0000andFFFF
Stick network encryption key configuration
-> {K 401 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}
<- {a}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32-character, hex encryption key
Network message request/response
-> {R TT XXXXXX YYYY ZZZ[...]}
<- {r XXXXXX YYYY ZZZ[...]}TTis some kind of type identifier added to outgoing messages onlyXXXXXXis the source serial numberYYYYis the message typeZZZ[...]is the message payload
Network message structure
Messages contain data travelling between devices of the WMS network.
Messages are embedded within R/r frames, and can be of different types.
The following message types are known:
| Message type | Content |
|---|---|
5060 | Change network parameters broadcast |
50AC | ACK from device |
7020/7021 | Scan request/response |
7050/7051 | Wave request/response |
7080 | Weather station broadcast |
7070/7071 | Device move to position request/response |
8010/8011 | Device status request/response |
Weather station broadcast
<- {r XXXXXX 7080 YY WW L1 ZZZZZZ L2 xx RR TT yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy}
// the followings are actual message received from 2 different weather stations
r ABCDEF 7080 00 00 10 FFFFFF FA C8 FF FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
r ABCDEF 7080 00 01 1A FFFFFF FA C8 FF FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
r ABCDEF 7080 00 00 00 FFFFFF 00 C7 FF FF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFYYunknownWWwind speed (hex)L1illuminance 1, needs processingZZZZZZunknownL2illuminance 2, needs processingxxunknownRRrain (00= no rain,C8= rain)TTtemperature, needs processingyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyunknown
According to the forum, the following post-processing is needed:
- temperature: convert to dec, divide by 2, and subtract 35
- illuminance
- if
L1is00, the illuminance value isL2, converted to dec, multiplied by 2 - otherwise, convert both
L1andL2to dec, multiply them and then multiply by 2
- if
Given the mismatch between the documentation and the sample messages, only wind speed is currently implemented
Wave request/response
-> {R06 XXXXXX 7050}
<- {a}
<- {r XXXXXX 50AC YYYY}
// real world examples
r ABCDEF 50AC 88ED
r ABCDEF 50AC CDD6
r ABCDEF 50AC B043
---
<- {r XXXXXX 7050}XXXXXXserial number of the source deviceYYYYunknown - changes with every request
Device status request/response
-> {R06 XXXXXX 8010 01000005}
<- {a}
<- {r XXXXXX 8011 010000 TT PP WW V1 V2 MM}
// real world examples
r ABCDEF 8011 010000 05 00 FF FF FF 00
r ABCDEF 8011 010000 05 14 FF FF FF 01
r ABCDEF 8011 010000 05 1D FF FF FF 01
r ABCDEF 8011 010000 05 36 FF FF FF 00XXXXXXserial number of the target deviceTTdevice type.03and05seen in the wild.05seems to be theWMS Plug receiverPPposition (hex)WWinclination (hex)V1valance 1V2valance 2MMstatus of the device:00for a stopped device,01for a device that is moving
Given the lack of test devices, valance is currently not implemented
The 01000005 string in the request and 010000 in the response has no known meaning.
Move to position request/response
-> {R06 XXXXXX 7070 CC} (for CC == 01)
-> {R06 XXXXXX 7070 CC PP WW V1 V2} (for CC == 03)
<- {a}
<- {r XXXXXX 7071 0010023F02 pp ww FFFF0C0DFFFF}
// real world examples
r ABCDEF 7071 0010023F02 96 7F FFFF0CFFFFFF
r ABCDEF 7071 0010023F02 C8 7F FFFF0CFFFFFF
r ABCDEF 7071 0010023F02 64 7F FFFF0CFFFFFFXXXXXXserial number of the target deviceCCcommand01stop moving03move to position
PPposition (hex)WWinclination (hex)V1valance 1V2valance 2ppprevious target position (hex)wwprevious target inclination (hex)
Change network parameters broadcast
This message is sent during device discovery, when linking a remote to a device.
<- {r XXXXXX 5060 PPPP 02 CC 00}XXXXXXserial number of the source devicePPPPPAN IDCCchannel (hex)
Received scan request/response
<- {r XXXXXX 7020 PPPP 02}
-> {R01 XXXXXX 7021 PPPP 02}XXXXXXserial number of the source devicePPPPPAN ID
Send scan request/response
-> {R04 XXXXXX 7020 PPPP TT}
<- {a}
<- {r XXXXXX 7021 PPPP TT UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU}XXXXXXserial number of the source device (should beFFFFFFwhen sending a scan request)PPPPPAN IDTTdevice typeUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUunknown
Network join request
<- {r XXXXXX 5018 PPPP KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK FF CC}XXXXXXserial number of the source devicePPPPPAN IDKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKnetwork encryption key (reversed)CCchannel (hex)
Notes about hex-encoded fields
Some of the fields in the messages need to be converted to be properly usable.
- Channel: Convert to base 10
- Inclination: Convert to base 10 and subtract 127
- Network encryption key: Reverse (
ABCDEFshould becomeEFCDAB) - Position: Convert to base 10 and divide by 2 to have a 0-100 value. 0 means fully retracted
- Wind speed: Convert to base 10