mirror of
https://github.com/filipvh/lg-airco-modbus-mqtt.git
synced 2024-10-05 01:49:08 +00:00
push with some fixes and docker build/push github workflow
This commit is contained in:
parent
4df409c520
commit
71919d3067
43
.github/workflows/build.yaml
vendored
Normal file
43
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
name: Build prod docker app
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: registry.hub.docker.com
|
||||||
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
password: ${{ secrets.REGISTRY_SECRET }}
|
||||||
|
|
||||||
|
- name: Set up Docker Context for Buildx
|
||||||
|
id: buildx-context
|
||||||
|
run: |
|
||||||
|
docker context create builders
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
endpoint: builders
|
||||||
|
- name: Get version
|
||||||
|
id: get_version
|
||||||
|
run: |
|
||||||
|
echo "VERSION=$(cat version.info)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
tags: registry.hub.docker.com/${{ secrets.REGISTRY_USERNAME }}/${{ github.event.repository.name }}:${{ env.VERSION }}
|
||||||
|
|
28
Dockerfile
Normal file
28
Dockerfile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Use the official Python 3.11 image as a parent image
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
# Set environment variables
|
||||||
|
# Prevents Python from writing pyc files to disc (equivalent to python -B option)
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE 1
|
||||||
|
# Prevents Python from buffering stdout and stderr (equivalent to python -u option)
|
||||||
|
ENV PYTHONUNBUFFERED 1
|
||||||
|
|
||||||
|
# Set work directory
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
|
# Install OS dependencies (if any), keeping the image as small as possible
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Python dependencies
|
||||||
|
# Copy the requirements.txt file into the container at /usr/src/app/
|
||||||
|
COPY requirements.txt .
|
||||||
|
# Install the Python dependencies
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copy the rest of the codebase into the container
|
||||||
|
COPY version.info .
|
||||||
|
COPY ./src ./src
|
||||||
|
|
||||||
|
# Command to run the application
|
||||||
|
CMD ["python", "src/server.py"]
|
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
@ -14,32 +14,40 @@ from state_service import StateService
|
|||||||
class ModbusClient:
|
class ModbusClient:
|
||||||
def __init__(self, config: ModbusConfig, state_service: StateService):
|
def __init__(self, config: ModbusConfig, state_service: StateService):
|
||||||
self._config = config
|
self._config = config
|
||||||
|
self._client = None
|
||||||
self._state_service = state_service
|
self._state_service = state_service
|
||||||
self._client = ModbusTcpClient(host=config.host, port=config.port)
|
|
||||||
self._poll_interval = config.poll_interval
|
self._poll_interval = config.poll_interval
|
||||||
self._shutdown_event = Event()
|
self._shutdown_event = Event()
|
||||||
self._loops_to_skip = 0
|
self._loops_to_skip = 0
|
||||||
|
|
||||||
def start_polling(self) -> None:
|
def connect(self) -> None:
|
||||||
logger.info("Modbus | Starting the modbus polling...")
|
logger.info(f"Modbus | Connecting to {self._config.host}:{self._config.port}.")
|
||||||
|
self._client = ModbusTcpClient(host=self._config.host, port=self._config.port)
|
||||||
|
self._client.connect()
|
||||||
|
if not self._client.is_socket_open():
|
||||||
|
raise Exception('Modbus | Could not open connection.')
|
||||||
|
logger.info("Modbus | Connected.")
|
||||||
|
logger.info("Modbus | Starting the modbus polling.")
|
||||||
self._shutdown_event.clear()
|
self._shutdown_event.clear()
|
||||||
self._schedule_next_poll()
|
self._schedule_next_poll()
|
||||||
|
|
||||||
def stop_polling(self) -> None:
|
def disconnect(self) -> None:
|
||||||
logger.info("Modbus | Stopping the modbus polling...")
|
logger.info("Modbus | Stopping the modbus polling.")
|
||||||
self._shutdown_event.set()
|
self._shutdown_event.set()
|
||||||
if self._poll_timer:
|
if hasattr(self, '_poll_timer') and self._poll_timer:
|
||||||
self._poll_timer.cancel()
|
self._poll_timer.cancel()
|
||||||
|
logger.info("Modbus | Closing the connection.")
|
||||||
|
self._client.close()
|
||||||
|
|
||||||
def _schedule_next_poll(self):
|
def _schedule_next_poll(self) -> None:
|
||||||
if not self._shutdown_event.is_set():
|
if not self._shutdown_event.is_set():
|
||||||
self._poll_timer = Timer(interval=self._poll_interval, function=self._poll_modbus_server)
|
self._poll_timer = Timer(interval=self._poll_interval, function=self._poll_modbus_server)
|
||||||
self._poll_timer.start()
|
self._poll_timer.start()
|
||||||
|
|
||||||
def _poll_modbus_server(self):
|
def _poll_modbus_server(self) -> None:
|
||||||
slave = self._config.slave
|
slave = self._config.slave
|
||||||
if self._loops_to_skip>0:
|
if self._loops_to_skip > 0:
|
||||||
logger.debug("Skipping poll")
|
logger.debug("Modbus | Skipping poll")
|
||||||
self._loops_to_skip -= 1
|
self._loops_to_skip -= 1
|
||||||
self._schedule_next_poll()
|
self._schedule_next_poll()
|
||||||
return
|
return
|
||||||
@ -124,41 +132,41 @@ class ModbusClient:
|
|||||||
finally:
|
finally:
|
||||||
self._schedule_next_poll()
|
self._schedule_next_poll()
|
||||||
|
|
||||||
def write_operate(self, value: bool):
|
def write_operate(self, value: bool) -> None:
|
||||||
logger.info(f"Modbus | Writing {value} to operate coil.")
|
logger.debug(f"Modbus | Writing {value} to operate coil.")
|
||||||
self._loops_to_skip = 3
|
self._loops_to_skip = 3
|
||||||
response = self._client.write_coil(address=0, value=value, slave=self._config.slave)
|
response = self._client.write_coil(address=0, value=value, slave=self._config.slave)
|
||||||
if response.isError():
|
if response.isError():
|
||||||
logger.error(f"Modbus | Could not set operate to {value}")
|
logger.error(f"Modbus | Could not set operate to {value}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"Modbus | {response}")
|
logger.debug(f"Modbus | {response}")
|
||||||
|
|
||||||
def set_temperature(self, value: float):
|
def set_temperature(self, value: float) -> None:
|
||||||
temp = int(value*10)
|
temp = int(value*10)
|
||||||
logger.info(f"Modbus | Writing {value} to register 1.")
|
logger.debug(f"Modbus | Writing {value} to register 1.")
|
||||||
self._loops_to_skip = 3
|
self._loops_to_skip = 3
|
||||||
response = self._client.write_register(address=1, value=temp, slave=self._config.slave)
|
response = self._client.write_register(address=1, value=temp, slave=self._config.slave)
|
||||||
if response.isError():
|
if response.isError():
|
||||||
logger.error(f"Modbus | Could not set temperature to {temp}")
|
logger.error(f"Modbus | Could not set temperature to {temp}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"Modbus | {response}")
|
logger.debug(f"Modbus | {response}")
|
||||||
|
|
||||||
def set_mode(self, value: Mode):
|
def set_mode(self, value: Mode) -> None:
|
||||||
mode = value.value
|
mode = value.value
|
||||||
logger.info(f"Modbus | Writing {value} to register 0.")
|
logger.debug(f"Modbus | Writing {value} to register 0.")
|
||||||
self._loops_to_skip = 3
|
self._loops_to_skip = 3
|
||||||
response = self._client.write_register(address=0, value=mode, slave=self._config.slave)
|
response = self._client.write_register(address=0, value=mode, slave=self._config.slave)
|
||||||
if response.isError():
|
if response.isError():
|
||||||
logger.error(f"Modbus | Could not set mode to {mode}")
|
logger.error(f"Modbus | Could not set mode to {mode}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"Modbus | {response}")
|
logger.debug(f"Modbus | {response}")
|
||||||
|
|
||||||
def set_fan_speed(self, value):
|
def set_fan_speed(self, value) -> None:
|
||||||
fan_speed = value.value
|
fan_speed = value.value
|
||||||
logger.info(f"Modbus | Writing {value} to register 0.")
|
logger.debug(f"Modbus | Writing {value} to register 0.")
|
||||||
self._loops_to_skip = 3
|
self._loops_to_skip = 3
|
||||||
response = self._client.write_register(address=14, value=fan_speed, slave=self._config.slave)
|
response = self._client.write_register(address=14, value=fan_speed, slave=self._config.slave)
|
||||||
if response.isError():
|
if response.isError():
|
||||||
logger.error(f"Modbus | Could not set fan speed to {fan_speed}")
|
logger.error(f"Modbus | Could not set fan speed to {fan_speed}")
|
||||||
else:
|
else:
|
||||||
logger.info(f"Modbus | {response}")
|
logger.debug(f"Modbus | {response}")
|
0
src/models/__init__.py
Normal file
0
src/models/__init__.py
Normal file
@ -1,5 +1,3 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
@ -18,8 +16,10 @@ class MqttClient:
|
|||||||
def __init__(self, config: MQTTConfig, ha_discovery_config: HaMqttDiscoveryConfig):
|
def __init__(self, config: MQTTConfig, ha_discovery_config: HaMqttDiscoveryConfig):
|
||||||
self._config = config
|
self._config = config
|
||||||
self._ha_discovery_config = ha_discovery_config
|
self._ha_discovery_config = ha_discovery_config
|
||||||
|
|
||||||
self._client = mqtt.Client()
|
self._client = mqtt.Client()
|
||||||
self._client.username_pw_set(username=self._config.username, password=self._config.password)
|
self._client.username_pw_set(username=self._config.username, password=self._config.password)
|
||||||
|
|
||||||
self._client.on_connect = self._on_connect
|
self._client.on_connect = self._on_connect
|
||||||
self._client.on_message = self._on_message
|
self._client.on_message = self._on_message
|
||||||
self._client.on_disconnect = self._on_disconnect
|
self._client.on_disconnect = self._on_disconnect
|
||||||
@ -28,18 +28,28 @@ class MqttClient:
|
|||||||
self.on_message = EventHook[OnMessageEvent]()
|
self.on_message = EventHook[OnMessageEvent]()
|
||||||
self.on_disconnect = EventHook[OnDisconnectEvent]()
|
self.on_disconnect = EventHook[OnDisconnectEvent]()
|
||||||
|
|
||||||
def connect(self):
|
def connect(self) -> None:
|
||||||
host = self._config.host
|
host = self._config.host
|
||||||
port = self._config.port
|
port = self._config.port
|
||||||
|
|
||||||
logger.info(f"MQTT | Connecting to {host}:{port}")
|
logger.info(f"MQTT | Connecting to {host}:{port}")
|
||||||
self._client.connect(
|
self._client.connect(
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
keepalive=self._config.keepalive
|
keepalive=self._config.keepalive
|
||||||
)
|
)
|
||||||
|
|
||||||
def go_online(self):
|
def go_online(self) -> None:
|
||||||
|
topics = [
|
||||||
|
self._ha_discovery_config.power_command_topic,
|
||||||
|
self._ha_discovery_config.mode_command_topic,
|
||||||
|
self._ha_discovery_config.temperature_command_topic,
|
||||||
|
self._ha_discovery_config.fan_mode_command_topic
|
||||||
|
]
|
||||||
|
|
||||||
|
for topic in topics:
|
||||||
|
self._client.subscribe(topic=topic, qos=0)
|
||||||
|
|
||||||
self._client.will_set(
|
self._client.will_set(
|
||||||
topic=self._ha_discovery_config.availability_topic,
|
topic=self._ha_discovery_config.availability_topic,
|
||||||
payload=self._ha_discovery_config.payload_not_available,
|
payload=self._ha_discovery_config.payload_not_available,
|
||||||
@ -56,44 +66,21 @@ class MqttClient:
|
|||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def go_offline(self):
|
def go_offline(self) -> None:
|
||||||
self._client.publish(
|
self._client.publish(
|
||||||
topic=self._ha_discovery_config.availability_topic,
|
topic=self._ha_discovery_config.availability_topic,
|
||||||
payload=self._ha_discovery_config.payload_not_available,
|
payload=self._ha_discovery_config.payload_not_available,
|
||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def subscribe(self, topics: List[str], qos=0):
|
def loop_forever(self, timeout=1.0, max_packets=1, retry_first_connection=False) -> None:
|
||||||
for topic in topics:
|
logger.info("MQTT | Starting loop")
|
||||||
self._client.subscribe(topic, qos=qos)
|
|
||||||
|
|
||||||
def loop_forever(self, timeout=1.0, max_packets=1, retry_first_connection=False):
|
|
||||||
self._client.loop_forever(timeout=timeout, max_packets=max_packets,
|
self._client.loop_forever(timeout=timeout, max_packets=max_packets,
|
||||||
retry_first_connection=retry_first_connection)
|
retry_first_connection=retry_first_connection)
|
||||||
|
logger.info("MQTT | Loop has ended")
|
||||||
|
|
||||||
def _on_connect(self, client: mqtt.Client, userdata, flags, rc: int):
|
def publish_mode(self, mode: MqttMode) -> None:
|
||||||
if rc == 0:
|
logger.debug(f"MQTT | Publishing mode {mode} to HA")
|
||||||
logger.info("MQTT | Connected to the Server")
|
|
||||||
self.on_connected.fire(OnConnectEvent(flags=flags))
|
|
||||||
else:
|
|
||||||
logger.error("MQTT | Could not connect to Server")
|
|
||||||
|
|
||||||
def _on_message(self, client: mqtt.Client, userdata, msg):
|
|
||||||
logger.debug(
|
|
||||||
f"MQTT | Received message | Topic: {msg.topic} | qos: {msg.qos} | retain: {msg.retain} | Payload: {msg.payload}")
|
|
||||||
self.on_message.fire(OnMessageEvent(msg=MqttMessage(
|
|
||||||
topic=msg.topic,
|
|
||||||
payload=msg.payload,
|
|
||||||
qos=msg.qos,
|
|
||||||
retain=msg.retain
|
|
||||||
)))
|
|
||||||
|
|
||||||
def _on_disconnect(self, client: mqtt.Client, userdata, flags, rc: int):
|
|
||||||
logger.debug(f"MQTT | Client has disconnected")
|
|
||||||
self.on_disconnect.fire(OnDisconnectEvent(rc=rc))
|
|
||||||
|
|
||||||
def publish_mode(self, mode: MqttMode):
|
|
||||||
logger.info(f"Publishing mode {mode} to HA")
|
|
||||||
self._client.publish(
|
self._client.publish(
|
||||||
topic=self._ha_discovery_config.mode_state_topic,
|
topic=self._ha_discovery_config.mode_state_topic,
|
||||||
payload=mode.value,
|
payload=mode.value,
|
||||||
@ -101,7 +88,8 @@ class MqttClient:
|
|||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def publish_temperature_state(self, set_temperature: float):
|
def publish_temperature_state(self, set_temperature: float) -> None:
|
||||||
|
logger.debug(f"MQTT | Publishing set temperature {set_temperature} to HA")
|
||||||
self._client.publish(
|
self._client.publish(
|
||||||
topic=self._ha_discovery_config.temperature_state_topic,
|
topic=self._ha_discovery_config.temperature_state_topic,
|
||||||
payload=str(set_temperature),
|
payload=str(set_temperature),
|
||||||
@ -109,7 +97,8 @@ class MqttClient:
|
|||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def publish_current_temperature_state(self, current_temperature: float):
|
def publish_current_temperature_state(self, current_temperature: float) -> None:
|
||||||
|
logger.debug(f"MQTT | Publishing current temperature {current_temperature} to HA")
|
||||||
self._client.publish(
|
self._client.publish(
|
||||||
topic=self._ha_discovery_config.current_temperature_topic,
|
topic=self._ha_discovery_config.current_temperature_topic,
|
||||||
payload=str(current_temperature),
|
payload=str(current_temperature),
|
||||||
@ -117,10 +106,38 @@ class MqttClient:
|
|||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
def publish_fan_speed(self, fan_speed: MqttFanSpeed):
|
def publish_fan_speed(self, fan_speed: MqttFanSpeed) -> None:
|
||||||
|
logger.debug(f"MQTT | Publishing fan speed {fan_speed} to HA")
|
||||||
self._client.publish(
|
self._client.publish(
|
||||||
topic=self._ha_discovery_config.fan_mode_state_topic,
|
topic=self._ha_discovery_config.fan_mode_state_topic,
|
||||||
payload=fan_speed.value,
|
payload=fan_speed.value,
|
||||||
qos=0,
|
qos=0,
|
||||||
retain=True
|
retain=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def exit(self) -> None:
|
||||||
|
logger.info('MQTT | Stopping loop.')
|
||||||
|
self._client.loop_stop(True)
|
||||||
|
logger.info('MQTT | Disconnecting.')
|
||||||
|
self._client.disconnect()
|
||||||
|
|
||||||
|
def _on_connect(self, client: mqtt.Client, userdata, flags, rc: int) -> None:
|
||||||
|
if rc == 0:
|
||||||
|
logger.info("MQTT | Connected!")
|
||||||
|
self.on_connected.fire(OnConnectEvent(flags=flags))
|
||||||
|
else:
|
||||||
|
logger.error("MQTT | Could not connect to Server")
|
||||||
|
|
||||||
|
def _on_message(self, client: mqtt.Client, userdata, msg) -> None:
|
||||||
|
logger.debug(
|
||||||
|
f"MQTT | Received message | Topic: {msg.topic} | qos: {msg.qos} | retain: {msg.retain} | Payload: {msg.payload}")
|
||||||
|
self.on_message.fire(OnMessageEvent(msg=MqttMessage(
|
||||||
|
topic=msg.topic,
|
||||||
|
payload=msg.payload,
|
||||||
|
qos=msg.qos,
|
||||||
|
retain=msg.retain
|
||||||
|
)))
|
||||||
|
|
||||||
|
def _on_disconnect(self, client: mqtt.Client, userdata, rc: int) -> None:
|
||||||
|
logger.info(f"MQTT | Disconnected with result code {rc}")
|
||||||
|
self.on_disconnect.fire(OnDisconnectEvent(rc=rc))
|
@ -1,3 +1,4 @@
|
|||||||
|
import signal
|
||||||
import sys
|
import sys
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
@ -12,8 +13,6 @@ from models.mode_enums import Mode
|
|||||||
from models.mqtt_fan_speed_enums import MqttFanSpeed
|
from models.mqtt_fan_speed_enums import MqttFanSpeed
|
||||||
from models.mqtt_mode_enums import MqttMode
|
from models.mqtt_mode_enums import MqttMode
|
||||||
from models.mqtt_topcis import MqttTopics
|
from models.mqtt_topcis import MqttTopics
|
||||||
from models.on_connect_event import OnConnectEvent
|
|
||||||
from models.on_disconnect_event import OnDisconnectEvent
|
|
||||||
from models.on_message_event import OnMessageEvent
|
from models.on_message_event import OnMessageEvent
|
||||||
from models.state import State
|
from models.state import State
|
||||||
from mqtt_client import MqttClient
|
from mqtt_client import MqttClient
|
||||||
@ -22,7 +21,7 @@ from state_service import StateService
|
|||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
logger.info("Starting server")
|
logger.info("Server | Setup server")
|
||||||
self._config = load_config()
|
self._config = load_config()
|
||||||
self._version = load_version()
|
self._version = load_version()
|
||||||
self._topics = self._get_mqtt_topics()
|
self._topics = self._get_mqtt_topics()
|
||||||
@ -35,20 +34,30 @@ class Server:
|
|||||||
)
|
)
|
||||||
self._modbus_client = ModbusClient(config=self._config.modbus, state_service=self._state_service)
|
self._modbus_client = ModbusClient(config=self._config.modbus, state_service=self._state_service)
|
||||||
|
|
||||||
self._mqtt_client.on_connected.add_handler(self._on_mqtt_connected)
|
|
||||||
self._mqtt_client.on_message.add_handler(self._on_mqtt_message)
|
self._mqtt_client.on_message.add_handler(self._on_mqtt_message)
|
||||||
self._mqtt_client.on_disconnect.add_handler(self._on_mqtt_disconnect)
|
|
||||||
self._mqtt_client.connect()
|
|
||||||
self._mqtt_client.go_online()
|
|
||||||
self._make_mqtt_subscriptions()
|
|
||||||
|
|
||||||
self._state_service.state_changed.add_handler(self._on_state_changed)
|
self._state_service.state_changed.add_handler(self._on_state_changed)
|
||||||
|
|
||||||
self._modbus_client.start_polling()
|
def start(self) -> None:
|
||||||
|
logger.info("Server | Startup server")
|
||||||
|
try:
|
||||||
|
self._modbus_client.connect()
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
self.stop()
|
||||||
|
self._mqtt_client.connect()
|
||||||
|
self._mqtt_client.go_online()
|
||||||
self._mqtt_client.loop_forever()
|
self._mqtt_client.loop_forever()
|
||||||
|
|
||||||
def _on_state_changed(self, changes: State):
|
def stop(self, signum=None, frame=None) -> None:
|
||||||
|
logger.info(f"Server | Shutting down")
|
||||||
|
self._mqtt_client.exit()
|
||||||
|
self._modbus_client.disconnect()
|
||||||
|
|
||||||
|
logger.info(f"Server | Done. Bye!")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
def _on_state_changed(self, changes: State) -> None:
|
||||||
if changes.running is False:
|
if changes.running is False:
|
||||||
self._mqtt_client.publish_mode(MqttMode.OFF)
|
self._mqtt_client.publish_mode(MqttMode.OFF)
|
||||||
if changes.running is True:
|
if changes.running is True:
|
||||||
@ -68,7 +77,7 @@ class Server:
|
|||||||
if changes.fan_speed:
|
if changes.fan_speed:
|
||||||
self._publish_fan_speed_state(changes.fan_speed)
|
self._publish_fan_speed_state(changes.fan_speed)
|
||||||
|
|
||||||
def _publish_mode_state(self, mode):
|
def _publish_mode_state(self, mode) -> None:
|
||||||
if mode == Mode.AUTO:
|
if mode == Mode.AUTO:
|
||||||
self._mqtt_client.publish_mode(MqttMode.AUTO)
|
self._mqtt_client.publish_mode(MqttMode.AUTO)
|
||||||
if mode == Mode.COOL:
|
if mode == Mode.COOL:
|
||||||
@ -80,7 +89,7 @@ class Server:
|
|||||||
if mode == Mode.HEATING:
|
if mode == Mode.HEATING:
|
||||||
self._mqtt_client.publish_mode(MqttMode.HEAT)
|
self._mqtt_client.publish_mode(MqttMode.HEAT)
|
||||||
|
|
||||||
def _publish_fan_speed_state(self, fan_speed: FanSpeed):
|
def _publish_fan_speed_state(self, fan_speed: FanSpeed) -> None:
|
||||||
if fan_speed == FanSpeed.AUTO:
|
if fan_speed == FanSpeed.AUTO:
|
||||||
self._mqtt_client.publish_fan_speed(MqttFanSpeed.AUTO)
|
self._mqtt_client.publish_fan_speed(MqttFanSpeed.AUTO)
|
||||||
if fan_speed == FanSpeed.LOW:
|
if fan_speed == FanSpeed.LOW:
|
||||||
@ -92,10 +101,7 @@ class Server:
|
|||||||
if fan_speed == FanSpeed.UNKNOWN:
|
if fan_speed == FanSpeed.UNKNOWN:
|
||||||
self._mqtt_client.publish_fan_speed(MqttFanSpeed.UNKNOWN)
|
self._mqtt_client.publish_fan_speed(MqttFanSpeed.UNKNOWN)
|
||||||
|
|
||||||
def _on_mqtt_connected(self, event: OnConnectEvent):
|
def _on_mqtt_message(self, event: OnMessageEvent) -> None:
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_mqtt_message(self, event: OnMessageEvent):
|
|
||||||
topic = event.msg.topic
|
topic = event.msg.topic
|
||||||
payload = event.msg.payload
|
payload = event.msg.payload
|
||||||
|
|
||||||
@ -116,6 +122,7 @@ class Server:
|
|||||||
command = MqttMode.from_value(str(payload))
|
command = MqttMode.from_value(str(payload))
|
||||||
if command == MqttMode.OFF:
|
if command == MqttMode.OFF:
|
||||||
self._modbus_client.write_operate(value=False)
|
self._modbus_client.write_operate(value=False)
|
||||||
|
self._mqtt_client.publish_mode(mode=command)
|
||||||
else:
|
else:
|
||||||
self._modbus_client.write_operate(value=True)
|
self._modbus_client.write_operate(value=True)
|
||||||
self._mqtt_client.publish_mode(mode=command)
|
self._mqtt_client.publish_mode(mode=command)
|
||||||
@ -138,7 +145,7 @@ class Server:
|
|||||||
self._modbus_client.set_fan_speed(value=FanSpeed.UNKNOWN)
|
self._modbus_client.set_fan_speed(value=FanSpeed.UNKNOWN)
|
||||||
self._mqtt_client.publish_fan_speed(fan_speed=command)
|
self._mqtt_client.publish_fan_speed(fan_speed=command)
|
||||||
|
|
||||||
def _modbus_set_mode(self, command):
|
def _modbus_set_mode(self, command) -> None:
|
||||||
if command == MqttMode.AUTO:
|
if command == MqttMode.AUTO:
|
||||||
self._modbus_client.set_mode(value=Mode.AUTO)
|
self._modbus_client.set_mode(value=Mode.AUTO)
|
||||||
elif command == MqttMode.COOL:
|
elif command == MqttMode.COOL:
|
||||||
@ -150,12 +157,7 @@ class Server:
|
|||||||
elif command == MqttMode.FAN_ONLY:
|
elif command == MqttMode.FAN_ONLY:
|
||||||
self._modbus_client.set_mode(value=Mode.FAN_ONLY)
|
self._modbus_client.set_mode(value=Mode.FAN_ONLY)
|
||||||
|
|
||||||
def _on_mqtt_disconnect(self, event: OnDisconnectEvent):
|
def _get_mqtt_topics(self) -> MqttTopics:
|
||||||
logger.info(f"Disconnected with result code {event.rc}")
|
|
||||||
logger.info(f"Exiting...")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def _get_mqtt_topics(self):
|
|
||||||
unique_id = self._config.id
|
unique_id = self._config.id
|
||||||
return MqttTopics(
|
return MqttTopics(
|
||||||
availability=f"{unique_id}/availability",
|
availability=f"{unique_id}/availability",
|
||||||
@ -169,15 +171,6 @@ class Server:
|
|||||||
current_temperature=f"{unique_id}/current-temperature"
|
current_temperature=f"{unique_id}/current-temperature"
|
||||||
)
|
)
|
||||||
|
|
||||||
def _make_mqtt_subscriptions(self):
|
|
||||||
topics = self._topics
|
|
||||||
self._mqtt_client.subscribe(topics=[
|
|
||||||
topics.power_command,
|
|
||||||
topics.mode_command,
|
|
||||||
topics.temperature_command,
|
|
||||||
topics.fan_mode_command
|
|
||||||
])
|
|
||||||
|
|
||||||
def _get_ha_discovery_config(self) -> HaMqttDiscoveryConfig:
|
def _get_ha_discovery_config(self) -> HaMqttDiscoveryConfig:
|
||||||
topics = self._topics
|
topics = self._topics
|
||||||
config = self._config
|
config = self._config
|
||||||
@ -196,11 +189,23 @@ class Server:
|
|||||||
device=HaDeviceConfig(
|
device=HaDeviceConfig(
|
||||||
identifiers=[f"lg-{config.id}"],
|
identifiers=[f"lg-{config.id}"],
|
||||||
model=config.model,
|
model=config.model,
|
||||||
name=f"LG {config.name}",
|
name=f"LG",
|
||||||
sw_version=self._version
|
sw_version=self._version
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
logger.configure(handlers=[{"sink": sys.stdout, "format": "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
|
||||||
|
"<level>{level: <8}</level> | "
|
||||||
|
"<level>{message}</level>"}])
|
||||||
|
|
||||||
logger.info("Welcome to lg-airco-modbus-mqtt!")
|
logger.info("Welcome to lg-airco-modbus-mqtt!")
|
||||||
server = Server()
|
server = Server()
|
||||||
|
try:
|
||||||
|
server.start()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
logger.warning("Server | Interrupt received, stopping server...")
|
||||||
|
server.stop()
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, server.stop)
|
||||||
|
signal.signal(signal.SIGTERM, server.stop)
|
@ -31,7 +31,7 @@ class StateService:
|
|||||||
self._process_changes(delta_state)
|
self._process_changes(delta_state)
|
||||||
|
|
||||||
def _process_changes(self, delta_state: State):
|
def _process_changes(self, delta_state: State):
|
||||||
logger.debug(f"Changed state: {delta_state}")
|
logger.debug(f"State | Changed state: {delta_state}")
|
||||||
self.state_changed.fire(delta_state)
|
self.state_changed.fire(delta_state)
|
||||||
|
|
||||||
def get_state(self) -> State:
|
def get_state(self) -> State:
|
Loading…
Reference in New Issue
Block a user