SitStand - Controlling My Standing Desk with Bluetooth
Building a BLE controller for UPLIFT and Jiecang standing desks with CLI commands, a web dashboard, and activity tracking
SitStand: Hacking My Standing Desk
I’ve had a standing desk for years and even though the button to make it go up and down is inches from my hand, for whatever reason I realized I don’t press it enough. Technology to the rescue. The desk is an UPLIFT Desk that has an optional Bluetooth Adapter that can pair with a mobile app.
The implementation of the mobile app left a lot to be desired and it was perhaps 20 minutes later that I was reverse engineering the gadget.
The Problem
I wanted to:
- Control my desk from the command line (because reasons)
- Track how much time I spend sitting vs standing
- See a nice dashboard with analytics
- Eventually automate position changes on a schedule and perhaps hook into Home Assistant
What I Built
SitStand is a Bluetooth Low Energy (BLE) controller that works with UPLIFT and other related Jiecang-based standing desks. I was able to sniff out the Bluetooth device and that led me to find related repos and reverse-engineered Android apps that explored the protocol further.
I wanted two command line commands “sit” and “stand” that would do that one thing. After implementing the basics, I worked with Claude Code to make a pretty dashboard with added visualization.
It gives you:
CLI Commands
Simple sit and stand commands that just work. No app needed, no phone required.
1
2
$ stand # Desk goes up
$ sit # Desk goes down
Web Dashboard
A real-time monitoring interface with a 3D visualization of your desk and height tracking throughout the day.
Activity Analytics
Logs every transition with daily and hourly statistics. Now I can actually see my sitting habits (spoiler: I sit too much).
Auto-Discovery
The system automatically finds your desk’s Bluetooth address and caches it. No manual configuration needed.
The Technical Bits
The UpLift desks seem to be made by a company called Jiecang. They use a BLE protocol with a specific packet structure:
- Frame boundaries marked by
[0xF1, 0xF1]header and[0x7E]footer - Includes opcode, length, payload data, and checksum validation
It took a bit of wrangling but it seems to work fairly well, but currently only tested on my personal desk. Note that other desks may be different and the max/min offsets and adjustments for each desk may matter significantly, so use at your own risk.
Why Open Source This?
I haven’t seen a nice dashboard or a pure web implementation (just in the browser), this version has both. Hopefully others can improve on this.
Get Started
The project is MIT licensed and available on GitHub:
- Repository: github.com/graiz/sitstand
Requirements are minimal: Python 3.8+ and a computer with Bluetooth support. The README has full setup instructions.
Hope this helps you stand more on a daily basis.