Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for Bryant ControlBox #38

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jtolio
Copy link

@jtolio jtolio commented Nov 20, 2024

these values pulled from a Bryant ControlBox APK decompile

these values pulled from a Bryant ControlBox APK decompile
@jtolio
Copy link
Author

jtolio commented Nov 20, 2024

Note that when running this, it works! But there are errors:

midea-beautiful-air-cli status --ip 192.168.1.161 --app Bryant --account "<REDACTED>" --password "<REDACTED>"
WARNING:midea_beautiful.appliance:Midea B5 unknown property=b'@\x00'
WARNING:midea_beautiful.lan:Error getting device capabilities for sn=000000P0000000Q1AC93C42B******** id=15173260566**** address=192.168.***** version=3, cause Unable to send data after 3 retries, last error timed out for 000000P0000000Q1AC93C42B******** (15173260566****)
Traceback (most recent call last):
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 809, in identify
    responses = self._status(cmd, cloud if use_cloud else None)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 540, in _status
    responses = self.appliance_send(data)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 685, in appliance_send
    return self._appliance_send_8370(data)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 590, in _appliance_send_8370
    if packets := self._retry_send(original_data, response_buf):
                  ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 670, in _retry_send
    packets = self.appliance_send(data)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 685, in appliance_send
    return self._appliance_send_8370(data)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 590, in _appliance_send_8370
    if packets := self._retry_send(original_data, response_buf):
                  ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 675, in _retry_send
    raise MideaNetworkError(
    ...<3 lines>...
    )
midea_beautiful.exceptions.MideaNetworkError: Unable to send data after 3 retries, last error timed out for 000000P0000000Q1AC93C42B******** (15173260566****)
id 000000P0000000Q1AC93C42BA3B80000/151732605669938
  id      = 151732605669938
  addr    = 192.168.1.161
  s/n     = 000000P0000000Q1AC93C42BA3B80000
  model   = Air conditioner
  ssid    = net_ac_A3B8
  online  = True
  name    = Basement
  running = False
  target  = 18.5
  indoor  = 20.0
  outdoor = 2.2250738585072014e-308
  fan     = 102
  mode    = 4
  purify  = False
  eco     = False
  sleep   = False
  frost   = False
  comfort = False
  F       = True
  error   = 0
  supports= {'eco': 1, 'has_no_wind_feel': 0, 'mode': 1, 'fan_swing': 1, 'electricity': 0, 'strong_fan': 1, 'fan_speed': 1, 'humidity': 3, 'temperature0': 32, 'temperature1': 60, 'temperature2': 32, 'temperature3': 60, 'temperature4': 32, 'temperature5': 60, 'temperature6': 5}
  version = 3

or

(home-energy) ~/dev/home-energy$ midea-beautiful-air-cli set --ip 192.168.1.161 --app Bryant --account "<REDACTED>" --password "<REDACTED>" --running off
WARNING:midea_beautiful.appliance:Midea B5 unknown property=b'@\x00'
WARNING:midea_beautiful.lan:Error getting device capabilities for sn=000000P0000000Q1AC93C42B******** id=15173260566**** address=192.168.***** version=3, cause Unable to send data after 3 retries, last error timed out for 000000P0000000Q1AC93C42B******** (15173260566****)
Traceback (most recent call last):
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 809, in identify
    responses = self._status(cmd, cloud if use_cloud else None)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 540, in _status
    responses = self.appliance_send(data)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 685, in appliance_send
    return self._appliance_send_8370(data)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 590, in _appliance_send_8370
    if packets := self._retry_send(original_data, response_buf):
                  ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 670, in _retry_send
    packets = self.appliance_send(data)
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 685, in appliance_send
    return self._appliance_send_8370(data)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 590, in _appliance_send_8370
    if packets := self._retry_send(original_data, response_buf):
                  ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/home/jt/dev/home-energy/lib64/python3.13/site-packages/midea_beautiful/lan.py", line 675, in _retry_send
    raise MideaNetworkError(
    ...<3 lines>...
    )
midea_beautiful.exceptions.MideaNetworkError: Unable to send data after 3 retries, last error timed out for 000000P0000000Q1AC93C42B******** (15173260566****)
id 000000P0000000Q1AC93C42BA3B80000/151732605669938
  id      = 151732605669938
  addr    = 192.168.1.161
  s/n     = 000000P0000000Q1AC93C42BA3B80000
  model   = Air conditioner
  ssid    = net_ac_A3B8
  online  = True
  name    = Basement
  running = False
  target  = 18.5
  indoor  = 20.0
  outdoor = 5.3
  fan     = 102
  mode    = 4
  purify  = False
  eco     = False
  sleep   = False
  frost   = False
  comfort = False
  F       = True
  error   = 0
  supports= {'eco': 1, 'has_no_wind_feel': 0, 'mode': 1, 'fan_swing': 1, 'electricity': 0, 'strong_fan': 1, 'fan_speed': 1, 'humidity': 3, 'temperature0': 32, 'temperature1': 60, 'temperature2': 32, 'temperature3': 60, 'temperature4': 32, 'temperature5': 60, 'temperature6': 5}
  version = 3

@jtolio
Copy link
Author

jtolio commented Nov 22, 2024

the following command will give me the token and key for each device in my bryant controlbox account (though with errors that come from the LanDevice.identify method):

#!/usr/bin/env python3

import sys
from midea_beautiful.cloud import MideaCloud
from midea_beautiful.lan import appliance_state
from midea_beautiful.cli import _output

username, password, ip = sys.argv[1], sys.argv[2], sys.argv[3]

cloud = MideaCloud(
    appkey="b3b5afd46868aa14c4eac8e8765f0e1a",
    account=username,
    password=password,
    appid=1112,
    hmac_key=None,
    iot_key=None,
    api_url="https://mapp.appsmb.com",
    proxied=None,
    sign_key="xhdiwjnchekd4d512chdjx5d8e4c394D2D7S")

appliance = appliance_state(address=ip, cloud=cloud, use_cloud=False)
_output(appliance, show_credentials=True)

and the remaining code will use the discovered token and key to talk directly to my Bryant minisplit heads with WiFi dongles and tell them to only turn on when the ambient temperature needs it:

#!/usr/bin/env python3

import sys, json, logging, socket
from midea_beautiful import midea
from midea_beautiful.lan import DISCOVERY_MSG, LanDevice

MODE_AC = 2
MODE_HEAT = 4

with open(".thermostat-creds.json") as fh:
  creds = json.load(fh)

def C_to_F(c):
  return c*1.8 + 32

for appliance in creds:
  with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
    sock.settimeout(3)
    sock.connect((appliance["ip"], 6445))
    sock.sendall(DISCOVERY_MSG)
    response = sock.recv(512)
    dev = LanDevice(
        data=response,
        token=appliance["token"],
        key=appliance["key"])
    dev.refresh()
    print("considering", appliance["name"])
    print("indoor temp", C_to_F(dev.state.indoor_temperature))
    print("target temp", C_to_F(dev.state.target_temperature))
    print("running", dev.state.running)
    print("mode", dev.state.mode)

    def set_running(should_be_running):
      print("should be running", should_be_running)
      if should_be_running == dev.state.running:
        print("already in correct state")
        return
      print("toggling running state")
      dev.state.running = should_be_running
      dev.apply()

    if dev.state.mode == MODE_HEAT:
      set_running(
          dev.state.indoor_temperature <= dev.state.target_temperature)
    elif dev.state.mode == MODE_AC:
      set_running(
          dev.state.indoor_temperature >= dev.state.target_temperature)

Thanks for this library!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant