Trying to support an RV thermostat, but having issues

I’m at the very start of trying to support an RV thermo stat and have collected the MAC, UUID’s and commands from NRF connect. This is a successful log:

|V|15:35:33.890|Writing request to characteristic 0000ee01-0000-1000-8000-00805f9b34fb|
|---|---|---|
|D|15:35:33.891|gatt.writeCharacteristic(0000ee01-0000-1000-8000-00805f9b34fb, value=0x7B2254797065223A20224368616E6765222C224368616E676573223A207B227A6F6E65223A302C226D6F6465223A312C2022706F776572223A224F6E227D7D)|
|I|15:35:34.203|Data written to 0000ee01-0000-1000-8000-00805f9b34fb, value: (0x) 7B-22-54-79-70-65-22-3A-20-22-43-68-61-6E-67-65-22-2C-22-43-68-61-6E-67-65-73-22-3A-20-7B-22-7A-6F-6E-65-22-3A-30-2C-22-6D-6F-64-65-22-3A-31-2C-20-22-70-6F-77-65-72-22-3A-22-4F-6E-22-7D-7D, {Type: Change,Changes: {zone:0,mode:1, power:On}}|
|A|15:35:34.203|(0x) 7B-22-54-79-70-65-22-3A-20-22-43-68-61-6E-67-65-22-2C-22-43-68-61-6E-67-65-73-22-3A-20-7B-22-7A-6F-6E-65-22-3A-30-2C-22-6D-6F-64-65-22-3A-31-2C-20-22-70-6F-77-65-72-22-3A-22-4F-6E-22-7D-7D, {Type: Change,Changes: {zone:0,mode:1, power:On}} sent|

When I try and use the following config my device says its unsuccessful:

{
  "ble_write_address": "24:DC:C3:21:05:EE",
  "ble_write_service": "000000FF-0000-1000-8000-00805f9b34fb",
  "ble_write_char": "0000EE01-0000-1000-8000-00805f9b34fb",
  "ble_write_value": "7B2254797065223A20224368616E6765222C224368616E676573223A207B227A6F6E65223A302C226D6F6465223A312C2022706F776572223A224F6E227D7D",
  "value_type": "HEX",
  "ttl": 2,
  "immediate": true
}

One quirk of the device I know for sure is you have to send a Write Request, but I’m pretty sure OpenMQTTGateway is doing that. Anyone had anything similar who might be able to point me in the right direction? I’m going on messing around with this for around 20 hours now.

Also go this working via an SSH Script today:

import json
import time
import argparse
from bluepy.btle import Peripheral, UUID, BTLEException

def send_command(char, command):
“”“Sends a command to the BLE device using the characteristic provided.”“”
try:
char.write(command, withResponse=True)
print(“Command sent successfully:”, command.decode())
except BTLEException as e:
print(f"BLE operation failed with error: {str(e)}")

def read_status(peripheral, char_uuid):
“”“Reads the current status from the specified characteristic.”“”
try:
char = peripheral.getCharacteristics(uuid=char_uuid)[0]
data = char.read()
print(“Current status:”, data.decode(‘utf-8’)) # Assuming the data is in UTF-8 format; adjust decoding as needed.
except BTLEException as e:
print(f"Failed to read data: {str(e)}")

def main(args):
device_mac = “24:DC:C3:21:05:EE”
service_uuid = UUID(“000000FF-0000-1000-8000-00805f9b34fb”)
char_uuid = UUID(“0000EE01-0000-1000-8000-00805f9b34fb”)
read_char_uuid = UUID(“0000FF01-0000-1000-8000-00805f9b34fb”)

p = None
try:
    p = Peripheral(device_mac)
    if args.read:
        read_status(p, read_char_uuid)
    else:
        svc = p.getServiceByUUID(service_uuid)
        char = svc.getCharacteristics(uuid=char_uuid)[0]
        if args.power:
            send_command(char, json.dumps({"Type": "Change", "Changes": {"zone": args.zone, "power": args.power}}).encode('utf-8'))
            time.sleep(15)
        if args.mode:
            send_command(char, json.dumps({"Type": "Change", "Changes": {"zone": args.zone, "mode": args.mode}}).encode('utf-8'))
            time.sleep(15)
        if args.temperature:
            temp_type = 'heat_sp' if args.mode == 1 else 'cool_sp'
            send_command(char, json.dumps({"Type": "Change", "Changes": {"zone": args.zone, temp_type: args.temperature}}).encode('utf-8'))
            time.sleep(15)

finally:
    if p:
        p.disconnect()
        print("Disconnected from device.")

if name == “main”:
parser = argparse.ArgumentParser(description=“Control a BLE HVAC system.”)
parser.add_argument(“–read”, action=‘store_true’, help=“Read current status from the device”)
parser.add_argument(“–zone”, type=int, help=“Zone number to control”)
parser.add_argument(“–power”, choices=[“On”, “Off”], help=“Power state”)
parser.add_argument(“–mode”, type=int, help=“Mode of operation”)
parser.add_argument(“–temperature”, type=int, help=“Temperature setting”)
args = parser.parse_args()

main(args)

There is a current regression with the RAD/WRITE commands in OpenMQTTGateway :frowning:

You could try with an older version like 1.2.0 or hang on until this is being addressed in the current development branch.

I’ve got this working now using Armbian and a docker instance sending commands.

100% glad that there is an issue and I’m not insane!