feat: KoePi/Bestellungen/Presence Attribute erweitert - Details statt nur Zahlen
This commit is contained in:
@@ -234,6 +234,7 @@ function publishDiscovery() {
|
|||||||
name: '3D Bestellungen offen',
|
name: '3D Bestellungen offen',
|
||||||
unique_id: 'dickendock_bestellungen_offen',
|
unique_id: 'dickendock_bestellungen_offen',
|
||||||
state_topic: `${BASE_TOPIC}/druck/bestellungen_offen`,
|
state_topic: `${BASE_TOPIC}/druck/bestellungen_offen`,
|
||||||
|
json_attributes_topic: `${BASE_TOPIC}/druck/bestellungen_offen_attributes`,
|
||||||
icon: 'mdi:cube-send',
|
icon: 'mdi:cube-send',
|
||||||
unit_of_measurement: 'Bestellungen', state_class: 'measurement',
|
unit_of_measurement: 'Bestellungen', state_class: 'measurement',
|
||||||
availability_topic: AVAILABILITY_TOPIC, device: DEVICE,
|
availability_topic: AVAILABILITY_TOPIC, device: DEVICE,
|
||||||
@@ -362,14 +363,19 @@ function publishKoepiState({ offers, changed }) {
|
|||||||
if (!client?.connected) return;
|
if (!client?.connected) return;
|
||||||
const list = [...(offers || [])].sort((a, b) => parsePrice(a.price) - parsePrice(b.price));
|
const list = [...(offers || [])].sort((a, b) => parsePrice(a.price) - parsePrice(b.price));
|
||||||
|
|
||||||
let state = list.length
|
// State: nur die Anzahl (bleibt immer kurz und stabil) — die eigentlichen
|
||||||
? list.map(o => `${o.retailer}: ${o.price}`).join(' | ')
|
// Angebote stehen vollständig in den Attributen
|
||||||
|
const state = list.length ? `${list.length} Angebote` : 'keine Angebote';
|
||||||
|
|
||||||
|
// Lesbarer Mehrzeiler fürs Dashboard, zusätzlich zur strukturierten Liste
|
||||||
|
const listeText = list.length
|
||||||
|
? list.map(o => `${o.retailer}: ${o.price}${o.validity || o.dateRange ? ' (' + (o.validity || o.dateRange) + ')' : ''}`).join('\n')
|
||||||
: 'keine Angebote';
|
: 'keine Angebote';
|
||||||
if (state.length > 255) state = state.slice(0, 252) + '…';
|
|
||||||
|
|
||||||
client.publish(`${BASE_TOPIC}/koepi/state`, state, { retain: true });
|
client.publish(`${BASE_TOPIC}/koepi/state`, state, { retain: true });
|
||||||
client.publish(`${BASE_TOPIC}/koepi/attributes`, JSON.stringify({
|
client.publish(`${BASE_TOPIC}/koepi/attributes`, JSON.stringify({
|
||||||
angebote: list,
|
angebote: list,
|
||||||
|
liste_text: listeText,
|
||||||
anzahl: list.length,
|
anzahl: list.length,
|
||||||
letzter_check: new Date().toISOString(),
|
letzter_check: new Date().toISOString(),
|
||||||
}), { retain: true });
|
}), { retain: true });
|
||||||
@@ -383,12 +389,22 @@ function publishKoepiState({ offers, changed }) {
|
|||||||
// Wird jede Minute vom Scheduler in index.js aufgerufen
|
// Wird jede Minute vom Scheduler in index.js aufgerufen
|
||||||
function publishPresence() {
|
function publishPresence() {
|
||||||
if (!client?.connected) return;
|
if (!client?.connected) return;
|
||||||
const online = db.prepare(`
|
const alleNutzer = db.prepare(`
|
||||||
SELECT username FROM users WHERE last_active_at > datetime('now','localtime','-5 minutes')
|
SELECT username, last_active_at,
|
||||||
|
CASE WHEN last_active_at > datetime('now','localtime','-5 minutes') THEN 1 ELSE 0 END AS online
|
||||||
|
FROM users
|
||||||
|
ORDER BY last_active_at DESC
|
||||||
`).all();
|
`).all();
|
||||||
|
const online = alleNutzer.filter(u => !!u.online);
|
||||||
|
|
||||||
client.publish(`${BASE_TOPIC}/presence/state`, String(online.length), { retain: true });
|
client.publish(`${BASE_TOPIC}/presence/state`, String(online.length), { retain: true });
|
||||||
client.publish(`${BASE_TOPIC}/presence/attributes`, JSON.stringify({
|
client.publish(`${BASE_TOPIC}/presence/attributes`, JSON.stringify({
|
||||||
nutzer: online.map(u => u.username),
|
online: online.map(u => ({ benutzer: u.username, zuletzt_aktiv: u.last_active_at })),
|
||||||
|
alle_nutzer: alleNutzer.map(u => ({
|
||||||
|
benutzer: u.username,
|
||||||
|
zuletzt_aktiv: u.last_active_at,
|
||||||
|
online: !!u.online,
|
||||||
|
})),
|
||||||
}), { retain: true });
|
}), { retain: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,6 +511,14 @@ function publishDruckStatistik() {
|
|||||||
}
|
}
|
||||||
const offen = allOrders.length - byStatus.abgeschlossen;
|
const offen = allOrders.length - byStatus.abgeschlossen;
|
||||||
|
|
||||||
|
// Konkrete offene Bestellungen (nicht abgeschlossen) mit Besitzer, für die Attribute
|
||||||
|
const offeneBestellungen = db.prepare(`
|
||||||
|
SELECT o.id, o.name, o.status, o.bezahlt, o.abgeholt, o.created_at, u.username
|
||||||
|
FROM orders o JOIN users u ON u.id = o.user_id
|
||||||
|
WHERE NOT (o.bezahlt = 1 AND o.abgeholt = 1)
|
||||||
|
ORDER BY o.created_at DESC
|
||||||
|
`).all();
|
||||||
|
|
||||||
const pub = (topic, val) => client.publish(`${BASE_TOPIC}/${topic}`, String(val), { retain: true });
|
const pub = (topic, val) => client.publish(`${BASE_TOPIC}/${topic}`, String(val), { retain: true });
|
||||||
pub('druck/umsatz_monat', round2(umsatzMonat));
|
pub('druck/umsatz_monat', round2(umsatzMonat));
|
||||||
pub('druck/umsatz_gesamt', round2(umsatzGesamt));
|
pub('druck/umsatz_gesamt', round2(umsatzGesamt));
|
||||||
@@ -507,6 +531,9 @@ function publishDruckStatistik() {
|
|||||||
pub('druck/nettogewinn_monat', round2(nettoMonat));
|
pub('druck/nettogewinn_monat', round2(nettoMonat));
|
||||||
pub('druck/nettogewinn_gesamt', round2(nettoGesamt));
|
pub('druck/nettogewinn_gesamt', round2(nettoGesamt));
|
||||||
pub('druck/bestellungen_offen', offen);
|
pub('druck/bestellungen_offen', offen);
|
||||||
|
client.publish(`${BASE_TOPIC}/druck/bestellungen_offen_attributes`, JSON.stringify({
|
||||||
|
bestellungen: offeneBestellungen,
|
||||||
|
}), { retain: true });
|
||||||
pub('druck/bestellungen_warteliste', byStatus.warteliste);
|
pub('druck/bestellungen_warteliste', byStatus.warteliste);
|
||||||
pub('druck/bestellungen_in_arbeit', byStatus.in_arbeit);
|
pub('druck/bestellungen_in_arbeit', byStatus.in_arbeit);
|
||||||
pub('druck/bestellungen_fertig', byStatus.fertig);
|
pub('druck/bestellungen_fertig', byStatus.fertig);
|
||||||
|
|||||||
Reference in New Issue
Block a user