Ac infinity controller 67 Bluetooth temp, humidity, fan pwm

Do I have to put this bit in automations.yaml?

I get an error cos I have automation: already at the top of the config file.

automation:

  • alias: “run_set_acinfinity”
    trigger:
    platform: state
    entity_id: input_number.acinfinity_speed
    action:
    service: shell_command.set_acinfinity_speed
    image

I think it can be in the main configuration.yaml or the automations.yaml. Personally I have a separate file called acinfinity.yaml inside a packages folder with just the contents of that post above, all together in one file. then in my main configuration.yaml I have

homeassistant:
  packages: !include_dir_named packages

which loads any .yaml file that is placed in the packages sub folder. I am not sure if this is still the recommended way, but it is the way I’ve been doing things!

Hmm its still not working.

Ive got the input:

image

This is in my configruation.yaml:

This is the aci script:

This is in automations.yaml:

image

I ran this in Terminal:

What have I stuffed up? =)

Sorry, my fault - I had a mistake in the script above, have fixed it now

/usr/bin/expect

this should be the path for expect, not /config/expect.

Also you can use dev tools → states to manually set the value of your input_number, which might help troubleshoot/explain

You sir are an absolute bloody legend!!

It is working!

This is amazing. Thank you so much for your time helping me today I really really appreciate it the internet is a beautiful place.

1 Like

Awesome, glad to hear, this thread has been a very nice example of HA community spirit.

I think this is really just the start of this thread and potential ac infinity integration, thanks a lot for testing.

2 Likes

@jayrama @Samsung123 you guys been at this all night? Nice work !!!

@Samsung123 if your using this to grow you’ll love my next idea… it using a security camera to take live snaps of your plants , uses a program to see if anything is wrong with them, then recommends treatment if necessary

Hopefully allowing AI to grow our plants

@jayrama can you make a switch that allows on/off.

My idea was to try to recreate the ac infinity interface

read the post but didnt get us any closer to pulling that info, which is weird since on the 69 its sent non stop…

i fired up wireshark and sniffed advertising packets then used LightBlue to send those codes back to the peripheral uuids. made sure ones that could were listening for notifications but havent seen anything promising from that route. ill go back to gatttool and see if i can pull anything the old fashion route - wiped 7-11 out of red bulls so im good to put in another 18 cracking

I couldn’t tell the functional difference between off and on/0, so figured setting 0 was good enough - is there a good reason to turn off entirely instead?

1 Like

because the commands are there and it looks cool? it may save some electrical cost? power consumption

honestly no, in mine i have it set the same way expect i added off at 10 setting, just because i started with on10 / off 10

ive been playing with 67 for a hour or so and theres nothing coming from the thing in terms of temp/humid readings , which i find weird since ive found it on the 69 pro and the multi plug outlet

both using same uuid and just opened notifications.

doing the same on the 67 has just produced a silent uuid, so i sent commands to the other to get notifications and nothing promising so far

1 Like

notified from 70d51002-2c7f-4e75-ae8a-d758951c34e0

69 pro
1e ff 02 09 03 1c 4c 01 08 41 13 3b 00 * 7e * 00 00 00 05 1d 4c 00 01 ff ff 00 01 ff ff 00 01 ff ff 00 01

75 outlet
1e ff 02 09 03 14 4c 01 0a 27 0c 22 00 *d9 *3d b8 00 01 3d b8 00 03 3d b8 00 01

on the 67 im getting no response, even when poking it with a few values

@jayrama ive download the apk to pc, ill see if i can take a look inside and see if theres anything useful

 private static void resoleCDevice(Device device, byte[] bArr) {
        byte b = bArr[13];
        device.isDegree = !ByteUtils.getBit(b, 1);
        device.tmpState = (byte) ByteUtils.getBits(b, 4, 2);
        device.humState = (byte) ByteUtils.getBits(b, 6, 2);
        device.tmp = ByteUtils.getShort(bArr, 15) * 10;
        device.hum = (bArr[17] & 255) * DataFragment.TAG_FILTER_TEMPERATURE;
        byte b2 = bArr[14];
        device.autoHighTmpSwitch = !ByteUtils.getBit(b2, 4);
        device.autoLowTmpSwitch = !ByteUtils.getBit(b2, 5);
        device.autoHighHumSwitch = !ByteUtils.getBit(b2, 6);
        device.autoLowHumSwitch = !ByteUtils.getBit(b2, 7);
        if (device.isDegree) {
            device.autoHighTmp = bArr[20];
            device.autoLowTmp = bArr[21];
        } else {
            device.autoHighTmp = bArr[18];
            device.autoLowTmp = bArr[19];
        }
        device.autoHighHum = bArr[22];
        device.autoLowHum = bArr[23];
    }

    private static void resoleABDevice(Device device, byte[] bArr) {
        byte b = bArr[13];
        device.isDegree = true ^ ByteUtils.getBit(b, 1);
        device.fanState = (byte) ByteUtils.getBits(b, 2, 2);
        device.tmpState = (byte) ByteUtils.getBits(b, 4, 2);
        device.humState = (byte) ByteUtils.getBits(b, 6, 2);
        device.tmp = ByteUtils.getShort(bArr, 14);
        device.hum = ByteUtils.getShort(bArr, 16);
        device.fan = bArr[18];
    }
}
06:26:11.971 - Connecting to nearby peripheral: 4GRDH 
06:26:12.537 - Connected to nearby peripheral: 4GRDH 
06:26:12.638 - Discovered nearby peripheral: (null) (RSSI: -86) 
06:26:13.522 - Characteristic (2A24) read: <41432049 6e66696e 69747900> 
06:26:13.545 - Characteristic (2A27) read: <312e31> 
06:26:13.575 - Characteristic (2A28) read: <312e302e 3534> 
06:26:13.651 - Discovered nearby peripheral: M203T_d16b74 (RSSI: -71) 
06:26:13.872 - Stopping search for nearby peripherals 
06:26:16.342 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) read: <11223344> 
06:26:18.233 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08070e7c 00930000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:47.232 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08040e42 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:48.237 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e44 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:49.235 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e45 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:50.233 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08040e44 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:51.230 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08030e42 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:52.235 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e40 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:53.232 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e44 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:54.230 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e44 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:55.250 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08030e3c 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:56.233 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e3f 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 
06:37:57.230 - Characteristic (70D51002-2C7F-4E75-AE8A-D758951CE4E0) notified: <1eff0209 031c0001 08060e49 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001> 


