feat(zones): rename tabs to zones across api, ui, and storage
Made-with: Cursor
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
LED driver registry persisted in ``db/device.json``.
|
||||
|
||||
Storage key and **id** field are the device **MAC**: 12 lowercase hex characters
|
||||
(no colons). **name** is for ``select`` / tabs (not unique). **address** is the
|
||||
(no colons). **name** is for ``select`` / zones (not unique). **address** is the
|
||||
reachability hint: same as MAC for ESP-NOW, or IP/hostname for Wi-Fi.
|
||||
"""
|
||||
|
||||
@@ -160,7 +160,7 @@ class Device(Model):
|
||||
address=None,
|
||||
mac=None,
|
||||
default_pattern=None,
|
||||
tabs=None,
|
||||
zones=None,
|
||||
device_type="led",
|
||||
transport="espnow",
|
||||
):
|
||||
@@ -183,7 +183,7 @@ class Device(Model):
|
||||
"transport": tr,
|
||||
"address": addr,
|
||||
"default_pattern": default_pattern if default_pattern else None,
|
||||
"tabs": list(tabs) if tabs else [],
|
||||
"zones": list(zones) if zones else [],
|
||||
}
|
||||
self.save()
|
||||
return mac_hex
|
||||
@@ -273,7 +273,7 @@ class Device(Model):
|
||||
"transport": "wifi",
|
||||
"address": ip,
|
||||
"default_pattern": None,
|
||||
"tabs": [],
|
||||
"zones": [],
|
||||
}
|
||||
self.save()
|
||||
return mac_hex
|
||||
|
||||
@@ -26,18 +26,18 @@ class Profile(Model):
|
||||
if changed:
|
||||
self.save()
|
||||
|
||||
def create(self, name="", profile_type="tabs"):
|
||||
def create(self, name="", profile_type="zones"):
|
||||
"""Create a new profile and its own empty palette.
|
||||
|
||||
profile_type: "tabs" or "scenes" (ignoring scenes for now)
|
||||
profile_type: "zones" or "scenes" (ignoring scenes for now)
|
||||
"""
|
||||
next_id = self.get_next_id()
|
||||
# Create a unique palette for this profile.
|
||||
palette_id = self._palette_model.create(colors=[])
|
||||
self[next_id] = {
|
||||
"name": name,
|
||||
"type": profile_type, # "tabs" or "scenes"
|
||||
"tabs": [], # Array of tab IDs
|
||||
"type": profile_type, # "zones" or "scenes"
|
||||
"zones": [], # Array of zone IDs
|
||||
"scenes": [], # Array of scene IDs (for future use)
|
||||
"palette_id": str(palette_id),
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
from models.model import Model
|
||||
|
||||
class Tab(Model):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def create(self, name="", names=None, presets=None):
|
||||
next_id = self.get_next_id()
|
||||
self[next_id] = {
|
||||
"name": name,
|
||||
"names": names if names else [],
|
||||
"presets": presets if presets else [],
|
||||
"default_preset": None
|
||||
}
|
||||
self.save()
|
||||
return next_id
|
||||
|
||||
def read(self, id):
|
||||
id_str = str(id)
|
||||
return self.get(id_str, None)
|
||||
|
||||
def update(self, id, data):
|
||||
id_str = str(id)
|
||||
if id_str not in self:
|
||||
return False
|
||||
self[id_str].update(data)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
def delete(self, id):
|
||||
id_str = str(id)
|
||||
if id_str not in self:
|
||||
return False
|
||||
self.pop(id_str)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
def list(self):
|
||||
return list(self.keys())
|
||||
62
src/models/zone.py
Normal file
62
src/models/zone.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from models.model import Model
|
||||
|
||||
|
||||
def _maybe_migrate_tab_json_to_zone():
|
||||
"""One-time copy ``db/tab.json`` → ``db/zone.json`` when upgrading."""
|
||||
try:
|
||||
base = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
db_dir = os.path.join(base, "db")
|
||||
zone_path = os.path.join(db_dir, "zone.json")
|
||||
tab_path = os.path.join(db_dir, "tab.json")
|
||||
if not os.path.exists(zone_path) and os.path.exists(tab_path):
|
||||
shutil.copy2(tab_path, zone_path)
|
||||
print("Migrated db/tab.json -> db/zone.json")
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
class Zone(Model):
|
||||
"""Preset layout row (stored in ``db/zone.json``); legacy storage was ``tab.json`` / Tab."""
|
||||
|
||||
def __init__(self):
|
||||
if not getattr(Zone, "_migration_checked", False):
|
||||
_maybe_migrate_tab_json_to_zone()
|
||||
Zone._migration_checked = True
|
||||
super().__init__()
|
||||
|
||||
def create(self, name="", names=None, presets=None):
|
||||
next_id = self.get_next_id()
|
||||
self[next_id] = {
|
||||
"name": name,
|
||||
"names": names if names else [],
|
||||
"presets": presets if presets else [],
|
||||
"default_preset": None,
|
||||
}
|
||||
self.save()
|
||||
return next_id
|
||||
|
||||
def read(self, id):
|
||||
id_str = str(id)
|
||||
return self.get(id_str, None)
|
||||
|
||||
def update(self, id, data):
|
||||
id_str = str(id)
|
||||
if id_str not in self:
|
||||
return False
|
||||
self[id_str].update(data)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
def delete(self, id):
|
||||
id_str = str(id)
|
||||
if id_str not in self:
|
||||
return False
|
||||
self.pop(id_str)
|
||||
self.save()
|
||||
return True
|
||||
|
||||
def list(self):
|
||||
return list(self.keys())
|
||||
Reference in New Issue
Block a user