Put phone away box

This weekend I’m planning to tackle a simple project to reduce my screen time. I dedicated some thinking to this topic and maybe my case will be interesting to you.

Analysing my usage patterns, basically there’s time where screen time is justified (waiting in a queue, commute in public transportation) and there’s time where it very isn’t - for example when kids are home or when I could spend time with my wife. It’s important to “weigh” the time, or classify the time and put proper attention to it. Then, you can also start lifting time from one class to another; goal is to generate high quality time slots and not waste them.

To fit my needs, I have to develop a tool that will measure my off-the-phone time in some slots. I can define them upfront (eg 17:30 - 22:30 from Monday to Friday), or just delete datapoints in beeminder and derail eventually.

The best tool for me would be a “put phone away box” that would send the reports to beeminder. I wasn’t the first person to invent that, but I don’t want to pay subscription for something that I can’t beemind. Also, I happen to have a raspberry pi that is perfect for this use case.

Raspberry is a small computer you can hide in your pocket. Very small, very flexible. You don’t need raspberry or arduino, it will work the same way with your laptop.

The idea is to put raspberry in some obscure part of the house, connect a USB charging cable for my phone and compute time it’s been connected with this cable. Datapoint will contain amount of minutes it’s been there + time range in a comment (so that I know when it was).

I have to find an SD card for the raspberry, put the system online and generate simple script with ChatGPT. Script will run on system boot and it will periodically scan ports to find a device and start measurements.

The goal would be to keep the phone as much as possible inside the raspberry charging station - eventually total screen time will decrease as I move more time into quality time and remove my phone from quality time slots. I think I should note down weekly the screen time from Apple anyway, just to check if total amount of time is decreasing. It is not necessary, but interesting to see. raspberry can live on battery too. I’ll start simple, I don’t have the battery.

I think this is the closest analogy to “GPS location in the gym“ or scanning QR code, but for the screen time. Also, I can put some rules in the code to ignore obvious cheats: plugging phone at night or plugging it for <10 minutes. I think I will report everything for the first week and then fine tune code and commitment. For reference, I spend about 20h a week with my phone. I think I should be at 10h.

Sounds good? I’ll share some code and photos once it’s done.

3 Likes

This sounds great, good luck with it!

I discarded some other options, for example reporting time manually each week or each day.

Another discarded idea, that’s free to implement: you can achieve the same result with just Shortcuts app on iOS. One tap would mark a start date, second would be an end date. On tapping end, a request would be made to some simple service to calculate the minutes between them and sent to beeminder. This has some downsides; the physical element is removed and it requires you to interact with a phone to get your score. It has to work the other way. I can’t be in a state of “I can’t wait to interact with a phone to increase my score on Beeminder”.

As I mentioned in the first post, the same usb-checking script can run on your laptop - but then you have to have your laptop with even bigger screen turned on. That’s what makes Raspberry a good option.

Nonetheless, don’t feel discouraged by technical details as I’m going to share numbers (baseline + result) as well.

1 Like
#!/usr/bin/env python3
import subprocess
import time
import requests
from datetime import datetime

LOGFILE = "/var/log/phone_time.log"
STATEFILE = "/tmp/phone_connected_since"
BEE_USERNAME = "YOUR_USERNAME"
BEE_GOAL = "YOUR_GOAL_SLUG"
BEE_TOKEN = "YOUR_API_KEY"

CHECK_INTERVAL = 60  # seconds

def log(msg):
    with open(LOGFILE, "a") as f:
        f.write(f"{datetime.now():%Y-%m-%d %H:%M:%S} - {msg}\n")

def is_phone_connected():
    """Detect Apple or Android phone connected via USB."""
    try:
        lsusb = subprocess.check_output(["lsusb"], text=True)
        # Apple devices: idVendor 05ac
        # Common Android: 18d1 (Google), 2e17 (Samsung), 12d1 (Huawei)
        return any(v in lsusb for v in ["05ac", "18d1", "2e17", "12d1"])
    except subprocess.CalledProcessError:
        return False

