1
+ import random
2
+
1
3
from enum import StrEnum
2
4
from chip import ChipDeviceCtrl
3
5
from chip .clusters .Types import NullValue
4
6
import chip .clusters as Clusters
5
7
6
8
9
+ MYSTERY_DRINK = "mystery mirrorball"
10
+
11
+
7
12
class Bottle (StrEnum ):
8
13
kBourbon = "bourbon"
9
14
kGin = "gin"
@@ -21,6 +26,12 @@ def time(self):
21
26
# One oz == approx 12s.
22
27
return self .oz * 12
23
28
29
+ def __eq__ (self , other ):
30
+ return self .oz == other .oz
31
+
32
+ def __lt__ (self , other ):
33
+ return self .oz < other .oz
34
+
24
35
25
36
class DrinkMachine :
26
37
def __init__ (self , devCtrl : ChipDeviceCtrl , node_id : int ):
@@ -39,6 +50,11 @@ def __init__(self, devCtrl: ChipDeviceCtrl, node_id: int):
39
50
self .add_recipe ("old fashioned" , {Bottle .kBourbon : Oz (2 ), Bottle .kSimpleSyrup : Oz (0.125 )})
40
51
self .add_recipe ("shot of bourbon" , {Bottle .kBourbon : Oz (1.5 )})
41
52
self .add_recipe ("shot of gin" , {Bottle .kGin : Oz (1.5 )})
53
+ self .add_recipe ("gin sour" , {Bottle .kGin : Oz (2 ), Bottle .kSourMix : Oz (1 ), Bottle .kSimpleSyrup : Oz (0.5 )})
54
+ self .add_recipe ("manhattan" , {Bottle .kBourbon : Oz (2 ), Bottle .kVermouth : Oz (1 )})
55
+ self .add_recipe ("campari sour" , {Bottle .kGin : Oz (1 ), Bottle .kCampari : Oz (1 ),
56
+ Bottle .kSourMix : Oz (0.75 ), Bottle .kSimpleSyrup : Oz (0.5 )})
57
+ self .add_recipe (MYSTERY_DRINK , {})
42
58
43
59
def set_bottle_names (self , bottles : dict [Bottle , int ]) -> bool :
44
60
''' Bottle is a dict of bottle name to endpoint and should contain all 6 endpoints at once'''
@@ -56,7 +72,50 @@ def add_recipe(self, name: str, ingredients: dict[Bottle, Oz]):
56
72
# TODO: should store somewhere permanent - simplest is to write out to file. In the meanwhile, we have a few pre-populated
57
73
self .recipes [name ] = ingredients
58
74
75
+ async def _dispense_mystery (self ):
76
+ num_ingredients = random .randint (1 , 3 )
77
+ bottles = set ()
78
+ choice = random .choice (list (Bottle ))
79
+ bottles .add (choice )
80
+ while len (bottles ) < num_ingredients :
81
+ # If this matches something in the bottle list already, it won't be added
82
+ choice = random .choice (list (Bottle ))
83
+ bottles .add (choice )
84
+
85
+ # we're going to aim for a 2.5 Oz shot with min 0.5 shot sizes
86
+ goal = 2.5
87
+ print (f"Creating your mystery beverage:" )
88
+ ingredients = {}
89
+ total = 0
90
+ for bottle in bottles :
91
+ remaining = num_ingredients - len (ingredients .keys ())
92
+ if remaining == 1 :
93
+ oz = goal - total
94
+ else :
95
+ max_oz = goal - total - 0.5 * (remaining - 1 )
96
+ # multiply by 2 because randrange likes ints
97
+ oz = random .randrange (1 , max_oz * 2 , 1 )/ 2
98
+ total += oz
99
+ ingredients [bottle ] = Oz (oz )
100
+ print (f"\t { oz } Oz of { bottle } " )
101
+
102
+ largest = max (ingredients , key = ingredients .get )
103
+ mystery_prefix = ['' , 'giant' , 'potent' , 'disco-tastic' , 'shiny' , 'Dr.' ]
104
+ mystery_suffix = ['blaster' , 'concoction' , 'blend' , 'cocktail' ]
105
+ mystery_extra_suffix = ['' , 'jr' , 'of wonder' , 'esq' ]
106
+ name = []
107
+ name .append (random .choice (mystery_prefix ))
108
+ name .append (largest )
109
+ name .append (random .choice (mystery_suffix ))
110
+ name .append (random .choice (mystery_extra_suffix ))
111
+ print (f'The { " " .join (name ).strip ()} ' )
112
+ print ('Please enjoy responsibly.' )
113
+ await self ._dispense_ingredients (ingredients )
114
+
59
115
async def dispense (self , recipe : str ):
116
+ if recipe == MYSTERY_DRINK :
117
+ return await self ._dispense_mystery ()
118
+
60
119
# 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
61
120
if recipe not in self .recipes .keys ():
62
121
print (f"Unable to find the specified recipe. Available Recipes: { self .recipes .keys ()} " )
@@ -69,6 +128,9 @@ async def dispense(self, recipe: str):
69
128
return
70
129
71
130
ingredients = self .recipes [recipe ]
131
+ self ._dispense_ingredients (ingredients )
132
+
133
+ async def _dispense_ingredients (self , ingredients : dict [Bottle , Oz ]):
72
134
for bottle , amount in ingredients .items ():
73
135
ep = self .bottles [bottle ]
74
136
time = amount .time ()
0 commit comments