Package: pycoolmasternet-ng
pycoolmasternet-ngA Python 3.9+ library for interacting with aCoolMasterNetHVAC bridge.
This is a fork ofpycoolmasternet-asyncwith significant changes:Pluggable transportsTransports - methods that define communication with the CoolMasterNet device - are now in classes. TCP/IP and RS232 is implemented, REST is TODO, and maybe at some point CoolAutomation's cloud-based service can be reverse-engineered and implemented too (not sure if their cloud service just forwards commands or if it operates at a higher level).More "Pythonic"Most values and data objects are mapped to Python classes - exceptions, enums, etc.Autodiscovery of device capabilitiesDevice capabilities are now inferred from "properties" saved in the CoolMasterNet unit. This means the CM device holds all configuration and the home automation controllers can just autodiscover them. See the CoolMasterNet manual on how to set these (you'll need to manually Telnet/serial in to set them first).Device capability databaseThere's a (work-in-progress, currently Mitsubishi Electric only) database of device capabilities such as allowed temperature ranges, etc - this would allow consumers of this library (such as home automation integrations) to autodiscover those and customize their UI accordingly.TODOsynchronous (blocking) interfaceimprove the device DB for non-Mitsubishi-Electric unitsREST transportsupport advanced CoolMasterNet functionality (I only have the CoolLinkHub with CoolPlugs so can't test that yet)InstallationYou can install pycoolmasternet-async fromPyPI:pip3 install pycoolmasternet-ngPython 3.9 and above are supported. As this is primarily designed for use in Home Assistant, support for prior Python versions isn't a priority.Extra protocols such as serial require additional dependencies:pip3 install pycoolmasternet-ng[serial]Basic usagefrompycoolmasternet_ngimporttransports,models,structures,constants# first create a transport - TCP/IP (CoolMasterNet calls this "aserver")ts=transports.TCPTransport("192.168.0.123",port=12345)# or Serialts=transports.SerialTransport('/dev/ttyS0',9600)# now create a gateway connected to your transport# this will internally populate a cache of models.Device objects with their current stategw=awaitmodels.Gateway.from_transport(transport=ts)# a dictionary of structures.UID: models.Devicedevices=gw.devices# get device with UID L5.001device=devices[structures.UID.from_string('L5.001')]# get device infodevice.power_state# Truedevice.mode# constants.Mode.COOLdevice.fan_mode# constants.FanMode.LOWdevice.louver_position# constants.LouverPositionState.NOT_SUPPORTEDdevice.target_temperature# Decimal('21')device.current_temperature# Decimal('22')device.temperature_unit# 'C'device.error_code# Nonedevice.demand# True# refresh that device - this will talk to the gateway to query the device's status and update the objectawaitdevice.refresh()# now check the updated valuesdevice.current_temperature# Decimal('21')device.demand# False# turn device offawaitdevice.set_power_state(False)# see the updated statusdevice.power_state# False# make multiple changesawaitdevice.set_mode(constants.Mode.HEAT,refresh=False)awaitdevice.set_temperature(23,refresh=False)awaitdevice.set_power_state(refresh=False)# note that device.power_state is still False as we haven't refresheddevice.power_state# False# now refresh explicitlyawaitdevice.refresh()# now device.power_state is up to datedevice.power_state# True# refresh all devices on the gatewayawaitgw.refresh()# now gw.devices has been rebuilt with updated models.Device objects# note that the objects are replaced and not updated in-placedevices[structures.UID.from_string('L5.001')]isdevice## FalseCreditskoreth'spycoolmasternetOnFreund'sforkpycoolmasternet-async