package fridge import ( "context" "errors" "fmt" "io" "strings" "time" "git.t-juice.club/torjus/oubliette/internal/shell" ) const sessionTimeout = 5 * time.Minute // FridgeShell emulates a Samsung Smart Fridge OS interface. type FridgeShell struct{} // NewFridgeShell returns a new FridgeShell instance. func NewFridgeShell() *FridgeShell { return &FridgeShell{} } func (f *FridgeShell) Name() string { return "fridge" } func (f *FridgeShell) Description() string { return "Samsung Smart Fridge shell emulator" } func (f *FridgeShell) Handle(ctx context.Context, sess *shell.SessionContext, rw io.ReadWriteCloser) error { ctx, cancel := context.WithTimeout(ctx, sessionTimeout) defer cancel() state := newFridgeState() // Boot banner. fmt.Fprint(rw, bootBanner()) for { if _, err := fmt.Fprint(rw, "FridgeOS> "); err != nil { return nil } line, err := shell.ReadLine(ctx, rw) if errors.Is(err, io.EOF) { fmt.Fprint(rw, "logout\r\n") return nil } if err != nil { return nil } trimmed := strings.TrimSpace(line) if trimmed == "" { continue } result := state.dispatch(trimmed) var output string if result.output != "" { output = result.output output = strings.ReplaceAll(output, "\r\n", "\n") output = strings.ReplaceAll(output, "\n", "\r\n") fmt.Fprintf(rw, "%s\r\n", output) } // Log command and output to store. if sess.Store != nil { if err := sess.Store.AppendSessionLog(ctx, sess.SessionID, trimmed, output); err != nil { return fmt.Errorf("append session log: %w", err) } } if result.exit { return nil } } } func bootBanner() string { now := time.Now() defrost := now.Add(-3*time.Hour - 22*time.Minute).Format("2006-01-02 15:04") return fmt.Sprintf(` _____ ____ ___ ____ ____ _____ ___ ____ | ___| _ \|_ _| _ \ / ___| ____/ _ \/ ___| | |_ | |_) || || | | | | _| _|| | | \___ \ | _| | _ < | || |_| | |_| | |__| |_| |___) | |_| |_| \_\___|____/ \____|_____\___/|____/ Samsung Smart Fridge OS v3.2.1 (FridgeOS-ARM) Model: RF28R7351SR | Serial: SN-2847-FRDG-9182 Firmware: 3.2.1-stable | Last defrost: %s Type 'help' for available commands. `, defrost) } type fridgeState struct { inventory []inventoryItem fridgeF int // fridge temp in °F freezerF int // freezer temp in °F } type inventoryItem struct { name string expiry string } type commandResult struct { output string exit bool } func newFridgeState() *fridgeState { return &fridgeState{ inventory: []inventoryItem{ {"Whole Milk (1 gal)", time.Now().Add(48 * time.Hour).Format("2006-01-02")}, {"Eggs (dozen)", time.Now().Add(7 * 24 * time.Hour).Format("2006-01-02")}, {"Leftover Pizza (3 slices)", time.Now().Add(24 * time.Hour).Format("2006-01-02")}, {"Orange Juice", time.Now().Add(5 * 24 * time.Hour).Format("2006-01-02")}, {"Butter (unsalted)", time.Now().Add(30 * 24 * time.Hour).Format("2006-01-02")}, {"Mystery Tupperware", time.Now().Add(-14 * 24 * time.Hour).Format("2006-01-02")}, }, fridgeF: 37, freezerF: 0, } } func (s *fridgeState) dispatch(input string) commandResult { parts := strings.Fields(input) if len(parts) == 0 { return commandResult{} } cmd := strings.ToLower(parts[0]) args := parts[1:] switch cmd { case "help": return s.cmdHelp() case "inventory": return s.cmdInventory(args) case "temp", "temperature": return s.cmdTemp(args) case "status": return s.cmdStatus() case "diagnostics": return s.cmdDiagnostics() case "alerts": return s.cmdAlerts() case "reboot": return s.cmdReboot() case "exit", "logout": return commandResult{output: "Goodbye! Keep your food fresh!", exit: true} default: return commandResult{output: fmt.Sprintf("FridgeOS: unknown command '%s'. Type 'help' for available commands.", cmd)} } } func (s *fridgeState) cmdHelp() commandResult { help := `Available commands: help - Show this help message inventory - List fridge contents inventory add - Add item to inventory inventory remove - Remove item from inventory temp - Show current temperatures temp set - Set temperature (zone: fridge|freezer) status - Show system status diagnostics - Run system diagnostics alerts - Show active alerts reboot - Reboot FridgeOS exit / logout - Disconnect` return commandResult{output: help} } func (s *fridgeState) cmdInventory(args []string) commandResult { if len(args) == 0 || strings.ToLower(args[0]) == "list" { return s.inventoryList() } sub := strings.ToLower(args[0]) switch sub { case "add": if len(args) < 2 { return commandResult{output: "Usage: inventory add "} } item := strings.Join(args[1:], " ") return s.inventoryAdd(item) case "remove": if len(args) < 2 { return commandResult{output: "Usage: inventory remove "} } item := strings.Join(args[1:], " ") return s.inventoryRemove(item) default: return commandResult{output: fmt.Sprintf("Unknown inventory subcommand '%s'. Try: list, add, remove", sub)} } } func (s *fridgeState) inventoryList() commandResult { if len(s.inventory) == 0 { return commandResult{output: "Inventory is empty."} } var b strings.Builder b.WriteString("=== Fridge Inventory ===\n") b.WriteString(fmt.Sprintf("%-30s %s\n", "ITEM", "EXPIRES")) b.WriteString(fmt.Sprintf("%-30s %s\n", "----", "-------")) for _, item := range s.inventory { b.WriteString(fmt.Sprintf("%-30s %s\n", item.name, item.expiry)) } b.WriteString(fmt.Sprintf("\nTotal items: %d", len(s.inventory))) return commandResult{output: b.String()} } func (s *fridgeState) inventoryAdd(item string) commandResult { expiry := time.Now().Add(7 * 24 * time.Hour).Format("2006-01-02") s.inventory = append(s.inventory, inventoryItem{name: item, expiry: expiry}) return commandResult{output: fmt.Sprintf("Added '%s' to inventory (expires: %s).", item, expiry)} } func (s *fridgeState) inventoryRemove(item string) commandResult { lower := strings.ToLower(item) for i, inv := range s.inventory { if strings.ToLower(inv.name) == lower || strings.Contains(strings.ToLower(inv.name), lower) { s.inventory = append(s.inventory[:i], s.inventory[i+1:]...) return commandResult{output: fmt.Sprintf("Removed '%s' from inventory.", inv.name)} } } return commandResult{output: fmt.Sprintf("Item '%s' not found in inventory.", item)} } func (s *fridgeState) cmdTemp(args []string) commandResult { if len(args) == 0 { return commandResult{output: fmt.Sprintf( "=== Temperature Status ===\nFridge: %d°F (%.1f°C)\nFreezer: %d°F (%.1f°C)", s.fridgeF, fToC(s.fridgeF), s.freezerF, fToC(s.freezerF), )} } if strings.ToLower(args[0]) != "set" || len(args) < 3 { return commandResult{output: "Usage: temp set "} } zone := strings.ToLower(args[1]) var val int if _, err := fmt.Sscanf(args[2], "%d", &val); err != nil { return commandResult{output: "Invalid temperature value. Must be an integer."} } switch zone { case "fridge": if val < 33 || val > 45 { return commandResult{output: fmt.Sprintf("WARNING: Temperature %d°F is out of safe range (33-45°F). Setting rejected.", val)} } s.fridgeF = val return commandResult{output: fmt.Sprintf("Fridge temperature set to %d°F (%.1f°C).", val, fToC(val))} case "freezer": if val < -10 || val > 10 { return commandResult{output: fmt.Sprintf("WARNING: Temperature %d°F is out of safe range (-10 to 10°F). Setting rejected.", val)} } s.freezerF = val return commandResult{output: fmt.Sprintf("Freezer temperature set to %d°F (%.1f°C).", val, fToC(val))} default: return commandResult{output: fmt.Sprintf("Unknown zone '%s'. Use 'fridge' or 'freezer'.", zone)} } } func fToC(f int) float64 { return float64(f-32) * 5.0 / 9.0 } func (s *fridgeState) cmdStatus() commandResult { status := `=== FridgeOS System Status === Compressor: Running Door seal: OK Ice maker: Active Water filter: 82% remaining WiFi: Connected (SmartHome-5G) Signal: -42 dBm Internal camera: Online (3 objects detected) Voice assistant: Standby TikTok recipes: Enabled Spotify: "Chill Vibes" playlist paused Energy rating: A++ Power: 127W SmartHome Hub: Connected (12 devices) Firmware: v3.2.1-stable Update available: v3.3.0-beta` return commandResult{output: status} } func (s *fridgeState) cmdDiagnostics() commandResult { diag := `Running FridgeOS diagnostics... [1/6] Compressor.............. OK [2/6] Temperature sensors..... OK [3/6] Door seal integrity..... OK [4/6] Ice maker............... OK [5/6] Network connectivity.... OK [6/6] Internal camera......... OK ALL SYSTEMS NOMINAL` return commandResult{output: diag} } func (s *fridgeState) cmdAlerts() commandResult { // Build dynamic alerts based on inventory. var alerts []string for _, item := range s.inventory { expiry, err := time.Parse("2006-01-02", item.expiry) if err != nil { continue } days := int(time.Until(expiry).Hours() / 24) if days < 0 { alerts = append(alerts, fmt.Sprintf("CRITICAL: %s expired %d day(s) ago!", item.name, -days)) } else if days <= 2 { alerts = append(alerts, fmt.Sprintf("WARNING: %s expires in %d day(s)", item.name, days)) } } alerts = append(alerts, "INFO: Ice maker: low water pressure detected", "INFO: Firmware update available: v3.3.0-beta", "INFO: TikTok recipe sync overdue (last sync: 3 days ago)", ) var b strings.Builder b.WriteString("=== Active Alerts ===\n") for _, a := range alerts { b.WriteString(a + "\n") } b.WriteString(fmt.Sprintf("\n%d alert(s) active", len(alerts))) return commandResult{output: b.String()} } func (s *fridgeState) cmdReboot() commandResult { reboot := `FridgeOS is rebooting... Stopping services........... done Saving inventory data....... done Flushing temperature log.... done Unmounting partitions....... done Rebooting now. Goodbye!` return commandResult{output: reboot, exit: true} }