mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-08 07:01:40 +02:00
Binds binary_sensor and reading-carrying sensor entities to a printer and renders their state on its card, worded by Home Assistant's device_class. Optional per-sensor alert condition drives a notification on the transition into the alert state and an opt-in interlock that holds queued prints while alerting -- a hold with a readable waiting_reason, never a failure, and only ever on a sensor that was read successfully. Sensors get their own table rather than a wider entity pattern on SmartPlug: get_smart_plug_by_printer would otherwise hand the card's power button a door contact to switch. The hold is passed to the model matcher directly rather than merged into busy_printers: _check_auto_drying reads that set as "is currently printing" and would put an idle-but-held printer down the mid-print drying path. The notification_providers migration spells its default FALSE, not 0 -- Postgres rejects an integer default for a boolean and _safe_execute swallows the error.
This commit is contained in:
@@ -2167,6 +2167,75 @@ export interface HATestConnectionResult {
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
// A Home Assistant entity bound to a printer for display on its card (#1148, #448).
|
||||
// Read-only: unlike a SmartPlug there is nothing here to switch.
|
||||
export interface PrinterHASensor {
|
||||
id: number;
|
||||
printer_id: number;
|
||||
name: string;
|
||||
entity_id: string;
|
||||
kind: 'binary' | 'numeric';
|
||||
device_class: string | null; // HA's own class: "door", "temperature", ...
|
||||
unit: string | null; // numeric sensors only
|
||||
// What counts as needing attention. Binary sensors use alert_state, numeric
|
||||
// ones the thresholds; all null means the sensor is display-only.
|
||||
alert_state: 'on' | 'off' | null;
|
||||
alert_above: number | null;
|
||||
alert_below: number | null;
|
||||
block_print: boolean; // hold the printer's queue while alerting
|
||||
notify_on_alert: boolean;
|
||||
show_on_printer_card: boolean;
|
||||
sort_order: number;
|
||||
last_state: string | null;
|
||||
last_changed: string | null;
|
||||
last_checked: string | null;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface PrinterHASensorReading {
|
||||
id: number;
|
||||
name: string;
|
||||
entity_id: string;
|
||||
kind: 'binary' | 'numeric';
|
||||
device_class: string | null;
|
||||
unit: string | null;
|
||||
state: string | null; // null when unreadable or not yet polled
|
||||
value: number | null; // numeric sensors only
|
||||
alerting: boolean;
|
||||
block_print: boolean;
|
||||
reachable: boolean;
|
||||
last_changed: string | null;
|
||||
}
|
||||
|
||||
export interface PrinterHASensorCreate {
|
||||
printer_id: number;
|
||||
name: string;
|
||||
entity_id: string;
|
||||
kind: 'binary' | 'numeric';
|
||||
device_class?: string | null;
|
||||
unit?: string | null;
|
||||
alert_state?: 'on' | 'off' | null;
|
||||
alert_above?: number | null;
|
||||
alert_below?: number | null;
|
||||
block_print?: boolean;
|
||||
notify_on_alert?: boolean;
|
||||
show_on_printer_card?: boolean;
|
||||
sort_order?: number;
|
||||
}
|
||||
|
||||
export type PrinterHASensorUpdate = Partial<Omit<PrinterHASensorCreate, 'printer_id'>>;
|
||||
|
||||
// An entity offered by the binding picker.
|
||||
export interface HADisplayEntity {
|
||||
entity_id: string;
|
||||
friendly_name: string;
|
||||
state: string | null;
|
||||
domain: string; // "binary_sensor" | "sensor"
|
||||
device_class: string | null;
|
||||
unit_of_measurement: string | null;
|
||||
}
|
||||
|
||||
export interface SmartPlugEnergy {
|
||||
power: number | null; // Current watts
|
||||
voltage: number | null; // Volts
|
||||
@@ -2615,6 +2684,7 @@ export interface NotificationProvider {
|
||||
on_plate_clear_required: boolean;
|
||||
// Bed cooled
|
||||
on_bed_cooled: boolean;
|
||||
on_ha_sensor_alert: boolean;
|
||||
// First layer complete
|
||||
on_first_layer_complete: boolean;
|
||||
// Inventory stock alerts
|
||||
@@ -2675,6 +2745,7 @@ export interface NotificationProviderCreate {
|
||||
on_plate_clear_required?: boolean;
|
||||
// Bed cooled
|
||||
on_bed_cooled?: boolean;
|
||||
on_ha_sensor_alert?: boolean;
|
||||
// First layer complete
|
||||
on_first_layer_complete?: boolean;
|
||||
// Inventory stock alerts
|
||||
@@ -2728,6 +2799,7 @@ export interface NotificationProviderUpdate {
|
||||
on_plate_clear_required?: boolean;
|
||||
// Bed cooled
|
||||
on_bed_cooled?: boolean;
|
||||
on_ha_sensor_alert?: boolean;
|
||||
// First layer complete
|
||||
on_first_layer_complete?: boolean;
|
||||
// Inventory stock alerts
|
||||
@@ -5195,6 +5267,22 @@ export const api = {
|
||||
getHASensorEntities: () =>
|
||||
request<HASensorEntity[]>('/smart-plugs/ha/sensors'),
|
||||
|
||||
// Home Assistant sensors bound to a printer (#1148, #448)
|
||||
getHASensors: (printerId?: number) =>
|
||||
request<PrinterHASensor[]>(`/ha-sensors/${printerId ? `?printer_id=${printerId}` : ''}`),
|
||||
getHASensorReadings: (printerId: number) =>
|
||||
request<PrinterHASensorReading[]>(`/ha-sensors/by-printer/${printerId}/readings`),
|
||||
getBindableHAEntities: (search?: string) => {
|
||||
const params = search ? `?search=${encodeURIComponent(search)}` : '';
|
||||
return request<HADisplayEntity[]>(`/ha-sensors/entities${params}`);
|
||||
},
|
||||
createHASensor: (data: PrinterHASensorCreate) =>
|
||||
request<PrinterHASensor>('/ha-sensors/', { method: 'POST', body: JSON.stringify(data) }),
|
||||
updateHASensor: (id: number, data: PrinterHASensorUpdate) =>
|
||||
request<PrinterHASensor>(`/ha-sensors/${id}`, { method: 'PATCH', body: JSON.stringify(data) }),
|
||||
deleteHASensor: (id: number) =>
|
||||
request<{ message: string }>(`/ha-sensors/${id}`, { method: 'DELETE' }),
|
||||
|
||||
// REST smart plug
|
||||
testRESTConnection: (url: string, method: string = 'GET', headers?: string | null) =>
|
||||
request<{ success: boolean; error: string | null }>('/smart-plugs/rest/test-connection', {
|
||||
|
||||
Reference in New Issue
Block a user