Skip to content

Commit 3e30568

Browse files
committed
controller start: not done or tested
1 parent eb2dcbf commit 3e30568

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from enum import StrEnum
2+
from chip import ChipDeviceCtrl
3+
import chip.clusters as Clusters
4+
5+
6+
class Bottle(StrEnum):
7+
kBourbon = "bourbon"
8+
kGin = "gin"
9+
kCampari = "campari"
10+
kVermouth = "vermouth"
11+
kSourMix = "sour mix"
12+
kSimpleSyrup = "simple syrup",
13+
14+
# One once == approx 12s.
15+
16+
17+
class Oz:
18+
def __init__(self, oz: float):
19+
self.oz = oz
20+
21+
def time(self):
22+
return self.oz * 12
23+
24+
25+
class DrinkMachine:
26+
def __init__(self, devCtrl: ChipDeviceCtrl, node_id: int):
27+
self.dev_ctrl = devCtrl
28+
self.node_id = node_id
29+
# TODO: Should this actually be modelled as an aggregator with bridged nodes so I can have a nodelabel?
30+
# Right now I'm going to leave this as something on the app side because it's a demo, but it's weird that we don't have writeable labels unless you model it strangely. Spec issue?
31+
self.bottles: dict[Bottle, int] = {Bottle.kBourbon: 1, Bottle.kGin: 2,
32+
Bottle.kCampari: 3, Bottle.kVermouth: 4, Bottle.kSourMix: 5, Bottle.kSimpleSyrup: 6}
33+
self.recipes: dict[str, dict[Bottle, Oz]] = {}
34+
self.add_recipe("negroni", {Bottle.kGin: Oz(1.5), Bottle.kCampari: Oz(1.5), Bottle.kVermouth: Oz(1.5)})
35+
self.add_recipe("boulevardier", {Bottle.kBourbon: Oz(1.5), Bottle.kCampari: Oz(1.5), Bottle.kVermouth: Oz(1.5)})
36+
self.add_recipe("bourbon sour", {Bottle.kBourbon: Oz(2), Bottle.kSourMix: Oz(1), Bottle.kSimpleSyrup: Oz(1.5)})
37+
self.add_recipe("martini", {Bottle.kGin: Oz(2), Bottle.kVermouth: Oz(0.25)})
38+
self.add_recipe("gimlet", {Bottle.kGin: Oz(2.5), Bottle.kSourMix: Oz(0.5), Bottle.kSimpleSyrup: Oz(0.5)})
39+
self.add_recipe("old fashioned", {Bottle.kBourbon: Oz(2), Bottle.kSimpleSyrup: Oz(0.125)})
40+
41+
def set_bottle_names(self, bottles: dict[Bottle, int]) -> bool:
42+
''' Bottle is a dict of bottle name to endpoint and should contain all 6 endpoints at once'''
43+
if len(bottles) != 6:
44+
return False
45+
self.bottles = bottles
46+
47+
def get_bottle_names(self):
48+
return self.Bottle
49+
50+
def add_recipe(self, name: str, ingredients: dict[Bottle, Oz]):
51+
# TODO: should store somewhere permanent - simplest is to write out to file. In the meanwhile, we have a few pre-populated
52+
self.recipes[name] = ingredients
53+
54+
async def dispense(self, recipe: str):
55+
# TODO: be a bit nicer on the comparison here. Strings as keys aren't great, but I want the flexibility to add non-standard recipes
56+
if recipe not in self.recipes.keys():
57+
print(f"Unable to find the specified recipe. Available Recipes: {self.recipes.keys()}")
58+
return
59+
required_bottles = set(self.recipes[recipe].keys())
60+
if not required_bottles.issubset(set(self.bottles)):
61+
print('Recipe requires an ingredient that is not loaded into the drink machine')
62+
print(f'Recipe requires: {required_bottles}')
63+
print(f'Availble: {self.bottles}')
64+
return
65+
66+
ingredients = self.recipes[recipe]
67+
for bottle, amount in ingredients.items():
68+
ep = self.bottles[bottle]
69+
time = amount.time()
70+
await self.dev_ctrl.SendCommand(nodeid=self.node_id, endpoint=ep,
71+
payload=Clusters.ValveConfigurationAndControl.Commands.Open(openDuration=time))

0 commit comments

Comments
 (0)