Comfort Masters walked my house, did the measurements, talked through duct balancing and a proper heat-load calculation, and handed me a number: $24,000 to fix the way my house cools.
The problem is real. A few rooms, mine worst of all, run hot no matter what my central air does, because the house has an overwhelming heat load. A balanced system sized to a real Manual J load is the correct answer. But $24,000 is a lot of correct, and I’m not ready to spend it today.
So I passed for now and kept running the central air I already have. To pick up the slack in the rooms it can’t keep cold on its own, I bought three Midea 12,000 BTU Duo portable air conditioners, around $400 each, and put Home Assistant in charge of them. I’d rather pay a bit more on the power bill every month than $24,000 up front.
Why my room is the hard case
My bedroom is the worst room in the house for this, and it has every excuse to be. It sits over an uninsulated garage, so the floor is whatever temperature the garage is. The windows are old single-pane aluminum, the siding is original, the house leaks air, and there isn’t enough insulation anywhere. The central air runs, but in summer this room soaks up heat from below and through the walls faster than one vent can pull it back out.
Fixing the envelope is a winter project: windows, siding, insulation, sealing up the garage ceiling. That’s the real answer the $24,000 quote was aimed at. Until then I’m brute-forcing comfort, which is exactly what a portable unit and some automation are good at.
The units
All three are the same Midea 12,000 BTU Duo. I bought mine at Costco, and right now they’re on sale there for $379.99 in store or $409 online. The same unit on Amazon is $619 as I write this, so the Costco price is the one to catch if you have a membership.
Here’s where they live:
- Brandon room, my room, the priority. I want it cold at all times, including overnight.
- Cat room upstairs. The network closet is inside this room’s closet, so cooling here protects my gear too.
- Guest bedroom, on its own circuit, only needs a few short runs a day.
One physical constraint drives the whole design: the Brandon room unit and the cat room unit are on the same 20-amp circuit. They can’t both run at once. Start both compressors and the breaker trips. Everything below is built around never letting that happen.
Getting them into Home Assistant
These are Matter devices, so the join was painless. I added each one to the Apple Home app first, then shared it into Home Assistant over Matter using the new matter.js app and integration. No Midea cloud account, and nothing sitting in the middle that breaks when the vendor pushes new firmware.
Each unit shows up natively as a handful of entities:
- A climate entity, the thermostat itself: off, cool, or fan only
- A fan entity with low, medium, high, and auto speeds
- A temperature sensor reading from the unit
The fan entity is the one that matters. I can set fan speed without touching the thermostat, and everything below depends on that.
A better sensor than the one in the AC
First thing I changed: I stopped trusting the temperature reading built into each AC. Those sensors sit right next to the cold-air intake, so they read low and jump around. Fine for the unit’s own thermostat, useless for deciding what the room actually feels like.
So I drive everything off dedicated room sensors instead. My room uses a Zooz ZSE44 temperature and humidity sensor, and the cat room, guest room, and network closet each have their own. Real room air, measured away from the cold blast. Every decision below reads from those, not from the AC.
Keeping my room cold without the fan hunting
A portable AC’s thermostat is crude. Set it to 70 and it cycles the compressor on and off around that number, and the room temperature swings with it. I didn’t want swings. So I set my unit to its minimum, 61 degrees, which means the compressor basically never reaches target and just runs continuously. Then I control comfort entirely with fan speed.
The first version flipped the fan up and down constantly. It would ramp down to low, then back to high a few minutes later, over and over. The problem was that my trigger points sat right inside the temperature range where the room normally hovers, so the smallest drift kept crossing a line.
The fix is a deadband. The fan rests on medium across a comfortable zone and only changes when the room really leaves it:
- Above 70 degrees, fan goes high, and it reacts fast, after 2 minutes
- 68 to 70 degrees, fan sits on medium, the normal resting state
- Below 68 degrees, fan drops to low, but slowly, only after 10 minutes
Making the “drop the fan” decision deliberately slow is what killed the hunting. A brief cool dip isn’t enough to ramp down anymore. The room sits in its band and the fan barely moves.
The breaker interlock
This is the safety-critical piece. My room and the cat room can’t cool at the same time.
The rule is simple and absolute: if both units are ever in cool mode at once, the cat room unit switches off immediately. My room wins. The Midea units don’t report over Matter whether the compressor is actually drawing power, only what mode they’re in, so I treat “cool mode” as “drawing power” and never allow the overlap. It’s the conservative read, and I’d rather be conservative than go reset a breaker.
Cooling the network closet on demand
The network closet lives in the cat room’s closet, and networking gear makes heat. But the gear has its own fans, so I let it run warmer than a living space.
When the closet climbs above 87 degrees, or the cat room itself gets above 82, a separate automation kicks in:
- It turns my AC fully off first, freeing the 20-amp circuit.
- It runs the cat room unit on high, set to 72.
- It guarantees a protected 15-minute minimum so the closet actually gets cooled.
- After that it ends as soon as the closet drops back down, the cat room cools off, or my room creeps above 75 degrees, whichever comes first.
- Then it turns my AC back on and restores everything.
That fourth point is the one I care about most. Turning my own AC off for up to half an hour to cool a closet is a fine trade, right up until my room gets uncomfortable. So I automated the line I wasn’t willing to cross: if my room hits 75, the closet burst ends early and my cooling comes back, no matter what.
The guest room
The guest room is the easy one. It’s on a separate circuit, so it never threatens the breaker. It runs a 25-minute burst whenever its sensor reads above 79 degrees, and sends a notification to my phone reminding me to open the guest room door so the cool air spills into the upstairs living room. Temperature-driven, not on a clock, so it only runs when there’s a reason to.
Mr. Freeze mode
Sometimes I don’t want comfortable. I want cold. Movie night, a brutal afternoon, whenever.
So I built a button. One toggle in Home Assistant, which I can hit from a dashboard or say to Siri. When it turns on, it:
- Drops the Ecobee to 68 to pull the whole house down
- Runs my room and the guest room both on high
- Starts a 2-hour timer so it can’t run all night by accident
While Mr. Freeze is on, the normal fan logic steps aside so my room stays pinned on high instead of politely ramping itself back down. When the timer runs out, or I flip it off, everything reverses: the Ecobee hold is cancelled so it returns to its schedule, the guest room shuts off, and my room goes back to its steady 61-and-modulate-the-fan routine.
I turned it on for a movie the other night. Within seconds the Ecobee was holding 68, both units were on high, and a notification told me it would shut itself off in two hours. That’s the whole point: a one-tap cold blast I don’t have to remember to undo.
The automations
There are three. AC Manager does the everyday work: the fan deadband, the breaker interlock, and the guest room burst, all keyed off trigger IDs. The burst cool automation handles the network closet. Mr. Freeze Mode is the on-demand override.
AC Manager:
alias: AC Manager
mode: parallel
max: 10
triggers:
- alias: Brandon room above 70F for 2 min
trigger: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 70
for: "00:02:00"
id: fan_high
- alias: Brandon room 68 to 70F for 5 min
trigger: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 68
below: 70
for: "00:05:00"
id: fan_medium
- alias: Brandon room below 68F for 10 min
trigger: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
below: 68
for: "00:10:00"
id: fan_low
- alias: Brandon AC switched to cool (init fan)
trigger: state
entity_id: climate.brandon_ac
to: cool
id: fan_init
- alias: Cat Room AC switched to cool (interlock)
trigger: state
entity_id: climate.cat_room_upstairs_ac
to: cool
id: interlock
- alias: Brandon AC switched to cool (interlock)
trigger: state
entity_id: climate.brandon_ac
to: cool
id: interlock
- alias: Guest room above 79F for 5 min
trigger: numeric_state
entity_id: sensor.guest_room_temperature
above: 79
for: "00:05:00"
id: guest
actions:
- choose:
- alias: Hot, set Brandon fan to high
conditions:
- condition: trigger
id: fan_high
- condition: state
entity_id: input_boolean.mr_freeze_mode
state: "off"
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: high
- alias: Comfortable, set Brandon fan to medium
conditions:
- condition: trigger
id: fan_medium
- condition: state
entity_id: input_boolean.mr_freeze_mode
state: "off"
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: medium
- alias: Cool, set Brandon fan to low
conditions:
- condition: trigger
id: fan_low
- condition: state
entity_id: input_boolean.mr_freeze_mode
state: "off"
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: low
- alias: Init Brandon fan when AC turns on
conditions:
- condition: trigger
id: fan_init
- condition: state
entity_id: input_boolean.mr_freeze_mode
state: "off"
sequence:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 70
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: high
- conditions:
- condition: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 68
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: medium
default:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: low
- alias: Breaker interlock, Brandon wins, Cat Room off
conditions:
- condition: trigger
id: interlock
- condition: state
entity_id: climate.brandon_ac
state: cool
- condition: state
entity_id: climate.cat_room_upstairs_ac
state: cool
sequence:
- action: climate.set_hvac_mode
target:
entity_id: climate.cat_room_upstairs_ac
data:
hvac_mode: "off"
- alias: Guest room 25-min cooling burst
conditions:
- condition: trigger
id: guest
sequence:
- action: climate.set_hvac_mode
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
hvac_mode: cool
- action: climate.set_temperature
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
temperature: 70
- action: fan.set_preset_mode
target:
entity_id: fan.guest_bedroom_guest_room_ac
data:
preset_mode: high
- action: notify.mobile_app_brandon_iphone
data:
title: Guest room cooling
message: >-
Guest room is above 79F, AC running 25 min. Open the guest room
door to push cool air into the upstairs living room.
- delay: "00:25:00"
- action: climate.set_hvac_mode
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
hvac_mode: "off"
The network closet burst, in its own automation so it can’t tangle with the everyday fan logic:
alias: Cat Room / Network Closet burst cool
mode: single
triggers:
- alias: Network closet above 87F for 5 min
trigger: numeric_state
entity_id: sensor.network_closet_temperature
above: 87
for: "00:05:00"
id: closet
- alias: Cat room above 82F for 5 min
trigger: numeric_state
entity_id: sensor.cat_room_temperature
above: 82
for: "00:05:00"
id: catroom
actions:
- alias: Turn Brandon AC off (free the 20A circuit)
action: climate.set_hvac_mode
target:
entity_id: climate.brandon_ac
data:
hvac_mode: "off"
- delay: "00:00:05"
- action: climate.set_hvac_mode
target:
entity_id: climate.cat_room_upstairs_ac
data:
hvac_mode: cool
- action: climate.set_temperature
target:
entity_id: climate.cat_room_upstairs_ac
data:
temperature: 72
- action: fan.set_preset_mode
target:
entity_id: fan.cat_room_upstairs_ac
data:
preset_mode: high
- alias: Protected 15-min minimum run
delay: "00:15:00"
- alias: Wait until satisfied or Brandon room hits 75F (max 15 more min)
wait_for_trigger:
- trigger: numeric_state
entity_id: sensor.network_closet_temperature
below: 80
- trigger: numeric_state
entity_id: sensor.cat_room_temperature
below: 76
- trigger: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 75
timeout: "00:15:00"
continue_on_timeout: true
- action: climate.set_hvac_mode
target:
entity_id: climate.cat_room_upstairs_ac
data:
hvac_mode: "off"
- action: climate.set_hvac_mode
target:
entity_id: climate.brandon_ac
data:
hvac_mode: cool
- action: climate.set_temperature
target:
entity_id: climate.brandon_ac
data:
temperature: 61
And Mr. Freeze, which is just an input_boolean plus a timer:
alias: Mr Freeze Mode
mode: queued
max: 5
triggers:
- alias: Mr Freeze turned on
trigger: state
entity_id: input_boolean.mr_freeze_mode
to: "on"
id: activate
- alias: Mr Freeze turned off
trigger: state
entity_id: input_boolean.mr_freeze_mode
to: "off"
id: deactivate
- alias: Mr Freeze timer finished
trigger: event
event_type: timer.finished
event_data:
entity_id: timer.mr_freeze
id: timer_done
actions:
- choose:
- alias: Activate, max cooling
conditions:
- condition: trigger
id: activate
sequence:
- action: climate.set_temperature
target:
entity_id: climate.ecobee
data:
temperature: 68
- action: climate.set_hvac_mode
target:
entity_id: climate.brandon_ac
data:
hvac_mode: cool
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: high
- action: climate.set_hvac_mode
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
hvac_mode: cool
- action: climate.set_temperature
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
temperature: 70
- action: fan.set_preset_mode
target:
entity_id: fan.guest_bedroom_guest_room_ac
data:
preset_mode: high
- action: timer.start
target:
entity_id: timer.mr_freeze
- action: notify.mobile_app_brandon_iphone
data:
title: Mr Freeze on
message: >-
Ecobee set to 68F, Brandon + Guest rooms on high. Auto-ends in
2h or when you turn it off.
- alias: Timer done, turn Mr Freeze off
conditions:
- condition: trigger
id: timer_done
sequence:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.mr_freeze_mode
- alias: Deactivate, restore normal cooling
conditions:
- condition: trigger
id: deactivate
sequence:
- action: timer.cancel
target:
entity_id: timer.mr_freeze
- action: ecobee.resume_program
target:
entity_id: climate.ecobee
data:
resume_all: true
- action: climate.set_hvac_mode
target:
entity_id: climate.guest_bedroom_guest_room_ac
data:
hvac_mode: "off"
- action: climate.set_hvac_mode
target:
entity_id: climate.brandon_ac
data:
hvac_mode: cool
- action: climate.set_temperature
target:
entity_id: climate.brandon_ac
data:
temperature: 61
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 73
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: high
- conditions:
- condition: numeric_state
entity_id: sensor.brandon_room_climate_air_temperature
above: 69
sequence:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: medium
default:
- action: fan.set_preset_mode
target:
entity_id: fan.brandon_ac
data:
preset_mode: low
The math
Let me be honest about the running cost, because my first guess was way too low.
One of these units pulls up to 11.9 amps, about 1.4 kW at the wall. Mine runs close to around the clock. Call it a conservative 1.2 kW on average: 1.2 kW times 24 hours times 30 days is roughly 860 kWh a month for that one unit. Residential power around here runs about 16 cents a kWh right now and climbs in summer, so my room alone is somewhere near $140 a month when it’s hot. The other two run in bursts, so add maybe $40 to $80 on top. And this is on top of the central air I’m already running, not instead of it. Realistically the portables cost me $150 to $250 a month in the worst summer months, not the $50 to $100 I first assumed.
Now the up-front side. Three units at the Costco price is about $1,150, against the $24,000 quote to fix it properly. Even if the portables cost me an extra $250 every single month, all year, that’s $3,000 a year, and it would still take the better part of a decade to spend the difference, and they won’t cost that in winter. By then I’ll have either chipped away at the windows and insulation myself or saved up for the real system on my own schedule.
A $24,000 system is the right call if you want it done once and never think about it again. I’d rather keep the money for now, run three cheap boxes hard, and let the automations hold comfort right where I sit until I get to the windows and insulation.