Add required battery_size to devices, filter install panels by size
This commit is contained in:
@@ -634,8 +634,10 @@ def create_app(config_object="config"):
|
||||
devices = db.query(Device).order_by(Device.name).all()
|
||||
device_types = sorted({d.device_type for d in devices if d.device_type})
|
||||
device_locations = sorted({d.location for d in devices if d.location})
|
||||
device_battery_sizes = sorted({d.battery_size for d in devices if d.battery_size})
|
||||
return render_template("device_list.html", devices=devices,
|
||||
device_types=device_types, device_locations=device_locations)
|
||||
device_types=device_types, device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Devices — add
|
||||
@@ -646,19 +648,31 @@ def create_app(config_object="config"):
|
||||
all_devices = db.query(Device).all()
|
||||
device_types = sorted({d.device_type for d in all_devices if d.device_type})
|
||||
device_locations = sorted({d.location for d in all_devices if d.location})
|
||||
device_battery_sizes = sorted({d.battery_size for d in all_devices if d.battery_size})
|
||||
|
||||
if request.method == "POST":
|
||||
name = request.form.get("name", "").strip()
|
||||
slots_raw = request.form.get("battery_slots", "1").strip()
|
||||
notes = request.form.get("notes", "").strip() or None
|
||||
device_type = request.form.get("device_type", "").strip() or None
|
||||
battery_size = request.form.get("battery_size", "").strip() or None
|
||||
location = request.form.get("location", "").strip() or None
|
||||
|
||||
if not name:
|
||||
flash("Device name is required.", "error")
|
||||
return render_template("device_add.html",
|
||||
device_types=device_types,
|
||||
device_locations=device_locations), 400
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes), 400
|
||||
|
||||
if not battery_size:
|
||||
flash("Battery size is required.", "error")
|
||||
return render_template("device_add.html",
|
||||
device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes,
|
||||
form_name=name, form_notes=notes or "",
|
||||
form_device_type=request.form.get("device_type", "")), 400
|
||||
|
||||
try:
|
||||
slots = int(slots_raw)
|
||||
@@ -669,6 +683,7 @@ def create_app(config_object="config"):
|
||||
return render_template("device_add.html",
|
||||
device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes,
|
||||
form_name=name, form_notes=notes or "",
|
||||
form_device_type=request.form.get("device_type", "")), 400
|
||||
|
||||
@@ -677,19 +692,22 @@ def create_app(config_object="config"):
|
||||
return render_template("device_add.html",
|
||||
device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes,
|
||||
form_name=name, form_slots=slots,
|
||||
form_notes=notes or "",
|
||||
form_device_type=request.form.get("device_type", "")), 400
|
||||
|
||||
device = Device(name=name, battery_slots=slots, notes=notes,
|
||||
device_type=device_type, location=location)
|
||||
device_type=device_type, battery_size=battery_size,
|
||||
location=location)
|
||||
db.add(device)
|
||||
db.commit()
|
||||
flash(f"Device '{name}' added.", "success")
|
||||
return redirect(url_for("device_list"))
|
||||
|
||||
return render_template("device_add.html", device_types=device_types,
|
||||
device_locations=device_locations)
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes)
|
||||
|
||||
# ------------------------------------------------------------------ #
|
||||
# Devices — detail
|
||||
@@ -700,12 +718,22 @@ def create_app(config_object="config"):
|
||||
device = db.get(Device, device_id)
|
||||
if device is None:
|
||||
abort(404)
|
||||
brands = [r[0] for r in db.query(Battery.brand).distinct().order_by(Battery.brand).all()]
|
||||
available_batteries = (db.query(Battery)
|
||||
.filter_by(status="available")
|
||||
.order_by(Battery.label).all())
|
||||
device_types = sorted({d.device_type for d in db.query(Device).all() if d.device_type})
|
||||
device_locations = sorted({d.location for d in db.query(Device).all() if d.location})
|
||||
all_devices = db.query(Device).all()
|
||||
brands_q = db.query(Battery.brand).filter(Battery.status == "available")
|
||||
if device.battery_size:
|
||||
brands_q = brands_q.filter(
|
||||
(Battery.size == device.battery_size) | (Battery.size == None)
|
||||
)
|
||||
brands = [r[0] for r in brands_q.distinct().order_by(Battery.brand).all()]
|
||||
avail_q = db.query(Battery).filter_by(status="available")
|
||||
if device.battery_size:
|
||||
avail_q = avail_q.filter(
|
||||
(Battery.size == device.battery_size) | (Battery.size == None)
|
||||
)
|
||||
available_batteries = avail_q.order_by(Battery.label).all()
|
||||
device_types = sorted({d.device_type for d in all_devices if d.device_type})
|
||||
device_locations = sorted({d.location for d in all_devices if d.location})
|
||||
device_battery_sizes = sorted({d.battery_size for d in all_devices if d.battery_size})
|
||||
ha_live_pct = None
|
||||
if ha_client.enabled and device.ha_entity_id:
|
||||
ha_live_pct = ha_client.get_state(device.ha_entity_id, timeout=1)
|
||||
@@ -727,6 +755,7 @@ def create_app(config_object="config"):
|
||||
available_batteries=available_batteries,
|
||||
device_types=device_types,
|
||||
device_locations=device_locations,
|
||||
device_battery_sizes=device_battery_sizes,
|
||||
ha_enabled=ha_client.enabled,
|
||||
ha_live_pct=ha_live_pct)
|
||||
|
||||
@@ -763,6 +792,7 @@ def create_app(config_object="config"):
|
||||
device.battery_slots = slots
|
||||
device.notes = notes
|
||||
device.device_type = device_type
|
||||
device.battery_size = request.form.get("battery_size", "").strip() or None
|
||||
device.location = request.form.get("location", "").strip() or None
|
||||
device.ha_entity_id = request.form.get("ha_entity_id", "").strip() or None
|
||||
db.commit()
|
||||
@@ -807,11 +837,12 @@ def create_app(config_object="config"):
|
||||
|
||||
# Validate availability before writing anything
|
||||
for brand, qty in pairs:
|
||||
available_count = (
|
||||
db.query(func.count(Battery.id))
|
||||
.filter_by(brand=brand, status="available")
|
||||
.scalar()
|
||||
)
|
||||
avail_q = db.query(func.count(Battery.id)).filter_by(brand=brand, status="available")
|
||||
if device.battery_size:
|
||||
avail_q = avail_q.filter(
|
||||
(Battery.size == device.battery_size) | (Battery.size == None)
|
||||
)
|
||||
available_count = avail_q.scalar()
|
||||
if available_count < qty:
|
||||
flash(
|
||||
f"Need {qty} {brand}, but only {available_count} available.",
|
||||
@@ -822,13 +853,12 @@ def create_app(config_object="config"):
|
||||
# All checks passed — perform installs
|
||||
total_installed = 0
|
||||
for brand, qty in pairs:
|
||||
batch = (
|
||||
db.query(Battery)
|
||||
.filter_by(brand=brand, status="available")
|
||||
.order_by(Battery.id)
|
||||
.limit(qty)
|
||||
.all()
|
||||
)
|
||||
batch_q = db.query(Battery).filter_by(brand=brand, status="available")
|
||||
if device.battery_size:
|
||||
batch_q = batch_q.filter(
|
||||
(Battery.size == device.battery_size) | (Battery.size == None)
|
||||
)
|
||||
batch = batch_q.order_by(Battery.id).limit(qty).all()
|
||||
for b in batch:
|
||||
b.status = "installed"
|
||||
b.device_id = device.id
|
||||
@@ -870,6 +900,12 @@ def create_app(config_object="config"):
|
||||
f"{', '.join(existing_brands)}. Mixing brands is not recommended.",
|
||||
"warning",
|
||||
)
|
||||
if device.battery_size and battery.size and battery.size != device.battery_size:
|
||||
flash(
|
||||
f"Warning: {device.name} requires {device.battery_size} batteries, "
|
||||
f"but {battery.label} is {battery.size}.",
|
||||
"warning",
|
||||
)
|
||||
battery.status = "installed"
|
||||
battery.device_id = device.id
|
||||
db.commit()
|
||||
|
||||
Reference in New Issue
Block a user