Click for text version
Magnus Wedberg / home

Running OpenWRT (with web UI!) on a D-Link DSP-W215 (rev B1) power plug
The problem
Do note that these instructions won't restore the cloud functionality to your plug, or the functionality of the D-Link app. These are gone forever. End of service. Not supported. Forgotten in the parking lot. However, you can still use the plug locally, or with Home Assistant or similar systems.

Tree structure
Fine by you? Let's continue! D-Link has manufactured, approximately, six bazillion different models of almost every computer-related thingamajig in the world. It's not unsurprising that one of these is a cloud-controlled power plug. It's also not surprising that I bought one of these devices when I saw it at a bargain-bin type clearance sale a couple of years ago, this actually being my first "cloud device", and the price being something like the equivalent of three sausages. Thirdly, it's not surprising that D-Link decided to pull the plug (heh) on support for this device, as cloud connected companies so often and proudly do, making the device an unusable brick when its cloud connection is shut down. There should be laws requiring devices to offer local control but I digress.

Knowing about this D-Link planned obsolescence problem I had kept my eyes on this thread, documenting the fine work by the fine people of the OpenWRT forums with hacking in an alternate firmware. I ran into a couple of problems not covered there, though, and after finally succeeding with the flash I also managed to build a self-contained web UI for the thing. These are the instructions.

The firmware flash
Generally the flashing instructions (detailed in the thread but also in the OpenWRT wiki for the device) are fine -- the device has an emergency flash procedure so you can always reflash if something goes really wrong. The factory reflash also wastes all settings so it goes back to a good, non-bricked state if you mess up your network settings.

What was not detailed there was how to connect the device to your own WiFi network and then actually accessing it. The forum thread mentions binding the WiFi client net to LAN, unfortunately that didn't work for me at all. What worked was:

  1. Set the DSP-W215 to emergency flash mode by holding the reset button while plugging it in until the small LED flashes red
  2. Connect to the unsecured DSP-W215B-xxxx WiFi network now broadcasted, and visit the web UI at
  3. Flash the "factory" firmware image from the wiki page
  4. Wait until the unit has rebooted
  5. Connect to the new, OpenWRT-initiated DSP-xxxx network now broadcasted, this needs a password, detailed on the wiki page, and then connect to the web UI at
  6. Log in to the OpenWRT system. Standard password is blank, change it to something else immediately at System/Administration
  7. Upgrade OpenWRT at System/Backup / Flash Firmware with the "sysupgrade" firmware image from the wiki page
  8. Wait until the unit has rebooted
  9. Reconnect to WiFi (same as step 5)
  10. Connect to your client WiFi:
    • Go to Network/Wireless
    • On the "Radio" line, click "Scan"
    • Join your WiFi network
    • Check "Replace wireless configuration"
    • Fill in your WiFi passphrase
    • Bind the firewall zone to "wan" (pre-filled, don't touch this)!
    • At the next screen with advanced settings, don't change anything. Do NOT change the WiFi channel!
    • Save your settings but don't apply them.
  11. Go to Network/Firewall. Open up the WAN by allowing everything (Zones/wan: accept-accept-accept). Save but do not apply.
  12. Click the arrow to the right of "Save and apply" and choose Apply unchecked (important -- otherwise the device will reset the settings!). Then click the big red button to apply.
  13. The device should now be visible on your main network. Check your DHCP server (for example, the client list in your router) for which local IP it got. You can of course also use a fixed IP.
  14. If it's not visible after a few minutes you can always start over from 1 again.

Making a web UI for the DSP-W215
Now you have OpenWRT running on the plug but that's it. You can SSH to the device and issue on/off commands (and control the LEDs) but not much else. Clearly a local, unclouded, more user friendly way of controlling it is needed. Thankfully, OpenWRT already includes all stuff we need to get this working in the form of uHTTPd and Lua, which is used anyway for running the main OpenWRT web interface LuCI.

We will put the web ui on the normal HTTP port (80) and move LuCI to port 8080. You will of course need something to interact with the system via SCP/SSH, probably WinSCP and Putty if you are on Windows.

Connect to the plug's IP address with WinSCP, using the SCP protocol, username "root" and your chosen password. Then go to /etc/config and edit the file "uhttpd". It should have one or two sections, and you will have to modify it according to your wishes to add another "config uhttpd" section; use my uHTTPd config file as a reference and add the section config uhttpd 'plug', also change LuCI's port to 8080 in the first two existing list listen_http lines, or just copy everything in my file and replace the content in your own.

After this we will have to do a couple of things to construct the UI and put bindings to command line utilities et cetera, but this is way too long to describe, suffice to say that I mucked around with LuCI's construction/how it was ran by uHTTPd and managed to construct something that is probably sub-optimal but to everyone's surprise actually works. You might have noticed a "wwwplug" path in the config file; download the zip with the web UI here and unzip everything in it, then put the resulting structure in /wwwplug (a non-existing folder you must create in the root of the device). You don't have to set any rights or anything. It should look like this:

Tree structure

We must also install an additional package. Go to System/Software, click "Update lists" and then put "uhttpd-mod-lua" in the "Filter" box and install it.

Now restart the plug. You can do this nicely from LuCI/SSH or you can just remove it from the power socket and reattach it. After booting, you can browse the normal IP address (you might have to clear your browser cache if it's still trying to redirect to LuCI) to see the on/off web UI; LuCI is now on http://your.plugs.local.ip.address:8080 (also linked at the bottom of the web UI). You should see this:

Glowing OFF symbol

Clicking the symbol might produce the following result:
Glowing ON symbol

And that's it!

Bonus, controlling the plug from other things
If you are using other systems to control plugs you can just make simple GET requests ("visit/fetch a web address") to do stuff.
turns the power on,
turns it off and
returns only 0 or 1, depending on power status, for use with some rule you might want to construct, I dunno man!

The physical power button on the device is not working, this is not my fault but (possibly) a limitation of the OpenWRT system and (certainly) the status of current research into the device.

Modifications and extra niceties

  • I am using "red button" to symbolize off, and "green button" to symbolize on, both on the actual physical device and in the web UI. If you want to change this it should be pretty self-evident from the code in /wwwplug/lua/uhttpd.lua how to do it, just edit it to remove the toggling of the red LED.
  • If you make changes in the /wwwplug/lua/uhttpd.lua file you will have to reload the uHTTPd service. You can either reboot the plug (this gets tedious) or SSH into the device and issue the /etc/init.d/uhttpd restart command after every edit (still pretty tedious). If you can't access the UI after an edit, Lua didn't parse due to a syntax error and you will have to fix that.
  • Personally I want the plug to be on when booting. You can go to System/Startup/Local Startup and put these lines in:
    • echo 1 > /sys/class/gpio/gpio:ac_output_enable/value
    • echo 255 > /sys/devices/platform/leds/leds/green:power/brightness
    • echo 0 > /sys/devices/platform/leds/leds/red:power/brightness
  • You can also use cron in OpenWRT to construct schedules for turning power on or off. Instructions for cron are out-of-scope for this article but basically you will have to do echo 1 > /sys/class/gpio/gpio:ac_output_enable/value (or echo 0 of course), et cetera, at different times and there is a web UI in LuCI for that.
  • Other hacks? Probably! Your favorite hack is probably hindered at first by there being very little space left on the boot partition, but there is a partition held in RAM that has plenty of space left, so the crafty can pull stuff from the net and put there with uclient-fetch (which is already installed, while curl and wget are a bit large), executing from the temporary RAM partition (remember that all will be lost together with the power).

photos articles services about