def send_to_beeminder(minutes):
    url = f"https://www.beeminder.com/api/v1/users/{BEE_USERNAME}/goals/{BEE_GOAL}/datapoints.json"
    comment = f"{minutes} minutes phone connected (ended at {datetime.now():%H:%M})"
    data = {"auth_token": BEE_TOKEN, "value": minutes, "comment": comment}
    try:
        r = requests.post(url, data=data, timeout=10)
        if r.status_code == 200:
            log(f"Beeminder update OK: {r.text.strip()}")
        else:
            log(f"Beeminder update FAILED ({r.status_code}): {r.text.strip()}")
    except Exception as e:
        log(f"Beeminder update ERROR: {e}")

def main():
    connected = is_phone_connected()
    if connected:
        log("Initial state: phone connected.")
    else:
        log("Initial state: no phone connected.")

    start_time = None

    while True:
        new_state = is_phone_connected()

        if new_state and not connected:
            start_time = time.time()
            log("Phone connected.")
        elif not new_state and connected:
            if start_time:
                diff_minutes = int((time.time() - start_time) / 60)
                if diff_minutes > 0:
                    log(f"Phone disconnected after {diff_minutes} minutes.")
                    send_to_beeminder(diff_minutes)
                else:
                    log("Phone disconnected after <1 minute (ignored).")
            start_time = None

        connected = new_state
        time.sleep(CHECK_INTERVAL)

if __name__ == "__main__":
    log("=== phone_tracker started ===")
    main()

with the following config:

sudo chmod +x /usr/local/bin/phone_tracker.py

# /etc/systemd/system/phone-tracker.service
[Unit]
Description=Phone USB Tracker for Beeminder
After=network-online.target

[Service]
ExecStart=/usr/bin/python3 /usr/local/bin/phone_tracker.py
Restart=always

[Install]
WantedBy=multi-user.target

# and then run:
sudo systemctl daemon-reload
sudo systemctl enable --now phone-tracker.service

And finally you’ll be able to inspect it:

sudo tail -n 50 /var/log/phone_time.log
2 Likes

Some notes regarding future steps.

This code successfully puts a number on beeminder. It has many drawbacks. Doesn’t work offline, doesn’t work outside of the house (I won’t carry a raspberry with me etc). I think I will productise it a bit later, once I confirm it works.

We can imagine a portable device just a bit bigger than your phone, that can fit it and can be easily carried around, sort of pocket or small wooden box.

Winter is coming, I will spend a lot of time in the house, so I just want to anticipate some problems you might want to solve; I will check in a few months. It’s enough for me.

I will still log time spent weekly, just to understand if it works. Also, I will try to understand what are the leeches and what’s the good phone use. If it makes me happier, I wouldn’t mind to spend even more time in front of the screen.

I set the rate to 50 mins a day, effectively it should be in the afternoons during week days, so 1h from Monday to Friday works for me.

3 Likes

I’m following with interest, thanks for sharing your progress!

I had to think of a box like Box breathing box - macwright.com as I read this, at least for the home use cases :slight_smile: figured I’d drop a link for inspiration.

1 Like

Thank you.

On box breathing box - I appreciate Tom for taking time to prepare quality images on dark background that corresponds with his website’s. Side note: I would really like to have this sixth sense of a librarian for my own miniprojects: Projects - macwright.com

I ordered some books from the local library to kill night time scrolling and replace it with books.

I’ll report in a week with some measurements.

Nothing else comes to my mind right now.

1 Like

Let’s calibrate some assumptions.

Past weekly usage with projected future from GPT.

Out of ~26h each week, 15h is dedicated to Chrome and an hour or two to YouTube. Another 2h is focused tasks (Anki, Duolingo, Beeminder) and another 2h is chores or work (text messages, maps, spotify). Then add another 5 on random noise (banking app, more YouTube or checking emails).

I checked the data, and actually with 3h 30min each day I’m a perfectly typical Millennial (this is how I self-identify).

Overall average: The global average for all screen time is about 6 hours and 40 minutes, with a significant portion on phones.

American average: In the U.S., the average is approximately 5 hours and 16 minutes per day.

Gen Z: This group spends the most time, averaging around 7 hours and 18 minutes daily.

Millennials: They spend an average of about 3.4 hours (205 minutes) per day

I think we can realistically get to 15h, that would be great. I think that would mean that I don’t use my phone for entertainment too much. At 10h, I’d be a monk that is using phone just for work or self-improvement.

1 Like