Skip to content

Instantly share code, notes, and snippets.

@mrchrisadams
Last active March 21, 2026 12:50
Show Gist options
  • Select an option

  • Save mrchrisadams/279c4d40282b374428f62577d5481018 to your computer and use it in GitHub Desktop.

Select an option

Save mrchrisadams/279c4d40282b374428f62577d5481018 to your computer and use it in GitHub Desktop.
Exporting temperature data from IKEA Dirigera hub to CSV

Exporting temperature data from IKEA Dirigera hub to CSV

Exporting Temperature Data from IKEA Dirigera to CSV

This guide covers how to install the ikea CLI, authenticate with your Dirigera hub, and export all temperature readings from your Alpstuga sensors into CSV files. Useful as documented evidence for a rent reduction (Mietminderung) claim.

Note: This uses the unofficial ikea-dirigera-client library. It is not affiliated with IKEA. A future hub firmware update could break it.


1. Install the CLI

macOS

brew tap salex-org/homebrew-tap
brew install salex-org/tap/ikea-dirigera-cli

# Remove quarantine flag (required on macOS)
xattr -d com.apple.quarantine /opt/homebrew/bin/ikea

Linux (amd64)

curl -L https://github.com/salex-org/ikea-dirigera-client/releases/download/v1.0.2/ikea-dirigera-cli_1.0.2_linux_amd64.tar.gz \
  | tar -xz ikea
sudo mv ikea /usr/local/bin/

Linux (arm64, e.g. Raspberry Pi)

curl -L https://github.com/salex-org/ikea-dirigera-client/releases/download/v1.0.2/ikea-dirigera-cli_1.0.2_linux_arm64.tar.gz \
  | tar -xz ikea
sudo mv ikea /usr/local/bin/

Windows

Download ikea-dirigera-cli_1.0.2_windows_amd64.zip from the releases page, unzip it, and add the folder containing ikea.exe to your PATH.

Verify the installation:

ikea --help

2. Find Your Hub's IP Address

Your laptop must be on the same local network as the Dirigera hub (same Wi-Fi).

Option A — Let the CLI scan for it

ikea list hubs

This uses mDNS to discover Dirigera hubs on your network. Note the IP address shown.

Option B — Find it via your router

Log in to your router's admin page (usually 192.168.0.1 or 192.168.1.1) and look for a device named something like DIRIGERA or IKEA in the connected device list.


3. Authenticate with the Hub

Run the authorize command with your hub's IP (replace 192.168.1.x with the real IP):

ikea authorize 192.168.1.x

When prompted, press the button on the back of the Dirigera hub within 60 seconds.

The CLI will:

  1. Create a new user on the hub
  2. Obtain an access token
  3. Save a named context to ~/.ikea-dirigera-cli.yaml (the token itself is stored in your OS keychain)

Verify it worked:

ikea list contexts

You should see one entry marked with * as the current context.


4. Explore Your Devices

List all devices registered on the hub:

ikea list devices

To see full details for any device (including all attributes):

ikea show device <device-id>

To find only temperature sensors, pipe through grep:

ikea list devices -o json | python3 -c "
import json, sys
devices = json.load(sys.stdin)
sensors = [d for d in devices if 'sensor' in d.get('deviceType','').lower() or 'sensor' in d.get('type','').lower()]
for s in sensors:
    print(s['id'], s.get('type'), s.get('deviceType'))
"

The Alpstuga sensors typically report a deviceType of temperatureAndHumiditySensor.


5. Export Temperature Data to CSV

The Dirigera hub only stores the current snapshot of sensor readings — it does not expose historical logs through its API. Each call to the API returns the most recent reading. To build a historical dataset, you need to poll the hub repeatedly and accumulate readings over time.

One-time snapshot (current readings)

To grab a single snapshot of all temperature sensors right now:

ikea list devices -o json | python3 - << 'EOF'
import json, sys, csv, datetime

with open(sys.stdin.fileno()) as f:
    devices = json.load(f)

timestamp = datetime.datetime.now().isoformat()
rows = []

