""" Real world sample client demonstrating use of geckolib Python async suffers like many interpreted languages with function colour see: http://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ To avoid this, the geckolib is written using synchronous functions and methodologies, but using threading to manage the I/O portions. Where appropriate, state flags are exposed so that you can use async clients to ensure that your host is still responsive and I don't have to maintain two versions of the library ... ugh!""" import time import json from geckolib import GeckoLocator # Replace with your own UUID, see https://www.uuidgenerator.net/> CLIENT_ID = "ca3fd7f4-f96f-4b13-bf9e-69e9725a3c92" def state(spaIdentifier): print(f" - Using spa identifier : {spaIdentifier} for client id : {CLIENT_ID}") facade = GeckoLocator.find_spa(CLIENT_ID, spaIdentifier).get_facade(False) print(f" * Connecting to {facade.name} ", end="", flush=True) while not facade.is_connected: # Could also be `await asyncio.sleep(1)` facade.wait(1) print(".", end="", flush=True) #spa={} #spa['name']=facade.name #spa['id']=facade.identifier #spa['cmds']=[] cmds=[] print(" connected") #print(f" - Watercare mode : {facade.water_care.mode} ;list: {facade.water_care.modes}") cmdWaterCare={} cmdWaterCare['name'] = 'water_care' cmdWaterCare['state'] = facade.water_care.mode cmdWaterCare['stateList'] = facade.water_care.modes cmds.append(cmdWaterCare) #print(f" - Lights mode : {len(facade.lights)} |{facade.lights[0].is_on}") for i in range(len(facade.lights)): cmdLights = {} cmdLights['name'] = "lights_" + str(i) cmdLights['state'] = facade.lights[i].is_on cmds.append(cmdLights) #print(f" - Heater : {facade.water_heater.min_temp} | {facade.water_heater.max_temp} | {facade.water_heater.current_temperature} | {facade.water_heater.temperature_unit} ") cmdHeater={} cmdHeater['name'] = 'water_heater' cmdHeater['min_temp'] = facade.water_heater.min_temp cmdHeater['max_temp'] = facade.water_heater.max_temp cmdHeater['current_temp'] = facade.water_heater.current_temperature cmdHeater['unit'] = facade.water_heater.temperature_unit cmds.append(cmdHeater) #print(f" - Pump : {len(facade.pumps)} | {facade.pumps[0].is_on} | {facade.pumps[0].mode} | {facade.pumps[0].modes} ") for i in range(len(facade.pumps)): cmdPumps={} cmdPumps['name'] = "pumps_" + str(i) cmdPumps['state'] = facade.pumps[i].is_on cmdPumps['state'] = facade.pumps[i].mode cmdPumps['stateList'] = facade.pumps[i].modes cmds.append(cmdPumps) #print(f"Response : {json.dumps(spa)}") facade.complete() return cmds # First up, lets locate all the spas on your network print("Locating spas on your network ", end="", flush=True) locator = GeckoLocator(CLIENT_ID) locator.start_discovery() # We can perform other operations while this is progressing, like output a dot while not locator.has_had_enough_time: # Could also be `await asyncio.sleep(1)` locator.wait(1) print(".", end="", flush=True) locator.complete() # Report how many we've found print(f" found {len(locator.spas)} spas") if len(locator.spas) == 0: raise RuntimeError("Cannot continue as there were no spas detected") # Grasp info about your spa, this is often the integration phase in your # automation system, sometimes you can store binary identifiers, sometimes # you can't ... response={} response['spas']=[] for i in range(len(locator.spas)): spa={} spa['name']=locator.spas[i].name spa['id']=locator.spas[i].identifier_as_string #spa['cmds']=[] #spa['cmds'].append(state({locator.spas[i].identifier_as_string})) spa['cmds']=state({locator.spas[i].identifier_as_string}) response['spas'].append(spa) print(f"ResponseState|{json.dumps(response)}") #persistent_spa_identifier = locator.spas[0].identifier_as_string #print(f"Using spa identifier : {persistent_spa_identifier}") # Some time later, when we want to start the automation system but don't # want to choose the spa again, we do something like this ... #facade = GeckoLocator.find_spa(CLIENT_ID, persistent_spa_identifier).get_facade(False) # Now we have a facade, wait for it to be connected #print(f"Connecting to {facade.name} ", end="", flush=True) #while not facade.is_connected: # Could also be `await asyncio.sleep(1)` # facade.wait(1) # print(".", end="", flush=True) #print(" connected") # Do some things with the facade #print(f"Water heater : {facade.water_heater}") def pump_1_change(sender, old_value, new_value): print(f"Pump 1 changed from {old_value} to {new_value}") # Watch pump 1 for changes and report on them #facade.pumps[0].watch(pump_1_change) #print("Turn pump 1 on") #facade.pumps[0].set_mode('HI') #time.sleep(5) #print("Turning pump 1 off") #facade.pumps[0].set_mode('OFF') #light -> lights #is_on #turn_on #turn_off #heater -> water_heate #min_temp #max_temp #current_temperature #temperature_unit #pump -> pumps #is_on #modes #mode #set_mode #time.sleep(2) #facade.complete()