<1eff0209 031c0001 08060e49 00950000 00051d4c 0001ffff 0001ffff 0001ffff 0001>

think temp humidity are located here

apk is on another pc, i used @luma github repo to pull these

1 Like
public static int getTmp(int i, boolean z) {
        if (i == -32768) {
            return 0;
        }
        if (z) {
            return Math.round(((float) i) / 100.0f);
        }
        return Math.round((((((float) i) / 100.0f) * 9.0f) / 5.0f) + 32.0f);

DUDE. GET ME ON YOUR TEST. I have my security camera running a timelapse doing a snapshoit every 15 minutes with Blue Iris.

I’m crop steering, I’ve got all the bells and whistles to measure moisture, EC etc in the root zone.

my test are usually clunky things that work together

so far i just have to upload a base64 image to something crazy Jay would figure it out in seconds watch

Clunky things that work together is literally my life.

1 Like

awesome, will take a look at the sensor stuff later today, thanks mikey.

new project sounds interesting, im using frigate with a google coral here for camera AI

1 Like

so…pulled new data from the 69 to finish integration, from how to reverse bluetooth device on youtube…

and finding the checksum of the value has killing me for awhile… but i think i found something

dunno if its something or not but here goes

CRC-16/CCITT-FALSE

by removing the front common and incrementing value were left with “00031001 021201 0aff01 209a”

putting that into crccalc and removing the end byte 20 9a, it returns CRC-16/CCITT-FALSE to have value 209a

works on all on commands so far, 1 step closer?

a5000008 00ac71fe 00031001 021201 0aff01 209a
a5000008 00b5f2e6 00031001 021201 09ff01 79ca
a5000008 00cc1d58 00031001 021201 08ff01 4efa
a5000008 00db7f8e 00031001 021201 07ff01 62cb
a5000008 00ea59fc 00031001 021201 06ff01 55fb
a5000008 00f97bae 00031001 021201 05ff01 0cab
a5000008 0106566f 00031001 021201 04ff01 3b9b
a5000008 0117547f 00031001 021201 03ff01 be0b
a5000008 012322a8 00031001 021201 02ff01 893b
a5000008 013110db 00031001 021201 01ff01 d06b
a5000008 013bb191 00031001 021201 00ff01 e75b

a5000008 003b82a0 00031001 011101 0aff01 00a8
a5000008 0049dc75 00031001 011101 09ff01 59f8
a5000008 00550fc8 00031001 011101 08ff01 6ec8
a5000008 006719d9 00031001 011101 07ff01 42f9
a5000008 00725b4d 00031001 011101 06ff01 75c9
a5000008 007f8ae0 00031001 011101 05ff01 2c99
a5000008 008a355a 00031001 011101 04ff01 1ba9
a5000008 0096e6e7 00031001 011101 03ff01 9e39
a5000008 00ac71fe 00031001 011101 02ff01 a909
a5000008 00b8234b 00031001 011101 01ff01 f059
a5000008 00d84fed 00031001 011101 00ff01 c769
import asyncio
from bleak import BleakClient
from crccheck.crc import CRC-16/CCITT-FALSE

address = "34:85:18:6a:52:52"

async def main(address):
    async with BleakClient(address) as client:
        header = bytes.fromhex("a500000800ac71fe")
        command = bytes.fromhex("000310010212010aff01")
        crcinst = CRC-16/CCITT-FALSE
        crcinst.process(command)
        model_number = await client.write_gatt_char("70d510012c7f4e75ae8ad758951ce4e0 ", header + command + crcinst.finalbytes())

asyncio.run(main(address))

remember pip install asyncio bleak crccheck

1 Like

too bad crccheck.crc doesnt include crc-16/CITT…

you already do this?