Add model base class and models

- Add Model base class with get_next_id() method
- Add Preset model with CRUD operations
- Add Profile model with tabs and palette support
- Add Group model for device grouping
- Add Sequence model for preset sequencing
- Add Tab model for organizing device controls
- Add Palette model for color collections
This commit is contained in:
2026-01-11 21:34:14 +13:00
parent d00d21e2b6
commit 01f373f0bd
7 changed files with 302 additions and 0 deletions

51
src/models/group.py Normal file
View File

@@ -0,0 +1,51 @@
from models.model import Model
class Group(Model):
def __init__(self):
super().__init__()
def create(self, name=""):
next_id = self.get_next_id()
self[next_id] = {
"name": name,
"devices": [],
"pattern": "on",
"colors": ["000000", "FF0000"],
"brightness": 100,
"delay": 100,
"step_offset": 0,
"step_increment": 1,
"n1": 0,
"n2": 0,
"n3": 0,
"n4": 0,
"n5": 0,
"n6": 0,
"n7": 0,
"n8": 0
}
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())

42
src/models/model.py Normal file
View File

@@ -0,0 +1,42 @@
import json
import wifi
import ubinascii
import machine
class Model(dict):
def __init__(self):
self.file = self.__class__.__name__ + ".json"
super().__init__()
self.load() # Load settings from file during initialization
def set_defaults(self):
self = {}
def get_next_id(self):
"""Get the next available ID for creating a new record."""
if not self:
return "1"
max_id = max((int(k) for k in self.keys() if k.isdigit()), default=0)
return str(max_id + 1)
def save(self):
try:
j = json.dumps(self)
with open(self.file, 'w') as file:
file.write(j)
print("Settings saved successfully.")
except Exception as e:
print(f"Error saving settings: {e}")
def load(self):
try:
with open(self.file, 'r') as file:
loaded_settings = json.load(file)
self.update(loaded_settings)
print("Settings loaded successfully.")
except Exception as e:
print(f"Error loading settings")
self.set_defaults()
self.save()

37
src/models/pallet.py Normal file
View File

@@ -0,0 +1,37 @@
from models.model import Model
class Palette(Model):
def __init__(self):
super().__init__()
def create(self, name="", colors=None):
next_id = self.get_next_id()
self[next_id] = {
"name": name,
"colors": colors if colors else []
}
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())

50
src/models/preset.py Normal file
View File

@@ -0,0 +1,50 @@
from models.model import Model
class Preset(Model):
def __init__(self):
super().__init__()
def create(self):
next_id = self.get_next_id()
self[next_id] = {
"name": "",
"pattern": "",
"colors": [],
"brightness": 0,
"delay": 0,
"n1": 0,
"n2": 0,
"n3": 0,
"n4": 0,
"n5": 0,
"n6": 0,
}
self.save()
return next_id
def read(self, id):
id_str = str(id)
if id_str not in self:
return None
return self[id_str]
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())

40
src/models/profile.py Normal file
View File

@@ -0,0 +1,40 @@
from models.model import Model
class Profile(Model):
def __init__(self):
super().__init__()
def create(self, name=""):
next_id = self.get_next_id()
self[next_id] = {
"name": name,
"tabs": {},
"palette": [],
"tab_order": []
}
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())

44
src/models/squence.py Normal file
View File

@@ -0,0 +1,44 @@
from models.model import Model
class Sequence(Model):
def __init__(self):
super().__init__()
def create(self, group_name="", preset_names=None):
next_id = self.get_next_id()
self[next_id] = {
"group_name": group_name,
"presets": preset_names if preset_names else [],
"sequence_duration": 3000, # Duration per preset in ms
"sequence_transition": 500, # Transition time in ms
"sequence_loop": False,
"sequence_repeat_count": 0, # 0 = infinite
"sequence_active": False,
"sequence_index": 0,
"sequence_start_time": 0
}
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())

38
src/models/tab.py Normal file
View File

@@ -0,0 +1,38 @@
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 []
}
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())