feat(ha): enrich ha_sensor with opened_items, shopping_total, price_tracking, expiring_3d
This commit is contained in:
+50
-10
@@ -1396,6 +1396,42 @@ function haInventorySensor(PDO $db): void {
|
|||||||
ORDER BY i.expiry_date ASC LIMIT 10"
|
ORDER BY i.expiry_date ASC LIMIT 10"
|
||||||
)->fetchAll(PDO::FETCH_ASSOC);
|
)->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
// Opened items
|
||||||
|
$openedItems = (int)$db->query(
|
||||||
|
"SELECT COUNT(*) FROM inventory WHERE quantity > 0 AND opened_at IS NOT NULL"
|
||||||
|
)->fetchColumn();
|
||||||
|
|
||||||
|
// Fixed 3-day expiry count (always 3 days, regardless of expiry_days param)
|
||||||
|
$expiring3d = ($expiryDays === 3)
|
||||||
|
? $expiring
|
||||||
|
: (int)$db->query(
|
||||||
|
"SELECT COUNT(*) FROM inventory WHERE quantity > 0 AND expiry_date IS NOT NULL
|
||||||
|
AND expiry_date BETWEEN date('now') AND date('now', '+3 days')"
|
||||||
|
)->fetchColumn();
|
||||||
|
|
||||||
|
// Shopping total from server-side total cache (max 1 hour old)
|
||||||
|
$priceEnabled = env('PRICE_ENABLED', 'false') === 'true';
|
||||||
|
$priceCurrency = env('PRICE_CURRENCY', 'EUR');
|
||||||
|
$shoppingTotal = null;
|
||||||
|
if ($priceEnabled) {
|
||||||
|
$totalCachePath = __DIR__ . '/../data/shopping_total_cache.json';
|
||||||
|
if (file_exists($totalCachePath)) {
|
||||||
|
$tc = json_decode(file_get_contents($totalCachePath), true) ?? [];
|
||||||
|
// Find the most recent entry not older than 1 hour
|
||||||
|
$best = null;
|
||||||
|
$bestTs = 0;
|
||||||
|
foreach ($tc as $entry) {
|
||||||
|
if (isset($entry['ts']) && $entry['ts'] > $bestTs) {
|
||||||
|
$bestTs = $entry['ts'];
|
||||||
|
$best = $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($best && (time() - $bestTs) < 3600) {
|
||||||
|
$shoppingTotal = round((float)($best['result']['total'] ?? 0), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$stateValue = match($sensor) {
|
$stateValue = match($sensor) {
|
||||||
'expired' => $expired,
|
'expired' => $expired,
|
||||||
'shopping' => $shoppingCount,
|
'shopping' => $shoppingCount,
|
||||||
@@ -1406,21 +1442,25 @@ function haInventorySensor(PDO $db): void {
|
|||||||
echo json_encode([
|
echo json_encode([
|
||||||
'state' => $stateValue,
|
'state' => $stateValue,
|
||||||
'attributes' => [
|
'attributes' => [
|
||||||
'expiring_soon' => $expiring,
|
'expiring_soon' => $expiring,
|
||||||
'expiring_3d' => $expiring,
|
'expiring_3d' => $expiring3d,
|
||||||
'expired_items' => $expired,
|
'expired_items' => $expired,
|
||||||
'total_items' => $total,
|
'total_items' => $total,
|
||||||
'shopping_items' => $shoppingCount,
|
'opened_items' => $openedItems,
|
||||||
'expiring_list' => array_map(fn($r) => [
|
'shopping_items' => $shoppingCount,
|
||||||
|
'shopping_total' => $shoppingTotal,
|
||||||
|
'price_tracking_enabled' => $priceEnabled,
|
||||||
|
'price_currency' => $priceCurrency,
|
||||||
|
'expiring_list' => array_map(fn($r) => [
|
||||||
'name' => $r['name'],
|
'name' => $r['name'],
|
||||||
'quantity' => (float)$r['quantity'],
|
'quantity' => (float)$r['quantity'],
|
||||||
'unit' => $r['unit'],
|
'unit' => $r['unit'],
|
||||||
'expiry_date'=> $r['expiry_date'],
|
'expiry_date'=> $r['expiry_date'],
|
||||||
], $expiringItems),
|
], $expiringItems),
|
||||||
'unit_of_measurement'=> 'items',
|
'unit_of_measurement' => 'items',
|
||||||
'friendly_name' => 'EverShelf Pantry',
|
'friendly_name' => 'EverShelf Pantry',
|
||||||
'icon' => 'mdi:fridge',
|
'icon' => 'mdi:fridge',
|
||||||
'last_updated' => date('c'),
|
'last_updated' => date('c'),
|
||||||
],
|
],
|
||||||
], JSON_UNESCAPED_UNICODE);
|
], JSON_UNESCAPED_UNICODE);
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user