Понадобилось мне добавить в Home Assistant свой игровой PC. А именно возможность включения и выключения.
Возможность включение я разберу в другой статье, а в этой расскажу про выключение.
Быстрое гугление наводит на:
net rpc shutdown
Но я использую Home Assistant в Hass.io на малинке, а там не так просто доустановить отсутствующие утилиты. Нужен был способ исключительно на Python.
Я нашёл интересную библиотеку pypsexec и решил оформить её в виде компонента HA. Библиотека создаёт исполняемые exe-шники в папке Windows и запускает их через службы Windows, которые так же создаёт. Я решил немного поправить этот подход и обойтись только созданием служб Windows. Вот что получилось:
/config/custom_components/psexec/__init__.py
""" Компонент добавляет службу `psexec.exec` удаленного выполнения команд на компьютерах Windows через протокол `SMB 2`. В момент выполнения на удалённом компьютере создаётся и запускается служба Windows, выполняющая указанную команду. По завершению выполнения служба удаляется. Удалённый пользователь должен быть администратором. Если на удалённом компьютере включен UAC - необходимо внести правки в реестр: ``` Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System] "LocalAccountTokenFilterPolicy"=dword:00000001 ``` Если удалённый Windows старый (например win7) - необходимо указывать параметр `encrypt=false`. Подробности тут: https://pypi.org/project/pypsexec/ Пример использования (создаст в корне диска C файл out.txt): ``` script: smb_remote: sequence: - service: psexec.exec data: host: 192.168.1.123 username: user password: pass encrypt: false command: cmd.exe /c echo Hello World > c:\out.txt ``` Для засыпания компьютера необходимо отправить команду: ``` cmd.exe /c start /b shutdown.exe /h ``` - `cmd.exe /c` - выполняет далее указанную команду (для start нет exe файла) - `start /b` - запускает следующую команду в фоне (нельзя дожидаться окончания выполнения shutdown - мы его не дождёмся) - `shutdown.exe /h` - отправляет компьютер в сон (или гибернацию в зависимости от настроек компьютера) Компонент протестирован в HA на Windows и в Hass.io на Raspberry Pi 3. """ import logging _LOGGER = logging.getLogger(__name__) DOMAIN = "psexec" def setup(hass, config): def exec(call): import uuid from smbprotocol.connection import Connection from smbprotocol.session import Session from pypsexec.scmr import Service host = call.data.get('host') username = call.data.get('username') password = call.data.get('password') encrypt = call.data.get('encrypt', True) command = call.data.get('command') try: connection = Connection(uuid.uuid4(), host) connection.connect() session = Session(connection, username, password, require_encryption=encrypt) session.connect() service = Service('HomeAssistant', session) service.open() try: service.create(command) except: _LOGGER.exception("Can't create service") try: service.start() except: # Произвольный EXE-файл не может быть полноценной Службой, # поэтому даже при успешном выполнении мы будем получать ошибку pass try: service.delete() except: _LOGGER.exception("Can't delete service") service.close() connection.disconnect() except: _LOGGER.exception(f"Can't connect to: ") hass.services.register(DOMAIN, 'exec', exec) return True
/config/custom_components/psexec/manifest.json
{ "domain": "psexec", "name": "PsExec", "documentation": "https://www.home-assistant.io/", "dependencies": [], "codeowners": [ "AlexxIT" ], "requirements": [ "pypsexec" ] }
Для появления соотвествующей службы в Home Assistant необходимо включить компонент в configuration.yaml
psexec:
Пример использования и краткое описание приведены в комментариях к коду.
Конечно компонент можно использовать не только для удалённого выключения компьютера, а для совершенно разнообразных целей.