Info
This post is a part of a bigger project. You can read about it all here:
Physical controls of IKEA Idasen standing desk allow it to move up and down, but lack the ability to save any positions. While it is possible to connect via Bluetooth and save favourite heights in the app, switching between them requires us to still tap and hold the button there. The desk stops moving when button is released. I’m not sure what dictated that design decision, as the desk is capable of detecting obstructions and can stop itself from moving even if the user is still pressing the controls (don’t ask me how I know this). I would therefore like to just press the button once and let the desk do its thing. This got me thinking if there are any hackable solutions out there, and indeed there’s even more than one.
Introducing:
Name | Link |
---|---|
idasen-controller | https://github.com/rhyst/idasen-controller |
idasen | https://github.com/newAM/idasen |
esphome-idasen-desk-controller | https://github.com/j5lien/esphome-idasen-desk-controller |
Kudos to their creators. I chose to use the first one, idasen-controller.
I have a spare Raspberry Pi 3B+, which I’ll be using later to setup AirPlay streaming in my office, so I may as well use it for controlling my desk. I’m also planning to tie it all together with a nice Numpad controller, inspired by this YouTube video from David Zhang. Stay tuned!
I’m using the official distribution based on Debian 11 (Bullseye), specifically the x64 lite variant without desktop environment - Raspberry Pi OS Lite x64. I initially tried to set it up with Ubuntu Server, but I couldn’t get Bluetooth working reliably (it’s a real PITA sometimes). I didn’t want to sink more hours into this project (I have other things to do! 😝), so I reverted to official Raspberry Pi OS distribution. It works there.
Connecting via Bluetooth from Raspberry Pi
It’s quick and simple (when it works).
First, run bluetoothctl
. You should see an active Bluetooth adapter / controller and the prompt will change to [bluetooth]#
:
$ bluetoothctl
Agent registered
[CHG] Controller B8:27:EB:XX:XX:XX Pairable: yes
[bluetooth]#
At this point, you need to put the desk controller in pairing mode. Hold the Bluetooth pairing button until its blue LED starts rapidly flashing. Now we can scan for devices with:
[bluetooth]# scan on
Discovery started
[CHG] Controller B8:27:EB:XX:XX:XX Discovering: yes
[NEW] Device FA:A1:63:XX:XX:XX Desk 7372
[NEW] Device 71:66:5F:XX:XX:XX 71-66-5F-XX-XX-XX
[NEW] Device 5F:DD:10:XX:XX:XX 5F-DD-10-XX-XX-XX
[NEW] Device 68:D9:74:XX:XX:XX 68-D9-74-XX-XX-XX
[NEW] Device 44:B9:01:XX:XX:XX 44-B9-01-XX-XX-XX
[NEW] Device 5D:58:CF:XX:XX:XX 5D-58-CF-XX-XX-XX
[NEW] Device 3C:85:15:XX:XX:XX 3C-85-15-XX-XX-XX
[NEW] Device 39:EA:4A:XX:XX:XX 39-EA-4A-XX-XX-XX
[NEW] Device 68:43:7A:XX:XX:XX 68-43-7A-XX-XX-XX
[NEW] Device 3A:DB:B8:XX:XX:XX 3A-DB-B8-XX-XX-XX
[NEW] Device 40:6F:47:XX:XX:XX 40-6F-47-XX-XX-XX
[NEW] Device 67:8C:1C:XX:XX:XX 67-8C-1C-XX-XX-XX
[CHG] Device 39:EA:4A:XX:XX:XX ManufacturerData Key: 0x004c
[CHG] Device 39:EA:4A:XX:XX:XX ManufacturerData Value:
09 06 03 e1 c0 a8 0a dc ........
[CHG] Device 5F:DD:10:XX:XX:XX RSSI: -31
[CHG] Device 68:43:7A:XX:XX:XX RSSI: -78
[CHG] Device 40:6F:47:XX:XX:XX RSSI: -82
[bluetooth]#
We need to grab the MAC address of the desk controller, in this case it’s the first item on the list named “Desk 7372” with MAC address FA:A1:63:XX:XX:XX
(yes, call me paranoid, but I’m not showing it to you).
Tip
If you don’t see device name to identify it, you may need to lookup its MAC address via other means. Use any other system that can connect to desk controller via Bluetooth and display its MAC address, for example a smartphone running Android. I had that problem myself initially, but after couple tries it went away and bluetoothctl
started showing device names. Why? I have no idea. It’s Bluetooth!
We are ready to initiate pairing, but before doing that, let’s disable scanning. It’s noisy and we don’t need it anymore:
[bluetooth]# scan off
[...]
[CHG] Controller B8:27:EB:XX:XX:XX Discovering: no
Discovery stopped
[...]
[bluetooth]#
Now make sure the desk controller is still in pairing mode (with blue LED flashing), then initiate pairing with:
[bluetooth]# pair FA:A1:63:XX:XX:XX
Attempting to pair with FA:A1:63:XX:XX:XX
[CHG] Device FA:A1:63:XX:XX:XX Connected: yes
[...]
[bluetooth]#
And trust it for future connections. Note that bluetoothctl
changes the prompt to device name after connecting:
[Desk 7372]# trust FA:A1:63:XX:XX:XX
[CHG] Device FA:A1:63:XX:XX:XX Trusted: yes
Changing FA:A1:63:XX:XX:XX trust succeeded
[Desk 7372]#
Now let’s double check that the device is paired and trusted…
[Desk 7372]# info FA:A1:63:XX:XX:XX
Device FA:A1:63:XX:XX:XX (random)
Name: Desk 7372
Alias: Desk 7372
Paired: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
UUID: Vendor specific (99fa0001-338a-1024-8a49-009c0215f78a)
UUID: Vendor specific (99fa0010-338a-1024-8a49-009c0215f78a)
UUID: Vendor specific (99fa0020-338a-1024-8a49-009c0215f78a)
UUID: Vendor specific (99fa0030-338a-1024-8a49-009c0215f78a)
[Desk 7372]#
…and looks like it’s also connected, which is actually not what we want right now. idasen-controller
script will try to initiate connection on its own and will simply fail if the device is already connected. So, let’s disconnect with:
[Desk 7372]# disconnect FA:A1:63:XX:XX:XX
Attempting to disconnect from FA:A1:63:XX:XX:XX
[CHG] Device FA:A1:63:XX:XX:XX ServicesResolved: no
Successful disconnected
[CHG] Device FA:A1:63:XX:XX:XX Connected: no
[bluetooth]#
Great! We can move on.
Setup idasen-controller
script
First, we need to install pip3
utility with:
sudo apt install python3-pip
Now we can install the script:
pip3 install idasen-controller
Warning
The command above will install idasen-controller under your home directory: /home/$USER/.local/bin/idasen-controller
This may not be desired if you plan to execute it later under a different user, like a service account. This is exactly what I ended up doing in my future post related to this project.
To install idasen-controller
for all users you should run:
sudo -H pip3 install idasen-controller
This will install it in /usr/local/bin/idasen-controller
AFAIK there is no global config file and the script looks for it in home directory by default, although that can be changed by executing it with --config PATH
.
We also need to setup the config file. Here’s a one liner using nano
:
mkdir -p ~/.config/idasen-controller && nano ~/.config/idasen-controller/config.yaml
Now paste the config. Remember to change the MAC address. You should not need to change other values (at least not on Raspberry Pi). Favourites for sit and stand positions can be changed later too:
mac_address: FA:A1:63:XX:XX:XX
scan_timeout: 5
connection_timeout: 10
movement_timeout: 30
adapter_name: hci0
server_address: "127.0.0.1"
server_port: 9123
favourites:
sit: 680
stand: 1073
Press CTRL + O to save it, then CTRL + X to exit nano
.
Now let’s see if the script can communicate with desk controller. Run idasen-controller
and you should see current height in the output:
$ idasen-controller
Connected FA:A1:63:XX:XX:XX
Height: 680mm
Disconnected
You can move the desk now to any desired height with:
$ idasen-controller --move-to 700
Connected FA:A1:63:XX:XX:XX
Height: 680mm
Moving to height: 700
Height: 684mm Speed: 26mm/s
Height: 700mm Speed: 52mm/s
Height: 700mm Speed: 0mm/s
Final height: 700mm (Target: 700mm)
Disconnected
There is a slight delay of 3-4 seconds, which is a downside of having to connect and disconnect each time a command is issued. But! At least we no longer have to hold any buttons. We can work around the delay as well. More on that later.
I have been testing this for few days now and I’m yet to experience any connectivity issues (certainly unavoidable with Bluetooth!). So far it’s not bad.
Here are other useful commands:
Command | Description |
---|---|
idasen-controller | You know this one already. It prints current height. |
idasen-controller --watch | Continuously outputs height as it changes. |
idasen-controller --move-to sit | Moves the desk to height saved as “sit” from config file. |
idasen-controller --move-to stand | Moves to “stand” height from config file. |