D-link smart plug DSP-W215 with Openhab

Tutorial on how to make the smart plug from d-link dsp-w215 controllable from other than the official dlink application. In this case Openhab but should be possible to integrate it in any other application. Following tutorial is for linux. But with slight modification should be possible to use on windows as well (NODEJS is multiplatform).

Big thanks to bikerp – github

What i did:

  • Download the code from bikerp github page.
  • Edit the code of app.js as follows to be able to use it with exec binding in openhab. (For Openhab2 allow installation of EXEC for version 1. I have no idea how to work with the EXEC 2 yet. ) You have to put your PIN_CODE and IP of the DSP plug.
var soapclient = require('./js/soapclient');
var fs = require('fs');
var OUTPUT_FILE = "result.txt";
var LOGIN_USER = "admin";
var LOGIN_PWD = "PIN_CODE";
var HNAP_URL = "http://IP_OF_DSP/HNAP1";
var POLLING_INTERVAL = 60000;

var args = process.argv.slice(2);

soapclient.login(LOGIN_USER, LOGIN_PWD, HNAP_URL).done(function (status) {
 if (!status) {
   throw "Login failed!";
 }
 if (status != "success") {
   throw "Login failed!";
 }
 if (args == "on") {
   soapclient.on();
 }
 if (args == "off"){
   soapclient.off();
 }
 if (args == "power"){
   soapclient.consumption().done(function (power) {console.log(power);});
 }
 if (args == "total"){
   soapclient.totalConsumption().done(function (power) {console.log(power);});
 }
 if (args == "temp"){
  soapclient.temperature().done(function (temperature) {console.log(temperature);});
 }
 if (args == "state"){
  soapclient.state().done(function (state) {
   if(state == "true"){
    console.log("ON");
   } else {
    console.log("OFF");
   }
  });;
 }
});
  • You will also need to have installed NODEJS to be able to run javascript from terminal.
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
  • Run “npm install” inside directory with package.json and app.js . This will install locally all needed modules.
  • Set the items in openhab. In here you can see settings for switch has 1 input value and two outputs. Two outputs from openhab are simply ON and OFF. Input check every 10 seconds the actual state of the switch in case power plug was turned off by button.
  • In the following items file /usr/share/openhab/dlink_dsp/ is the path where i unzipped content from bikerp github.
Group    DSPW215_group    "Dlink Plug"    <poweroutlet>
Group    DSPW215_stats
Switch    DSPW215    "Plug switch"    <poweroutlet>    (DSPW215_group)        { exec="<[/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js state:30000:REGEX((.*?))] >[ON:/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js on] >[OFF:/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js off]" }
Number    DSPW215_power    "Plug current [%.2f W]"    <chart>    (DSPW215_group,DSPW215_stats)        { exec="<[/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js power:90000:REGEX((.*?))]" }
Number    DSPW215_total    "Plug total [%.2f KWh]"    <chart>    (DSPW215_group,DSPW215_stats)        { exec="<[/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js total:90000:REGEX((.*?))]" }
Number    DSPW215_temperature    "Plug Temperature: [%.2f C]"    <temperature>    (DSPW215_group)        { exec="<[/bin/sh@@-c@@cd /etc/openhab2/dlink_dsp/;node app.js temp:60000:REGEX((.*?))]" }
  • And the sitemap file
sitemap default label="My Home" {
  Frame label="Living room" {
    Group item=DSPW215_group
  }
}
  • Result on the Web page (additionally you can use charts and rules to make timer control)

Here is timer.rules if you wish to use the timer function.
It might need some improvement. Let me know if you think of something.

import org.joda.time.*
import org.openhab.model.script.actions.Timer
import org.openhab.core.library.types.*


var Timer masterAlarmTime = null
var Timer masterAlarmTimeOFF = null

rule "Initialize DSPW215 items"
when
    System started
then
    Alarm_DSPW215TimeMins.state
end

rule "DSPW215 alarm time"
when
    Item Alarm_DSPW215TimeMins received update or
    Item Alarm_DSPW215TimeMinsOFF received update
then
    var int minutes = (Alarm_DSPW215TimeMins.state as DecimalType).intValue()
    var int minutesOFF = (Alarm_DSPW215TimeMinsOFF.state as DecimalType).intValue()

    if (masterAlarmTime != null)
        masterAlarmTime.cancel()
    if (masterAlarmTimeOFF != null)
        masterAlarmTimeOFF.cancel()

    // work out when the alarm is to fire - start from midnight
    var DateTime alarmTime = new DateTime()

    // add the number of minutes selected
    alarmTime = alarmTime.plusMinutes(minutes)

    // create a timer to execute the alarm at the specified time
    masterAlarmTime = createTimer(alarmTime) [| 
        if (Alarm_DSPW215.state == ON) 
            Alarm_DSPW215Event.sendCommand(ON)
    ]
    Alarm_DSPW215Time.sendCommand(String::format("%02d:%02d", alarmTime.getHourOfDay(), alarmTime.getMinuteOfHour()))
    
    //To turn off
    var DateTime alarmTimeOFF = alarmTime.plusMinutes(minutesOFF+5)

    masterAlarmTimeOFF = createTimer(alarmTimeOFF) [| 
        if (Alarm_DSPW215.state == ON) 
            Alarm_DSPW215Event.sendCommand(OFF)
    ]

    // update the alarm display time    
    Alarm_DSPW215TimeOFF.sendCommand(String::format("%02d:%02d", alarmTimeOFF.getHourOfDay(), alarmTimeOFF.getMinuteOfHour()))
end

rule "DSPW215 alarm"
when
    Item Alarm_DSPW215Event received command ON
then
    DSPW215.sendCommand(ON)
end

rule "DSPW215 alarm OFF"
when
    Item Alarm_DSPW215Event received command OFF
then
    DSPW215.sendCommand(OFF)
    Alarm_DSPW215.sendCommand(OFF)
end

Leave a Reply

Your email address will not be published. Required fields are marked *