for device in devices:
    attrs = device.get("attributes", {})
    temp = attrs.get("currentTemperature")
    humidity = attrs.get("currentRelativeHumidity")
    if temp is not None:
        rows.append({
            "timestamp": timestamp,
            "device_id": device["id"],
            "room": device.get("room", {}).get("name", ""),
            "temperature_c": temp,
            "humidity_pct": humidity,
            "is_reachable": device.get("isReachable"),
            "last_seen": device.get("lastSeen"),
        })

writer = csv.DictWriter(sys.stdout, fieldnames=rows[0].keys())
writer.writeheader()
writer.writerows(rows)
EOF

Redirect to a file:

ikea list devices -o json | python3 snapshot.py > temperatures.csv

Continuous polling script (recommended for building a history)

Save this as poll_temperatures.py and run it to log readings every 5 minutes to a CSV file:

#!/usr/bin/env python3
"""
Poll all temperature sensors from IKEA Dirigera hub and append readings to a CSV.
Usage: python3 poll_temperatures.py <hub-ip> <access-token> <tls-fingerprint>

Get the access token:   ikea show token
Get the fingerprint:    ikea list contexts  (the "TLS Fingerprint" column)
"""

import csv
import datetime
import json
import os
import ssl
import sys
import time
import urllib.request

INTERVAL_SECONDS = 300  # 5 minutes
OUTPUT_FILE = "temperature_log.csv"
FIELDNAMES = ["timestamp", "device_id", "room", "custom_name",
              "temperature_c", "humidity_pct", "is_reachable", "last_seen"]


def fetch_devices(ip, port, token, fingerprint):
    url = f"https://{ip}:{port}/v1/devices"

    # Build a TLS context that accepts the hub's self-signed cert by fingerprint
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
    with urllib.request.urlopen(req, context=ctx, timeout=10) as resp:
        return json.load(resp)


def extract_sensor_rows(devices, timestamp):
    rows = []
    for device in devices:
        attrs = device.get("attributes", {})
        temp = attrs.get("currentTemperature")
        if temp is None:
            continue  # skip non-temperature devices
        rows.append({
            "timestamp": timestamp,
            "device_id": device["id"],
            "room": device.get("room", {}).get("name", ""),
            "custom_name": attrs.get("customName", ""),
            "temperature_c": temp,
            "humidity_pct": attrs.get("currentRelativeHumidity", ""),
            "is_reachable": device.get("isReachable"),
            "last_seen": device.get("lastSeen", ""),
        })
    return rows


def main():
    if len(sys.argv) < 4:
        print(__doc__)
        sys.exit(1)

    ip = sys.argv[1]
    token = sys.argv[2]
    fingerprint = sys.argv[3]  # kept for reference; urllib TLS check disabled above
    port = int(sys.argv[4]) if len(sys.argv) > 4 else 8443

    file_exists = os.path.exists(OUTPUT_FILE)

    print(f"Logging temperature readings to {OUTPUT_FILE} every {INTERVAL_SECONDS}s. Ctrl+C to stop.")

    with open(OUTPUT_FILE, "a", newline="") as csvfile:
        writer = csv.DictWriter(csvfile, fieldnames=FIELDNAMES)
        if not file_exists:
            writer.writeheader()

        while True:
            try:
                now = datetime.datetime.now().isoformat()
                devices = fetch_devices(ip, port, token, fingerprint)
                rows = extract_sensor_rows(devices, now)
                writer.writerows(rows)
                csvfile.flush()
                print(f"[{now}] Logged {len(rows)} sensor readings.")
            except Exception as e:
                print(f"[{datetime.datetime.now().isoformat()}] Error: {e}", file=sys.stderr)

            time.sleep(INTERVAL_SECONDS)


if __name__ == "__main__":
    main()

Get the values you need to run it:

# Get your access token
TOKEN=$(ikea show token)

# Get the TLS fingerprint — look in the "TLS Fingerprint" column
ikea list contexts

# Run the poller (replace 192.168.1.x and the fingerprint)
python3 poll_temperatures.py 192.168.1.x "$TOKEN" "your-fingerprint-here"

The script will append a new row every 5 minutes. You can leave it running overnight or for several days to accumulate data.


6. Running as a Background Service (macOS / Linux)

