gazoodle / geckolib Goto Github PK
View Code? Open in Web Editor NEWLibrary to interface with Gecko Alliance spa pack systems via in.touch2 module
License: GNU General Public License v3.0
Library to interface with Gecko Alliance spa pack systems via in.touch2 module
License: GNU General Public License v3.0
Hi,
I'm trying to use geckolib to change the watercare mode. I was successfull to adpot the example script and it works in the most calls, but sometimes it has a problem during connection esteblishment. So I decided to add some code to catch the error an call async_reset() but it won't work as expected. Because I use Python-language not very often, I would ask for help/suggestions. What I also need to say is, that there is another script running in background every minute that connects in the same manner and read's out some values and writes them away.
I created the following code, it's the "Async API Usage"-expamle with an modified main()-function:
async def main() -> None:
async with SampleSpaMan(CLIENT_ID, spa_identifier=SPA_ID) as spaman:
print("Looking for spas on your network ...")
connectAttemptCount = 0
connectSuccess = False
while not connectSuccess and connectAttemptCount < 2:
try:
print(f"*** connecting to spa (attempt: {connectAttemptCount + 1})")
# Wait for descriptors to be available
await spaman.wait_for_descriptors()
if len(spaman.spa_descriptors) == 0:
print("*** there were no spas found on your network.")
quit(-1)
await spaman.async_connect(spa_identifier=SPA_ID)
# Wait for the facade to be ready
await spaman.wait_for_facade()
currentWatercareMode = spaman.facade.water_care.active_mode
except Exception as e:
print(e)
print(f"error: unable to connect to spa: {SPA_ID}")
connectAttemptCount = connectAttemptCount + 1
# reset spaman
await spaman.async_reset()
else:
print("*** connection successfull created")
connectSuccess = True
if not connectSuccess:
print(f"error: unable to connect to spa controller after {connectAttemptCount - 1} attempts")
quit(-1)
# set water care mode
await spaman.facade.water_care.async_set_mode(spaman.facade.water_care.modes[0])
# ende
print("*** end")
return
If the connection error happens to log is (canceled by ctrl-c):
GeckoSpaEvent.SPA_MAN_ENTER: {}
Looking for spas on your network ...
*** connecting to spa (attempt: 1)
GeckoSpaEvent.LOCATING_STARTED: {}
GeckoSpaEvent.LOCATING_DISCOVERED_SPA: {'spa_descriptor': Whirlpool Rico(SPA68:aa:bb:cc:dd:ee)}
GeckoSpaEvent.LOCATING_DISCOVERED_SPA: {'spa_descriptor': SwimSpa Peggy(SPA68:aa:bb:cc:dd:ff)}
2023-02-26 18:23:07,538> INFO Found 2 spas ... [Whirlpool Rico(SPA68:aa:bb:cc:dd:ee), SwimSpa Peggy(SPA68:aa:bb:cc:dd:ff)]
GeckoSpaEvent.LOCATING_FINISHED: {'spa_descriptors': [Whirlpool Rico(SPA68:aa:bb:cc:dd:ee), SwimSpa Peggy(SPA68:aa:bb:cc:dd:ff)]}
GeckoSpaEvent.LOCATING_STARTED: {}
GeckoSpaEvent.LOCATING_STARTED: {}
GeckoSpaEvent.LOCATING_DISCOVERED_SPA: {'spa_descriptor': SwimSpa Peggy(SPA68:aa:bb:cc:dd:ff)}
GeckoSpaEvent.LOCATING_FINISHED: {'spa_descriptors': [SwimSpa Peggy(SPA68:aa:bb:cc:dd:ff)]}
GeckoSpaEvent.CLIENT_HAS_STATUS_SENSOR: {}
GeckoSpaEvent.CLIENT_HAS_RECONNECT_BUTTON: {}
GeckoSpaEvent.CONNECTION_STARTED: {}
GeckoSpaEvent.RUNNING_PING_RECEIVED: {'last_ping_at': datetime.datetime(2023, 2, 26, 17, 23, 7, 576750, tzinfo=datetime.timezone.utc)}
GeckoSpaEvent.CONNECTION_GOT_FIRMWARE_VERSION: {'intouch_version_en': '88 v15.0', 'intouch_version_co': '89 v11.0'}
GeckoSpaEvent.CLIENT_HAS_PING_SENSOR: {}
GeckoSpaEvent.CONNECTION_GOT_CHANNEL: {'channel': 31, 'signal': 94}
GeckoSpaEvent.CONNECTION_GOT_CONFIG_FILES: {'plateform_key': 'inyt', 'config_version': 65, 'log_version': 66}
GeckoSpaEvent.CONNECTION_INITIAL_DATA_BLOCK_REQUEST: {}
GeckoSpaEvent.LOCATING_FINISHED: {'spa_descriptors': []}
GeckoSpaEvent.SPA_NOT_FOUND: {'spa_address': None, 'spa_identifier': 'SPA68:aa:bb:cc:dd:ff'}
'NoneType' object has no attribute 'water_care'
error: unable to connect to spa: SPA68:aa:bb:cc:dd:ff
GeckoSpaEvent.RUNNING_SPA_DISCONNECTED: {}
*** connecting to spa (attempt: 2)
2023-02-26 18:23:21,487> ERROR Exception during spa connection
Traceback (most recent call last):
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 367, in connect
await self._connect()
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 334, in _connect
if not await self.struct.get(
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/driver/async_spastruct.py", line 64, in get
request = create_func()
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 337, in <lambda>
self._protocol.get_and_increment_sequence_counter(False),
AttributeError: 'NoneType' object has no attribute 'get_and_increment_sequence_counter'
GeckoSpaEvent.CONNECTION_FINISHED: {'facade': None}
2023-02-26 18:24:03,538> ERROR Task exception was never retrieved
future: <Task finished name='SPAMAN:Sequence Pump' coro=<GeckoAsyncSpaMan._sequence_pump() done, defined at /home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa_manager.py:524> exception=AttributeError("'NoneType' object has no attribute 'get_and_increment_sequence_counter'")>
Traceback (most recent call last):
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa_manager.py", line 543, in _sequence_pump
await self.async_connect(self._spa_identifier, self._spa_address)
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa_manager.py", line 334, in async_connect
return await self.async_connect_to_spa(spa_descriptors[0])
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa_manager.py", line 300, in async_connect_to_spa
await self._spa.connect()
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 367, in connect
await self._connect()
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 334, in _connect
if not await self.struct.get(
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/driver/async_spastruct.py", line 64, in get
request = create_func()
File "/home/rrov1/.local/lib/python3.9/site-packages/geckolib/async_spa.py", line 337, in <lambda>
self._protocol.get_and_increment_sequence_counter(False),
AttributeError: 'NoneType' object has no attribute 'get_and_increment_sequence_counter'
^CGeckoSpaEvent.SPA_MAN_EXIT: {'exc_info': (<class 'asyncio.exceptions.CancelledError'>, CancelledError(), <traceback object at 0x7f6717f2ea80>)}
Traceback (most recent call last):
File "/home/rrov1/spa_setWatercareMode.py", line 140, in <module>
asyncio.run(main())
File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.9/asyncio/base_events.py", line 629, in run_until_complete
self.run_forever()
File "/usr/lib/python3.9/asyncio/base_events.py", line 596, in run_forever
self._run_once()
File "/usr/lib/python3.9/asyncio/base_events.py", line 1854, in _run_once
event_list = self._selector.select(timeout)
File "/usr/lib/python3.9/selectors.py", line 469, in select
fd_event_list = self._selector.poll(timeout, max_ev)
KeyboardInterrupt
Any suggestions are welcome.
rrov1
Just curious if this code would work for the original in.touch I have tried looking at the packets during communication with the app and the module but i cannot understand it.
Not really an issue. Opening this to provide the log/behavior for what happens when the in.touch wifi unit is no longer RF sync'd with the remote hot tub side unit. (Providing this with the hope if you haven't tried this case, my logs might save you some time so you don't have to try it yourself.)
Hot tub is powered down, wifi unit still plugged in. The connect (manage) times out after a while with RuntimeError: Spa took too long to connect
which seems reasonable, though you do get bounced out of the shell.
However, there are some RFERR
(assumed to be RF Error) log warning messages which don't seem to be handled. Looks like it retries the connection 10+ times.
Log file emailed.
Starting discovery process...Found 2 spas
Welcome to the Gecko shell. Type help or ? to list commands.
(Gecko) list
1. My Steamer
2. My Spa
(Gecko) manage 2
Connecting to spa `My Spa` at 192.168.208.49 ... LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
LOG> WARNING Couldn't find new handler for b'RFERR'
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run()
File "/usr/lib/python3.7/threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/spa.py", line 282, in _ping_thread_func
self.refresh()
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/spa.py", line 311, in refresh
if not self.is_connected:
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/spa.py", line 306, in is_connected
raise RuntimeError("Spa took too long to connect ...")
RuntimeError: Spa took too long to connect ...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/utils/shared_command.py", line 38, in run
cmd.cmdloop()
File "/usr/lib/python3.7/cmd.py", line 138, in cmdloop
stop = self.onecmd(line)
File "/usr/lib/python3.7/cmd.py", line 217, in onecmd
return func(arg)
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/utils/shell.py", line 97, in do_manage
self.facade = spa.get_facade()
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/spa.py", line 48, in get_facade
while not facade.is_connected:
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/automation/facade.py", line 68, in is_connected
if not self._spa.is_connected:
File "/home/rct/proj/gecko/gazoodle/geckolib/src/geckolib/spa.py", line 306, in is_connected
raise RuntimeError("Spa took too long to connect ...")
RuntimeError: Spa took too long to connect ...
Hi,
I have these issue while try to install geckolib:
`pi@raspberrypi-iob:~ $ pip install geckolib
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting geckolib
Using cached https://files.pythonhosted.org/packages/57/70/353b9fd028243adc08b8e56e263922e8828a3c2730bb27d50358ad37d802/geckolib-0.4.7.tar.gz
Installing build dependencies ... done
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-7d73lW/geckolib/setup.py", line 6, in
setuptools.setup()
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/init.py", line 162, in setup
return distutils.core.setup(**attrs)
File "/usr/lib/python2.7/distutils/core.py", line 124, in setup
dist.parse_config_files()
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/dist.py", line 702, in parse_config_files
ignore_option_errors=ignore_option_errors)
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 121, in parse_configuration
meta.parse()
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 426, in parse
section_parser_method(section_options)
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 399, in parse_section
self[name] = value
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 184, in setitem
value = parser(value)
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 515, in _parse_version
version = self._parse_attr(value, self.package_dir)
File "/tmp/pip-build-env-LmhH9N/lib/python2.7/site-packages/setuptools/config.py", line 349, in _parse_attr
module = import_module(module_name)
File "/usr/lib/python2.7/importlib/init.py", line 37, in import_module
import(name)
File "/tmp/pip-install-7d73lW/geckolib/src/geckolib/init.py", line 5, in
from .async_tasks import AsyncTasks
File "/tmp/pip-install-7d73lW/geckolib/src/geckolib/async_tasks.py", line 14
async def aenter(self):
^
SyntaxError: invalid syntax
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-7d73lW/geckolib/
pi@raspberrypi-iob:~ $ python --version
Python 2.7.16
pi@raspberrypi-iob:~ $ python3 --version
Python 3.7.3
pi@raspberrypi-iob:~ $
`
Maybe related to python version? But I have no idea what to do
I'd like to track/log/plot the changes in temperature. If possible, I'd also like to track how often and how long the heater runs(*). Is anyone doing anything along these lines yet?
I've seen mentions of people working on Home Assistant integration. Anyone have pointers to repos where that work is occurring?
I know it is going to take a while to work everything out. I'm hoping to just get something quick and dirty done that publishes data to MQTT that I can use in Home Assistant or other environments (Influx/Grafana, etc.)
Anyone work out how quickly your spa loses heat at various outdoor temperatures?
(*) I'm interested in having some idea of energy consumption. I know I need to get and install some energy monitoring for branch circuits like the spa, but I haven't worked out a plan yet. If anyone has any suggestions I'd love to hear what you've done.
My Spa has a InYJ-3 pack that has the in.mix 300 light control system built in. The lights on/off button in the app and using the library doesn't do anything, other than change the state of the lights in the app.
Have you plans to support the in.mix 300 system? Would be great to be able to control and set the colours of the zones.
Hi,
Not able to connect to my spa so attaching my log file in case it will help to identify the issue. Looking forward to get this up and running already in HA :)
I'd like to start tracking temperature change vs. weather forecast -> The idea is to set rules to get my spa heating started at the right time based on the time I want to go in.
"I want my spa ready @6pm" --> calculate heating time based on the data collected vs. temp
or
Turn heating off if pump 2 not used for x hours
or
Reset due reminders after pushing IoT button
etc.
Thanks,
eranjo
Currently have to comment out line 4 and 53 on Windows to get the library to load
Traceback (most recent call last):
File "test.py", line 9, in
with GeckoLocator(CLIENT_ID1).get_spa_from_identifier('SPA80:1f:12:65:6b:1b') as locator1:
File "C:\Users\Schmid\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\geckolib\locator.py", line 90, in get_spa_from_identifier
return next(spa for spa in self.spas if spa.identifier == identifier)
StopIteration
Any Idea?
I was poking around in the code and other issues/requests seeing if it would be possible to view/control the salt water system on my spa. It looks like it may be possible, but I'm not 100% sure what to look for. I notice it listed in both Output connections are
and Actual connections are
in the logs, and tried capturing changing some settings while logging as well. I'm a Ruby developer by day but don't have much experience in Python (but I'm sure I could figure it out)...just not sure what to look for or where to start in terms of parsing messages and building a device handler for it, so some guidance would be helpful.
Hi there, trying to use GeckoShell to connect to my Bain Ultra tub that uses an in.Touch2 for remote access and not having much luck; looks like a nonexistent driver pack based on the platform key received. Anything I could do to help add support for these models?
Error is as follows:
>>> GeckoShell.run()
<Disclaimer>
----------------------------- USE AT YOUR OWN RISK -----------------------------
This code will allow you to make changes to your spa configuration that is
outside of what the app, top panel and side panel settings allow. I've not
tested every setting and it might be that you prevent your spa pack from
operating as it used to do.
I strongly suggest dumping the configuration values with the "config" command
and recording them somewhere safe.
</Disclaimer>
Starting discovery process...Found 1 spas
Connecting to spa `Meridian 55` at 192.168.0.245 ... LOG> ERROR Unhandled exception in receive_handler func
Traceback (most recent call last):
File "/home/sgregory/.local/lib/python3.7/site-packages/geckolib/spa.py", line 114, in _on_config_received
GeckoPack = importlib.import_module(pack_module_name).GeckoPack
File "/usr/lib/python3.7/importlib/__init__.py", line 127, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
File "<frozen importlib._bootstrap>", line 983, in _find_and_load
File "<frozen importlib._bootstrap>", line 965, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'geckolib.driver.packs.masi'
Excellent library! Just what I need, but I am a python newbie (learning just to access this library!). I could use a little more help on the syntax in python scripts that access spa status like pump1 or heater or ??. You gave an example of changing a pump, but what about just reading it?Maybe just suggest how one might generate the list of items that we have access to and what some syntax might look like to read those? Very appreciative of what you have already done!
I was having an issue with the code not finding the configuration for my spa (Cannot find XML configuration for inYT v65). I looked at the XML file at http://intouch.geckoal.com/gecko/prod/SpaPackStruct.xml and saw that for inYT the version number is v63. So I wondered what would happen if I just ignored the version, and I changed const.py to the following, to remove the version check
SPA_PACK_CONFIG_XPATH = "./ConfigStructures/ConfigStructure"
SPA_PACK_LOG_XPATH = "./LogStructures/LogStructure"
It appears to work fine when I do that. So the question is, should the code be ignoring the version, at least for some Plateforms?
It appears GeckoWaterHeater._current_operation always returns "Idle", regardless of the actual heater status.
Thanks for the library, I was working (and learning Python at the same time and the in.touch2 communication) to create an hass.io custom component when I found you'r library from https://github.com/chicago6061/in.touch2 repo.
Just found a weird thing, when you'r library discover all my actual device, it's find twice my P1 pump. I only have 1 pump (two speed), I don't know if it's normal or not. Like I said, I start learning Pyhton (I'm a PHP and C# programmer), so I need to understand everything from that language.
Here a copy of the log
client.log
I installed this awesome libary on my openhabian system. It works but i get an error every minute:
LOG> ERROR Enum accessor inFloErrorType out-of-range for ['FLOW_OK', 'MODE_1_FAIL', 'MODE_1_AND_2_FAIL', 'MODE_1_AND_HEATING_FAIL', 'HEATING_FAIL']
Traceback (most recent call last):
File "/home/openhabian/.local/lib/python3.7/site-packages/geckolib/driver/accessor.py", line 119, in _get_value
data = self.items[data]
IndexError: list index out of range
This is the same issue reported here: gazoodle/gecko-home-assistant#69
I've been attempting to change a local copy of the code to get the External Lights to work.
I don't know Python (sorry) and have made some assumptions on how a few things work.
I made changes to const.py to add support for UdL120 which I believe is the device that is the external lights.
2022-10-31 20:48:22,445 geckolib.driver.accessor INFO Value for UdL120 changed from OFF to ON
2022-10-31 20:48:22,445 geckolib.driver.observable DEBUG GeckoEnumStructAccessor 'UdL120': 'ON' changed from OFF to ON
KEY_USER_EXTERNAL_LIGHT = "UdL120" # DGW Nov 22 - # User devices are those that have a Ud in the tag name
KEYPAD_LIGHT_EXTERNAL = 17 # DGW Nov 22 - value of 17 is guess work
"L120": ("External Lights", KEYPAD_LIGHT_EXTERNAL, KEY_USER_EXTERNAL_LIGHT, DEVICE_CLASS_LIGHT), # DGW Nov 22
("External LIGHT", "Lights Button", KEYPAD_LIGHT_EXTERNAL), # DGW Nov 22
After connecting I only see "Lights"... and I was thinking I'd see Lights and External Lights
I'm also not certain if I can manually turn on/off UdL120
Connecting to spa Wilson E2000 Swim Spa
at 192.168.11.112 ... connected!
Heater: Temperature 30.5°C, SetPoint 30.0°C, Real SetPoint 30.0°C, Operation Cooling
Lights: OFF
WaterCare: Waiting...
Smart Winter Mode:Risk: NO
Circulating Pump: ON
Ozone: OFF
Smart Winter Mode:Active: False
Filter Status:Clean: False
Filter Status:Purge: False
Economy Mode: False
Wilson E2000 Swim Spa$ LI ON
Turn device Lights ON
Wilson E2000 Swim Spa$
I'm guessing... hoping someone is able to lend some guidance on what I could try next.
Hi
Well done on this library - it works really well and obviously a lot of low-level capturing needed - Well Done!
I'm using it for a non-HA home automation plugin for Indigo (using python3). All going pretty well, despite the async slight hurdles at my end..
I have noticed that CPU usage in my scenario sits around 15% for a mac Mini doing little else. If I increase further your
const.py: Line: 18
ASYNCIO_SLEEP_TIMEOUT_FOR_YIELD to 0.1 I can drop CPU to less than 0.7% ?
May be a possible tweak for other systems? As likely a sweat spot here somewhere. Food for thought perhaps?
Thanks
Glenn
Hi
pip is objecting to your dependency specifier:
DEPRECATION: geckolib 0.4.8 has a non-standard dependency specifier python-version>="3.7". pip 24.0 will enforce this behaviour change. A possible replacement is to upgrade to a newer version of geckolib or contact the author to suggest that they release a version with a conforming dependency specifiers. Discussion can be found at pypa/pip#12063
Can you correct Please.
Krs
Mark
I am usually against cloud api's, but my spa is in a remote place without home assistant.
Did you ever found out how it communicates with the cloud? Is it possible to develop a cloud api?
Hello!
I need help with a script to read the reminders. I always get 0 reminders (for both spa controllers I have in my network) :-(. The script I use is very simple and straightforward, based on the asynchronous example. I append it here. It takes only one parameter, the guid, looks for all spa controllers on the network, connects to them and then retrieves the reminders. I currently use geckolib 0.4.8, with 0.4.7 I have the problem. Everything else works fine.
Am I doing something wrong?
import sys
import asyncio
import logging
import requests
import urllib
from geckolib import GeckoAsyncSpaMan, GeckoSpaEvent # type: ignore
from geckolib.driver.protocol.reminders import GeckoReminderType
# Anzahl Argumente prüfen
if len(sys.argv) != 2:
print("*** Wrong number of script arguments.\n")
print(f"*** call example: {sys.argv[0]} clientId")
quit(-1)
print("total arguments passed:", len(sys.argv))
CLIENT_ID = sys.argv[1]
print(f"Connect using client id: {CLIENT_ID}")
class SampleSpaMan(GeckoAsyncSpaMan):
async def handle_event(self, event: GeckoSpaEvent, **kwargs) -> None:
# Uncomment this line to see events generated
print(f"{event}: {kwargs}")
pass
async def main() -> None:
async with SampleSpaMan(CLIENT_ID, spa_address=None) as spaman:
print("*** looking for spas on your network ...")
# Wait for descriptors to be available
await spaman.wait_for_descriptors()
if len(spaman.spa_descriptors) == 0:
print("*** there were no spas found on your network.")
return
# get all spa names
allNames = []
for descriptor in spaman.spa_descriptors:
allNames.append(descriptor.name)
mySpaDescriptors = []
# sort spa names and create a new spa descriptors array sorted by spa_name
for myName in sorted(allNames):
for descriptor in spaman.spa_descriptors:
if descriptor.name == myName:
mySpaDescriptors.append(descriptor)
for nSpaNum in range(len(mySpaDescriptors)):
spa_descriptor = mySpaDescriptors[nSpaNum]
print(f"connecting to {spa_descriptor.name} at {spa_descriptor.ipaddress} with {spa_descriptor.identifier_as_string}")
await spaman.async_set_spa_info(
spa_descriptor.ipaddress,
spa_descriptor.identifier_as_string,
spa_descriptor.name,
)
# Wait for the facade to be ready
await spaman.wait_for_facade()
print(f"spa_state {spaman.spa_state}")
rm = spaman.facade.reminders_manager
print(f"anzahl reminders: {len(rm.reminders)}")
for reminder in rm.reminders:
print(f"reminder: {reminder}")
print(f"error sensor state {spaman.facade.error_sensor.state}")
await asyncio.sleep(1)
# ende
print("*** end")
return
if __name__ == "__main__":
# Install logging
stream_logger = logging.StreamHandler()
stream_logger.setLevel(logging.DEBUG)
stream_logger.setFormatter(
logging.Formatter("%(asctime)s> %(levelname)s %(message)s")
)
logging.getLogger().addHandler(stream_logger)
logging.getLogger().setLevel(logging.INFO)
asyncio.run(main())
rrov1
It looks like work on this repo isn't really happening anymore. I'm curious if there's a way we can move development to a shared repo that isn't owned by a specific person.
Hi.
I possibly have a faulty tub. Occasionly the temperature reads to low and overheats the water and I then get an OH error on reboot as the temperature is above 40.
I mention the above in relation to the behaviour with geckolib that I have been experiecing.
Basically i have been having high and low spikes in temperature readings which is shown in the HA graphs below.
On a seperate machine i installed geckolib so i could explore using the shell. I was seeing a great deal of STATP packets all with very variable water temperature over a few seconds.
Mainly RhWaterTemp was very variable but also DisplayedTemp
I then disabled the STATP handler so the packets were not processed by accesor and no changes were seen by observables.
This has smoothed out the graphs. Now I never saw the variability in temps in the Gecko App and I am wondering if the app ignores STATP messages. STATP seem to be very variable. Either that or the lib is not processing them correctly.
Anybody else seen huge variability in temperature in the STATP messages?
Krs
Mark
I've recently done a fresh installation of HA and this evening decided to try and set up the Gecko integration.
I'm installing through HACS, installation completes and then I reboot, when I then go to add integration I get a blank box popup waiting for input with a submit button (see picture), not sure what it is wanting but I tried the IP of Hot Tub, it then comes back with a box that show Hot Tub and a Submit button (see picture), press Submit and its sits there for ages with spinning icon and then after quit a while it comes back and says Created Configuration for Hot Tub (see picture), click Finish. The intergration then shows Failed to set up (see picture). If I click on configure I see a options windows with six tick boxes but no writing (see picture). If I check the logs there are lots of Gecko errors and warnings (see picture).
Any idea as to what is wrong or what I've done wrong?
Thanks
Simon
version | core-2022.2.1 |
---|---|
installation_type | Home Assistant OS |
dev | false |
hassio | true |
docker | true |
user | root |
virtualenv | false |
python_version | 3.9.7 |
os_name | Linux |
os_version | 5.10.91 |
arch | x86_64 |
timezone | Europe/London |
GitHub API | ok |
---|---|
Github API Calls Remaining | 4846 |
Installed Version | 1.21.0 |
Stage | running |
Available Repositories | 970 |
Downloaded Repositories | 4 |
logged_in | true |
---|---|
subscription_expiration | 27 February 2022, 00:00 |
relayer_connected | true |
remote_enabled | true |
remote_connected | true |
alexa_enabled | true |
google_enabled | true |
remote_server | eu-west-2-0.ui.nabu.casa |
can_reach_cert_server | ok |
can_reach_cloud_auth | ok |
can_reach_cloud | ok |
host_os | Home Assistant OS 7.2 |
---|---|
update_channel | stable |
supervisor_version | supervisor-2022.01.1 |
docker_version | 20.10.9 |
disk_total | 31.3 GB |
disk_used | 6.6 GB |
healthy | true |
supported | true |
board | ova |
supervisor_api | ok |
version_api | ok |
installed_addons | SSH & Web Terminal (10.0.2), Home Assistant Google Drive Backup (0.105.2), Node-RED (10.4.0), File editor (5.3.3), ESPHome (2022.1.3) |
dashboards | 1 |
---|---|
resources | 0 |
views | 1 |
mode | storage |
The update fails um my YE-5 with the following error
File "/Users/walter/Desktop/Spa_Control/Geckolib/geckolib-main 2/client.py", line 118, in
facade = GeckoFacade(spa)
File "/Users/walter/Desktop/Spa_Control/Geckolib/geckolib-main 2/geckoautomation.py", line 237, in init
self.scan_outputs()
File "/Users/walter/Desktop/Spa_Control/Geckolib/geckolib-main 2/geckoautomation.py", line 266, in scan_outputs
self._pumps = [ GeckoPump(self, device, gecko_constants.devices[device])
File "/Users/walter/Desktop/Spa_Control/Geckolib/geckolib-main 2/geckoautomation.py", line 268, in
if gecko_constants.devices[device][3] == gecko_constants.device_class_pump]
builtins.KeyError: 'Waterfall'
BR Walter
Hi
When trying to install the library , I have this error
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-YJ5OrL/geckolib/
Any idea ?
Is there a way using Geckolib to set the clock on the spa to the correct time?
If not, is this something that could be possible with geckolib?
FWIW, I noticed my spa didn't adjust for the end of daylight savings time. Additionally the spa's clock seemed to be fast by about 9 minutes. I probably noticed this because my in.touch2 unit wasn't communicating with the gecko servers. (It was trying to connect to intouch.geckoal.com
and getting bad a misformatted ICMP port unreachable that never got back to the intouch.2. I was able to work around that by adding a host entry to my router that pointed intouch.geckoal.com to intouch2.geckoal.com.)
In case it helps, though the debugging process I did see at least the time synchronization request that my steamlinx unit sends to the gecko server: <SYNCH>ATIME</SYNCH>
The response from the Gecko server appears to be <SYNCH>TIMEAymd?hms</SYNCH>
The ymd,hms values are in binary not ascii, so 0x170b12
for 23-11-18
(today). The ? for me was an 0x06
between the ymd and hms. Not sure of the significance of that 0x06, a fixed separated or some timezone indicator?
The problem:
No entities showing for integration
What I've tried:
Followed the installation instructions. Used HACS and then integrated in HA. Tried re-starting, powercycling, deleting and re-installing, changing all Options and re-submitting all or none or one at a time. The MAC address was always seen until my daughter renamed the connection on the in.touch2 app to 'Ducky Tub' and now that is shown on the integration as well.
Then I powercycled the in.touch2 module, refreshed the integration. Re-started HA. Deleted and re-installed the integration. All with no change. The only thing I haven't done yet is to powercycle the hot tub itself, but I'm not sure what that would gain. Clearly the RF module inside is working as the in.touch2 iOS app is full functioning.
Getting the above error on startup - The spa name and IP are correctly identified but then screen fills with various Python errors and the above exception.
Just confirming my assumptions - Do I need to do the 'Linqpad voodoo' to update the XML file like others have?
Client.log is attached for reference
Thanks in advance!
Hi,
I have been playing around creating a home bridge plugin using you great library. I can't work out how to refresh the spa info though. I have tried the facade.spa.refresh() command but that doesn't appear to work.
While attempting to run the geckoshell, my spa is discovered, but it throws an error:
ModuleNotFoundError: No module named 'geckolib.driver.packs.'
I've attached the client.log.
client.log
This is coming from an in.touch.2 system that i purchased used and was previously hooked up to another hot tub. The spa transmitter always shows a solid red led. while the home transmitter shows blue. I was hoping this geckoshell could give me some insight as to why the spa transmitter can't connect, while the home transmitter shows the device has a great signal.
Trying GeckoLib shell with only the Mr Steam Steamlinx unit on the local lan. I'm not expecting Geckolib to run at this point, but thought I would collect and report data.
Perhaps a first goal would be to get to the point of recognizing the Mr. Steam unit isn't a spa and should be skipped.
Running GeckoShell hangs at Connecting to spa
My Steamer at 192.168...
Since it attempts to auto connect and hangs, I can't go any further in that shell. I wind up having to CTRL-C.
I haven't figured out yet if there is debugging I should be turning on.
With tcpdump I see a bunch of UDP with XML packets go back and forth. Guessing the command might be APING. There is a reference to MrSt_C02.xml
. It seems like the shell/library polls every few seconds.
Please let me know what would be good to run in order to collect data.
From the activity/comments, I believe that this repo is now that active one and that we shouldn't be using Chicago6061's in.touch2 repo, is that correct?
I saw a reference to client.py @gazoodle mentioned in the other repo, has that been replaced by GeckoShell?
If I run GeckoShell with both the in.touch2 (spa) and Mr. Steam steamlinx connected, it reports 2 spas found. However, I don't see an obvious command to use to connect to one of them, but maybe I'm being dense.
Let me know if you want to see any data from my in.yt-8 controller. I've done a config dump using GeckoShell. All looks ok as far as I can tell. I haven't gotten Chicago6061's dumpall.py to work yet.
I get the following error
Starting discovery process...Found 1 spas
Connecting to spa Wellis
at 172.xx.xx.xx ... connected!
Heater: Temperature 37.0°C, SetPoint 34.0°C, Real SetPoint 34.0°C, Operation Cooling
Pump 1: OFF
Lights: OFF
WaterCare: Waiting...
Smart Winter Mode:Risk: NO
Circulating Pump: OFF
Ozone: OFF
Smart Winter Mode:Active: False
Filter Status:Clean: False
Filter Status:Purge: False
Economy Mode: False
Error Sensor: VSP1CommLost, VSP2CommLost
Welcome to the Gecko shell. Type help or ? to list commands.
Wellis$ LOG> ERROR Unhandled exception in receive_handler func
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/geckolib/driver/udp_socket.py", line 181, in dispatch_recevied_data
receive_handler.handled(remote_end)
File "/usr/local/lib/python3.9/dist-packages/geckolib/driver/udp_protocol_handler.py", line 101, in handled
self._on_handled(self, sender)
File "/usr/local/lib/python3.9/dist-packages/geckolib/automation/watercare.py", line 64, in _on_watercare
self._on_change(self, old_mode, self.active_mode)
File "/usr/local/lib/python3.9/dist-packages/geckolib/driver/observable.py", line 39, in _on_change
f"{self.class.name} {sender} changed "
File "/usr/local/lib/python3.9/dist-packages/geckolib/automation/watercare.py", line 92, in str
return f"{self.name}: {GeckoConstants.WATERCARE_MODE_STRING[self.active_mode]}"
IndexError: list index out of range
I suggest exposing the Smart Winter Mode status as well as FilterStatus:
<SWMStatus>
<SwmPurgeSusp Type="Bool" Pos="282" BitPos="3" />
<SwmPurge Type="Bool" Pos="282" BitPos="5" />
<SwmActive Type="Bool" Pos="282" BitPos="6" />
<SwmRisk Type="Enum" Pos="313" Items="NO|LO|MED|HI|EXTREME" />
<SlaveSwmPurge Type="Bool" Pos="353" BitPos="5" />
<SlaveSwmActive Type="Bool" Pos="353" BitPos="6" />
<SwmAdc Type="Word" Pos="355" />
</SWMStatus>
<FilterStatus>
<Clean Type="Bool" Pos="273" BitPos="0" />
<Purge Type="Bool" Pos="273" BitPos="2" />
<FiltSuspendByUD Type="Bool" Pos="273" BitPos="3" />
<FiltSuspendedByOT Type="Bool" Pos="273" BitPos="4" />
<FiltSuspendedByErr Type="Bool" Pos="273" BitPos="5" />
<CPOT Type="Bool" Pos="274" BitPos="2" />
</FilterStatus>
Running GeckoShell against an In.YT 501 10.0 controller, I get the following warnings about STATV
, however things seem to work:
LOG> WARNING Couldn't find new handler for b"STATV\x00\x01'\
r\x00\x00\x02\x8c\x01\x05\x00\x00\x00\x00\x04\n,\xff\xff\xff\x00\x00\x01\x0e\x01T\x00\x01\x06\x00\x00\x00\x00
\x15\x06\x00\n\x03\x00\x14\x1d\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x00\x01'\r\x00\x00\x02\x8c\x01\x05\x00\x00\x00\x00\x04\n,\
xff\xff\xff\x00\x00\x01\x0e\x01T\x00\x01\x06\x00\x00\x00\x00\x15\x06\x00\n\x03\x00\x14\x1d\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x01\x02':9\x01\xf5\n\x00\x00\x08\x16\x00\x00\x00\x00\x00\x
00\x00\x03\x84\x00\x00\x00\x00\x01O\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x01\x02':9\x01\xf5\n\x00\x00\x08\x16\x00\x00\x00\x00\x00\x
00\x00\x03\x84\x00\x00\x00\x00\x01O\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x02\x03'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x1f\x15\x00\x17\x01\x00\xfd\x85\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x02\x03'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x1f\x15\x00\x17\x01\x00\xfd\x85\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x03\x04'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x03\x04'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x04\x05'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03"
LOG> WARNING Couldn't find new handler for b"STATV\x04\x05'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03"
LOG> WARNING Couldn't find new handler for b"STATV\x05\x06'\x04\x05\x06\x07\x08\xff\xff\xff\xff\xff\xff\xff\x
ff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffinYT_C58.x"
LOG> WARNING Couldn't find new handler for b"STATV\x05\x06'\x04\x05\x06\x07\x08\xff\xff\xff\xff\xff\xff\xff\x
ff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffinYT_C58.x"
LOG> WARNING Couldn't find new handler for b"STATV\x06\x07'ml\x00\x00\x00\x00inYT_S57.xml\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x06\x07'ml\x00\x00\x00\x00inYT_S57.xml\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x07\x08'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x07\x08'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x08\t'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14$D\x86\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x08\t'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14$D\x86\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\t\n'\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x03\x05\x00\x00\x00\x00\xff\x0e\x02\x00 \x02\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\t\n'\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x03\x05\x00\x00\x00\x00\xff\x0e\x02\x00 \x02\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\n\x0b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\n\x0b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x0b\x0c'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b"STATV\x0b\x0c'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
LOG> WARNING Couldn't find new handler for b'STATV\x0c\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
LOG> WARNING Couldn't find new handler for b'STATV\x0c\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
connected!
Heater: Temperature 66.0°F, SetPoint 59.0°F, Real SetPoint 59.0°F, Operation Cooling
Pump 2: OFF
Pump 1: HIGH
Waterfall: ON
Lights: OFF
WaterCare: Waiting...
Smart Winter Mode:Risk = NO
Circulating Pump = ON
Ozone = ON
Smart Winter Mode:Active = False
Filter Status:Clean = False
Filter Status:Purge = False
Welcome to the Gecko shell. Type help or ? to list commands.
My Spa$ version
SpaPackStruct.xml revision 19.00
intouch version EN 70 v8.0
intouch version CO 69 v7.0
Spa pack inYT 501 v10.0
Low level configuration # 8
Config version 58
Log version 57
Pack type 10
When using the async part the library is consuming 100% CPU (respectively one core in case of a multi core CPU).
That seems to be based on the short waiting time (1ms) in async_spa_manager.py (line 504).
Changing the yield asyncio sleep time (GeckoConstants.ASYNCIO_SLEEP_TIMEOUT_FOR_YIELD) from 0.001 to 0.02 solved the issue for me. CPU usage dropped under 3%.
hi guys,
sorry for my bad english, and please excuse me, I only have basic knowledge of programming.
Some python projects are already running on the raspberry.
I have upgradet my whirlpool with the in.touch.2 module and i want to usw it with my Loxone smart home control.
Probably not a complicated thing for professionals but I don't know how to switch between the "standard" and the "away" mode.
So when the Loxone energy manager says he has enough power from the photovoltaic - switch to "standard" heating, and when sun goes down switch to "away" oder eco mode.
Is there any option to control this script over UDP, HTTP or Mqtt?
thanks a lot
I have a Whirlcare Prestige working in Home Assistent using the Gecko Integration but there are some issues preventing a full integration:
The other 3 main pumps and the blower are working as they should.
This is a screenshot of the Home Assistant integration showing the issues:
This is a screenshot of the original in.touch 2 mobile app showing it correctly:
For completeness this is the 2nd page of the original in.touch 2 mobile app showing the light settings:
I'll send the following snapshot logs per email for further investigation:
If there's information missing or anything else I can help with, please let me know.
Thanks for the great library!
Shell usage is working great...
Now I am trying to get the async sample from the readme to work.
At the top I changed the following parameters
CLIENT_ID = "02ac6d28-xxxx-xxxx-xxxx-274d0aa491da"
SPA_ADDRESS = "192.168.42.123"
When I run the example I get the following error:
e:\Test\python async.py
GeckoSpaEvent.SPA_MAN_ENTER: {}
Looking for spas on your network ...
GeckoSpaEvent.LOCATING_STARTED: {}
2023-02-18 17:56:56,565> ERROR GeckoAsyncUdpProtocol: Exception received [WinError 10022] An invalid argument was supplied
Traceback (most recent call last):
File "C:\Python310-32\lib\asyncio\proactor_events.py", line 568, in _loop_reading
self._read_fut = self._loop._proactor.recvfrom(self._sock,
File "C:\Python310-32\lib\asyncio\windows_events.py", line 499, in recvfrom
ov.WSARecvFrom(conn.fileno(), nbytes, flags)
OSError: [WinError 10022] An invalid argument was supplied
GeckoSpaEvent.LOCATING_FINISHED: {'spa_descriptors': []}
**** There were no spas found on your network.
GeckoSpaEvent.SPA_MAN_EXIT: {'exc_info': (None, None, None)}
Hi,
is it atm possible to control the status (switch on/off) of the circulation pump?
Info about my System/Config:
`Heater: Temperature 33.5°C, SetPoint 32.0°C, Real SetPoint 32.0°C, Operation Cooling
Waterfall: OFF
Pump 1: OFF
Pump 2: OFF
Lights: OFF
WaterCare: Waiting...
Smart Winter Mode:Risk: NO
Circulating Pump: OFF
Ozone: OFF
Smart Winter Mode:Active: False
Filter Status:Clean: False
Filter Status:Purge: False
Economy Mode: False
Error Sensor: OverTemp
Welcome to the Gecko shell. Type help or ? to list commands.
Wellness$ help
LI about exit list monitor setpoint watercare
P1 accessors get logfile peek snapshot
P2 discover help loglevel refresh state
Waterfall eco license manage set version
Wellness$ list
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.