Omahub
← All plugins
K

AC Control

by kader

Mitsubishi M-NET HVAC control with per-zone temperature, mode, fan, air direction, filter and fault status, and alarms

Security review

Review recommended · 1 finding

Deterministic scan — not a security guarantee

Low
Risk level
Low
Analyzed commit
7e0e8d1
Scanned
1 month ago

Flagged patterns appear only in documentation files (README / docs) — descriptive examples, not executable code.

  • Docs package_manager README.md:20

    System-wide Python package installation (not --user).

    pip install requests`, or your distro's package).

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
7e0e8d1
Reviewed
1 month ago

The plugin is a straightforward HVAC control widget that communicates with a Mitsubishi M-NET gateway over HTTP/XML. The code is well-structured, includes proper error handling and timeouts, and does not perform any system-modifying actions beyond reading/writing its own config file. The only flagged item is a README suggestion to install the `requests` package system-wide, which is documentation only and not part of the plugin's execution.

  • The README suggests `pip install requests` without `--user`, which could affect system Python, but this is a user action and not executed by the plugin itself.
  • The plugin communicates with an unauthenticated HTTP gateway, but this is inherent to the hardware and clearly documented as a trusted-LAN assumption.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/aallamaa/hvac --enable
Widgets #bar

mhvac.ac — Omarchy AC control plugin

Bar widget for the Omarchy shell (Quickshell) that controls a Mitsubishi M-NET HVAC system: per-zone status, on/off, mode, temperature, and fan speed, from a popup anchored to a bar icon.

If the gateway can't be reached (or the status call fails for any reason), the bar icon switches to the theme's urgent/red color and drops the temperature reading rather than showing a stale value.

preview

Requirements

  • A Mitsubishi M-NET HVAC system reachable over the network through an HTTP/XML gateway (servlet/MIMEReceiveServlet) — this is a specific integration, not a generic "any AC" plugin. If your gateway doesn't speak this protocol, this plugin won't talk to it.
  • python3 on PATH, with the requests package installed (pip install requests, or your distro's package).
  • Network access from the machine running Omarchy to the gateway.

No elevated privileges are needed — everything runs as your normal user.

The M-NET HTTP/XML gateway protocol provides no authentication or encryption. This plugin assumes the gateway is reachable only over a trusted LAN; do not expose it directly to untrusted networks or the public internet.

Install

omarchy plugin add https://github.com/aallamaa/hvac.git --enable

Then place it on the bar (if --enable didn't already):

omarchy bar move mhvac.ac --section right

The widget works without a terminal shortcut. To use the shorter ac ... commands shown below, install an optional symlink to the deployed CLI:

mkdir -p ~/.local/bin
ln -s ~/.config/omarchy/plugins/mhvac.ac/ac_cli.py ~/.local/bin/ac

If that path already exists, inspect or remove it before creating the link; the command intentionally does not overwrite an existing file.

Usage

Click the snowflake icon in the bar to open the popup. Each zone shows:

  • a power button (on/off)
  • the current room temperature
  • a mode button (cycles through that zone's supported modes)
  • a fan-speed button (cycles through that zone's supported speeds)
  • an air-direction button when the indoor unit reports vane control support
  • a −/+ temperature stepper

An active filter-cleaning reminder shows the 󰵃 filter icon in the urgent color; hover it to see Filter ON. Active faults add [FAULT] in the urgent color; use ac alarms for the controller's detailed M-NET address, numeric alarm code, model, and detection time.

"All On"/"All Off" at the top act on every configured zone. The "AVG: N°" button next to them cycles the bar icon's own temperature display through avg/min/max/off (see Configure).

The bar icon itself shows an aggregate temperature reading whenever sensor data is available (regardless of whether a zone is on), and turns the theme's urgent/red color if the gateway can't be reached.

Configure

Gateway host/port, zone names, and per-zone capabilities live in ~/.config/ac-plugin/config.json, not in the code:

{
  "host": "192.168.1.2",
  "port": 80,
  "icon_temp": "avg",
  "zones": {
    "1": { "name": "Living room", "modes": ["COOL", "DRY", "FAN"], "fan_speeds": ["AUTO", "MID1", "MID2", "HIGH"], "air_directions": [] },
    "6": { "name": "Office", "modes": ["COOL", "HEAT", "DRY", "FAN"], "fan_speeds": ["LOW", "MID1", "MID2", "HIGH"], "air_directions": ["HORIZONTAL", "MID1", "MID2", "VERTICAL"] }
  }
}

icon_temp controls what number the bar icon shows next to the snowflake across available zone temperature readings: avg (default), min, max, or off. It's also editable straight from the popup — the "AVG: N°" button in the header cycles through the four values.

modes/fan_speeds are what the popup's mode/fan cycle buttons step through for that zone — see "Per-zone capability discovery" below for where they come from. A zone can also be given as a plain name string ("1": "Living room"); it's upgraded on load to the full shape above, filled in with not-yet-discovered defaults.

If this file (or its zones key) is missing, the popup shows a Discover zones button instead of silently creating configuration. Set the gateway address first if it is not the default, then click that button (or run ac zones-init) to read the configured group inventory and names. On firmware without the inventory API discovery falls back to probing the 50 possible group slots. It never assumes zones 1–6. An explicit "zones": {} is authoritative and means “query and control no groups.” Invalid or unreadable configuration fails closed instead of restoring built-in control targets. The initial gateway default is 192.168.1.2; use set-host or AC_HOST / AC_PORT to point discovery elsewhere. AC_CONFIG_FILE overrides the path.

Finding your zones

ac discover            # read the group inventory (with probe fallback)
ac zones-init          # same, then add groups and gateway-configured names
ac rename 3 "Kids room"
ac set-host 192.168.1.50

set-host changes only the gateway address; it deliberately retains existing zone names and discovered capabilities so an IP-address change does not erase your setup. If the new address points to different hardware, reconcile the saved zones before using bulk controls: run zones-init to add newly discovered groups, then remove stale groups from config.json (and run discover-features to refresh capabilities).

Before replacing an existing configuration, the CLI keeps one recovery copy at ~/.config/ac-plugin/config.json.backup. To restore it, copy it back over config.json while no AC command is running, then reopen the popup:

cp ~/.config/ac-plugin/config.json.backup ~/.config/ac-plugin/config.json

Per-zone capability discovery

Different indoor unit models on the same M-NET system can support different modes and fan speeds. discover-features reads the gateway's capability flags (IcKind, mode switches, fan-stage count, and automatic-fan support) and saves the resulting per-zone choices. It is entirely read-only and does not turn off or change any HVAC unit.

ac discover-features        # every configured zone
ac discover-features 6      # just zone/group 6

AUTOCOOL/AUTOHEAT remain display-only statuses: Mitsubishi integration documentation marks them as not applicable for setting, so the plugin never writes them. Capability results also report air-direction, swing, filter-sign, and error-sign availability in the CLI output.

Update

omarchy plugin update mhvac.ac --yes

Remove

omarchy plugin remove mhvac.ac --yes

That removes the plugin from the bar and deletes ~/.config/omarchy/plugins/mhvac.ac/. It leaves two things behind, which you can delete yourself if you want a full cleanup:

rm -rf ~/.config/ac-plugin           # host/zone/capability config
rm -f ~/.local/bin/ac                # the `ac` CLI shortcut, if installed

Development

Source of truth is this repo; ~/.config/omarchy/plugins/mhvac.ac/ holds a deployed copy (Omarchy's plugin validator rejects symlinks inside a plugin folder, so it can't just point back here). After editing files, redeploy with:

cp mit.py ac_cli.py Panel.qml manifest.json ~/.config/omarchy/plugins/mhvac.ac/

QML edits hot-reload automatically once copied; if changes don't seem to apply, omarchy restart shell forces a clean reload.

  • mit.py — M-NET client (XML over HTTP to the gateway), used as a library.
  • ac_cli.py — CLI wrapper around mit.py. The QML shells out to this for every read and write; it's also usable standalone from a terminal.
  • Panel.qml — the bar icon + popup (Quickshell/QML).
  • manifest.json — Omarchy plugin manifest (id: mhvac.ac).

Running ac_cli.py commands directly

There's no omarchy plugin <id> <command> passthrough — omarchy plugin only manages plugin lifecycle (list/enable/disable/validate). To run ac_cli.py commands yourself, either call it directly:

python3 ~/.config/omarchy/plugins/mhvac.ac/ac_cli.py status

or use the optional ac shortcut described under Install. It lives at ~/.local/bin/ac (normally on PATH) and calls the deployed copy:

ac status

Every subcommand prints one JSON value to stdout and exits 0 on success; on failure it prints {"error": "..."} to stderr and exits 1.

Commands

Command Args Description
status Status of every configured zone (drive, mode, set temp, fan speed, inlet temp).
config Print the resolved config (host, port, zones).
alarms List active detailed controller alarms. Read-only.
on <group> Turn a zone on.
off <group> Turn a zone off.
set-temp <group> <temp> Set target temperature (16–30).
set-fan <group> <speed> Set fan speed: AUTO, LOW, MID1, MID2, or HIGH. Not every zone accepts every value — see "Per-zone capability discovery".
set-mode <group> <mode> Set mode: COOL, HEAT, DRY, FAN, or AUTO. Not every zone accepts every value — see "Per-zone capability discovery".
set-air <group> <direction> Set a capability-discovered vane position such as HORIZONTAL, MID1, MID2, VERTICAL, or SWING.
all-on Attempt to turn on every configured zone and report each result.
all-off Attempt to turn off every configured zone and report each result.
discover [--max N] Read configured groups from the inventory API, falling back to probes when unsupported. Doesn't touch the config.
zones-init [--max N] Run discovery and add new groups using controller-configured names when available; existing names are kept.
discover-features [group] Read mode/fan capability flags for a zone (or every configured zone) and save them. Does not change HVAC state.
rename <group> <name> Set a zone's display name in the config.
set-host <host> [port] Set the gateway host/port in the config (default port 80).
set-icon-temp <mode> Set the bar icon's temperature display: avg, min, max, or off.

Examples

ac status
ac on 3
ac set-temp 3 22
ac set-fan 3 HIGH
ac set-mode 3 COOL
ac rename 3 "Kids room"
ac discover --max 10
ac zones-init
ac discover-features
ac discover-features 6
ac set-host 192.168.1.2

License

GPL-3.0-or-later — see LICENSE.

Protocol references

Mitsubishi does not appear to publish a public specification for the MIMEReceiveServlet XML wire format. The closest vendor documentation found is Mitsubishi Electric's G-50A operation manual and its IP integration instructions, which document 50 groups and identify Auto Cool/Auto Heat as non-settable statuses. The HTTP/XML packet details and one-group-at-a-time discovery are based on observed gateway behavior and independently reverse-engineered clients, not an official public wire-protocol specification.