macOS — launchd

Save as ~/Library/LaunchAgents/dirigera.poll.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>           <string>dirigera.poll</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/python3</string>
    <string>/Users/YOU/poll_temperatures.py</string>
    <string>192.168.1.x</string>
    <string>YOUR_TOKEN</string>
    <string>YOUR_FINGERPRINT</string>
  </array>
  <key>RunAtLoad</key>       <true/>
  <key>KeepAlive</key>       <true/>
  <key>StandardOutPath</key> <string>/tmp/dirigera.log</string>
  <key>StandardErrorPath</key><string>/tmp/dirigera.err</string>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/dirigera.poll.plist

Linux — systemd user service

Save as ~/.config/systemd/user/dirigera-poll.service:

[Unit]
Description=Dirigera temperature poller

[Service]
ExecStart=/usr/bin/python3 /home/YOU/poll_temperatures.py 192.168.1.x YOUR_TOKEN YOUR_FINGERPRINT
Restart=always
RestartSec=30

[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now dirigera-poll
journalctl --user -u dirigera-poll -f

7. Example CSV Output

timestamp,device_id,room,custom_name,temperature_c,humidity_pct,is_reachable,last_seen
2025-01-15T08:00:01,abc123,Bedroom,Alpstuga Schlafzimmer,16.2,58.0,True,2025-01-15T07:59:50
2025-01-15T08:00:01,def456,Living Room,Alpstuga Wohnzimmer,17.1,55.0,True,2025-01-15T07:59:48
2025-01-15T08:05:01,abc123,Bedroom,Alpstuga Schlafzimmer,16.0,59.0,True,2025-01-15T08:04:50

8. Tips for the Rent Reduction Letter (Mietminderung)

  • German law (§ 536 BGB) allows rent reduction when the apartment is not fit for use as agreed. Consistently cold temperatures are a recognised defect.
  • Recommended minimum temperature in living areas: 20–22 °C during the day; bedrooms 18 °C minimum (source: German tenant law guidance / Mieterverein).
  • Export your CSV and create a simple chart in LibreOffice Calc or Google Sheets.
  • Include the room name, dates, minimum and average temperatures per day.
  • Attach both the raw CSV and a chart as annexes to your letter.
  • Send the letter by Einschreiben mit Rückschein (recorded delivery with return receipt) so you have proof of delivery.

Troubleshooting

Problem Fix
ikea list hubs finds nothing Make sure laptop is on the same Wi-Fi as the hub. Try finding the IP via your router admin page instead.
Authorization times out Press the physical button on the back of the hub during the 60-second window.
context not set error Run ikea authorize <ip> first, or pass --context <name> explicitly.
TLS / certificate errors The hub uses a self-signed cert. The client pins by fingerprint — make sure you copied the fingerprint exactly.
No temperature in device list Use ikea show device <id> on each device to inspect attributes; look for currentTemperature.

References


Accessing Historical Temperature Data from the IKEA Home Smart App

The short answer

The Dirigera hub's local API has no history endpoint — every open-source client confirms this. The hub only exposes the current reading at any moment. The weeks of graphs you see in the IKEA Home Smart app are stored inside the app itself on your iPhone/iPad (in a local SQLite database), not on the hub and not in IKEA's cloud.

This means the data is accessible — you just need to extract it from an iPhone backup.


How the app stores the data

The IKEA Home Smart app (bundle ID: com.ikea.inter.homesmart2) caches historical sensor readings in a SQLite database inside its private app container on your device. This is standard iOS app architecture. The data is included in a local iTunes/Finder backup and can be extracted without jailbreaking.


Method 1: iMazing (recommended — macOS or Windows, free for this use)

iMazing is a free iOS device manager that can extract app data from a local backup.

Step 1 — Back up your iPhone to your Mac/PC (not iCloud)

On macOS Ventura or later:

  1. Connect iPhone via USB
  2. Open Finder → click your iPhone in the sidebar
  3. Under "Back up all of the data on your iPhone to this Mac", click Back Up Now
  4. Wait for it to complete

On Windows (or older macOS):

  • Use iTunes → click the device icon → Back Up Now

Do not encrypt the backup if you want to keep things simple — iMazing can read unencrypted backups directly.

Step 2 — Install iMazing

Download from imazing.com. The free version is sufficient for extracting app data.

Step 3 — Browse the app's data

  1. Open iMazing and select your iPhone
  2. Click Manage Apps (or Apps in the sidebar)
  3. Find IKEA Home smart in the list
  4. Click Export App Documents or use Browse App Data
  5. Look for a .sqlite or .db file — it will likely be named something like history.sqlite, cache.db, or similar in the app's Documents/ or Library/Caches/ folder
  6. Save it to your desktop

Step 4 — Query the SQLite file

Install DB Browser for SQLite (free, macOS/Windows/Linux).

  1. Open DB Browser → Open Database → select the file you exported
  2. Click the Browse Data tab
  3. Look through the table list for anything named like measurements, readings, sensor_history, temperature_log, or similar
  4. Once found, go to File → Export → Table(s) as CSV

Or from the command line:

# List all tables in the database
sqlite3 ~/Desktop/ikea-app-data.sqlite ".tables"

# Preview the temperature table (adjust table name to match what you find)
sqlite3 ~/Desktop/ikea-app-data.sqlite "SELECT * FROM measurements LIMIT 10;"

# Export to CSV
sqlite3 -csv -header ~/Desktop/ikea-app-data.sqlite \
  "SELECT * FROM measurements ORDER BY timestamp ASC;" \
  > temperature_history.csv

Method 2: Android + ADB (if you also have an Android phone)

If you have an Android device with the IKEA Home app installed and USB debugging enabled:

# Back up the IKEA app data (no root required for non-encrypted apps)
adb backup -noapk com.ikea.inter.homesmart2 -f ikea_backup.ab

# Convert the backup to a tar archive
dd if=ikea_backup.ab bs=1 skip=24 | python3 -c "import zlib,sys; sys.stdout.buffer.write(zlib.decompress(sys.stdin.buffer.read()))" > ikea_backup.tar

# Extract
tar -xf ikea_backup.tar

# Find SQLite databases
find . -name "*.db" -o -name "*.sqlite" | xargs ls -lh

Note: Android backup via ADB only works if the app has not set android:allowBackup="false" in its manifest. Many apps do set this flag, in which case ADB backup will produce an empty archive. Root access or a paid tool like Oxygen Forensic Detective would be needed in that case.


Method 3: Screenshot/screen record as a last resort

If the extraction methods above are blocked or too complex, you can still document the graphs directly from the app:

  1. Open the IKEA Home Smart app
  2. Navigate to each temperature sensor
  3. View the historical graph (days/weeks view)
  4. Take screenshots — on iPhone: Side button + Volume Up simultaneously
  5. On iPad: same button combination

Screenshots showing sensor name, room, date range, and temperature readings are accepted as supporting evidence in German tenancy disputes (Mietrechtsstreit). Date and time metadata is embedded in the photo EXIF data.


What to do if iMazing can't find sensor history

It's possible that the IKEA Home app stores historical data in iCloud rather than locally. If iMazing shows no useful database files:

  1. Check iCloud: Go to iPhone Settings → [Your Name] → iCloud → Manage Storage → IKEA Home smart — if it shows storage used, the data lives in iCloud
  2. GDPR data request: IKEA is subject to GDPR. Email privacy@inter.ikea.com and request a copy of all data held about you under Article 15 GDPR (Recht auf Auskunft). They must respond within 30 days and provide a machine-readable export. Reference your account email and the product serial number of your hub.

The GDPR route is also useful as a paper trail for your rent reduction case — a formal data request to IKEA creates a timestamped record that you owned and operated the sensors.


Summary table

Method Difficulty Works without root/jailbreak Cost
iMazing (Mac/Win backup extract) Low ✅ Yes Free
DB Browser for SQLite (view extracted DB) Low ✅ Yes Free
ADB backup (Android only) Medium ✅ Usually Free
Screenshots from app Very low ✅ Yes Free
GDPR data request to IKEA Low ✅ Yes Free (30-day wait)
Forward-polling with poll_temperatures.py Low ✅ Yes Free (starts from now)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment