Testing Docker file

This commit is contained in:
Simon Milvert 2023-02-27 21:47:19 +01:00
parent f1e62f5344
commit 7f66e99cfa
9 changed files with 97 additions and 75 deletions

View File

@ -2,10 +2,15 @@
FROM python:3.10-slim-buster
RUN mkdir /app
COPY . /app
COPY pyproject.toml /app
WORKDIR /app
ENV PYTHONPATH=${PYTHONPATH}:${PWD}
RUN pip3 install poetry
RUN poetry config virtualenvs.create false
RUN poetry install --only main
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .

View File

@ -5,15 +5,12 @@ services:
container_name: huawei-solar
restart: unless-stopped
image: huawei-solar-rtu:latest
user: root
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
environment:
- INVERTER_PORT=/dev/ttyUSB0
- MQTT_HOST=192.168.43.102
- BROKER_PORT=1883
- USE_CREDENTIALS=NO
- USER_NAME=none
- PASSWORD=none
- INVERTER_HOST=192.168.200.100
- MQTT_HOST=192.168.1.100
- USE_CREDENTIALS=YES
- USER_NAME=simon
- PASSWORD=bajsa123
- LOGLEVEL=DEBUG
- MQTT_TOPIC=raspberryTopic
- DATA_MODE=INVERTER # INVERTER or OFFLINE

View File

@ -8,6 +8,7 @@ authors = ["Simon Milvert <simon@milvert.com>"]
python = "^3.9"
huawei-solar = "^2.2.4"
paho-mqtt = "^1.6.1"
python-dotenv = "^1.0.0"
[tool.poetry.dev-dependencies]
pytest = "^7.2.1"

View File

@ -0,0 +1,14 @@
import logging
import os
from dotenv import load_dotenv
load_dotenv()
FORMAT = (
"%(asctime)-15s %(threadName)-15s "
"%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
)
LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper()
logging.basicConfig(level=LOGLEVEL, format=FORMAT)

View File

@ -1,8 +1,11 @@
import logging
from src.data import InverterData
from src.log import log_info
LOGGER = logging.getLogger(__name__)
async def get_data(client, register, slave_id):
result = await client.get(register, slave_id)
log_info(f"{register}: {result.value}")
LOGGER.debug(f"{register}: {result.value}")
return InverterData(value=result.value, unit=result.unit, name=register)

View File

@ -1,8 +1,9 @@
import logging
import random
from src.data import InverterData, ReadRegister
from src.log import log_info
LOGGER = logging.getLogger(__name__)
POSSIBLE_SAMPLE_UNITS = [
"EXAMPLE_UNIT_A",
"EXAMPLE_UNIT_B",
@ -14,7 +15,7 @@ POSSIBLE_SAMPLE_UNITS = [
async def get_dummy_data() -> InverterData:
log_info("Generate dummy data")
LOGGER.info("Generate dummy data")
value = random.randint(0, 100)
name = random.choice(ReadRegister.reg_to_read_measured)
unit = random.choice(POSSIBLE_SAMPLE_UNITS)

View File

@ -1,13 +0,0 @@
import logging
FORMAT = (
"%(asctime)-15s %(threadName)-15s "
"%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
)
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.INFO)
def log_info(message):
log.info(message)

View File

@ -1,59 +1,63 @@
import asyncio
import json
import logging
import os
import paho.mqtt.client
from huawei_solar import AsyncHuaweiSolar
from huawei_solar import register_values as rv
from src import mqtt
from src.data import InverterData, ReadRegister
from src.inverter import get_data
from src.inverter_dummy import get_dummy_data
from src.log import log_info
from src.mqtt import connect
DATA_MODE = os.getenv("DATA_MODE", "dummy")
DATA_MODE = os.getenv("DATA_MODE", "INVERTER")
MQTT_TOPIC = os.getenv("MQTT_TOPIC", "inverter")
FORCE_GET = os.getenv("FORCE_GET", False)
REQUEST_INTERVAL = 60
slave_id = os.getenv("INVERTER_ID", 1)
port = os.getenv("INVERTER_PORT", 502)
host = os.getenv("INVERTER_HOST", "10.0.2.20")
host = os.getenv("INVERTER_HOST", "192.168.200.100")
LOGGER = logging.getLogger(__name__)
REQUEST_INTERVAL = 60
async def get_inverter_client() -> (InverterData, str):
async def get_inverter_client() -> AsyncHuaweiSolar:
inverter_client = await AsyncHuaweiSolar.create(host, port, slave_id)
log_info("-- INVERTER -- Connected to Inverter")
status = await inverter_client.get(
ReadRegister.inverter_reg_status, slave_id
)
log_info(f"-- INVERTER -- Status: {status}")
return inverter_client, status
LOGGER.info("-- INVERTER -- Connected to Inverter")
return inverter_client
async def main():
inverter_client, status = await get_inverter_client()
inverter_client = await get_inverter_client()
count = 0
while True:
if status.value == rv.DEVICE_STATUS_DEFINITIONS.get(
0x0200
status = await inverter_client.get(
ReadRegister.inverter_reg_status, slave_id
)
LOGGER.info(f"-- INVERTER -- Status: {status}")
if (
status.value == rv.DEVICE_STATUS_DEFINITIONS.get(0x0200)
or FORCE_GET
): # Inverter is active, Get data
# Get measured values
LOGGER.info("-- INVERTER -- Send measured values")
for register in ReadRegister.reg_to_read_measured:
result = await get_inverter_data(
inverter_client, register, slave_id
)
result = await get_inverter_data(inverter_client, register)
send_data(
mqtt_client,
format_data_to_serialized_json(result),
f"measure/{result.name}",
)
# Get calculated values
LOGGER.info("-- INVERTER -- Send calculated values")
for register in ReadRegister.reg_to_read_calculated:
result = await get_inverter_data(
inverter_client, register, slave_id
)
result = await get_inverter_data(inverter_client, register)
send_data(
mqtt_client,
format_data_to_serialized_json(result),
@ -61,24 +65,30 @@ async def main():
)
if count == 5:
LOGGER.info("-- INVERTER -- Send status/alarm")
for register in ReadRegister.reg_to_read_status:
result = await get_inverter_data(
inverter_client, register, slave_id
)
result = await get_inverter_data(inverter_client, register)
send_data(
mqtt_client,
format_data_to_serialized_json(result),
f"status/{result.name}",
)
count = 0
else:
LOGGER.debug("-- INVERTER -- Not Active, No need to read values")
count += 1
LOGGER.info(f"Sleeping {REQUEST_INTERVAL}")
await asyncio.sleep(REQUEST_INTERVAL)
def send_data(client, storable_data, topic=""):
def send_data(
client: paho.mqtt.client, storable_data: str, topic: str = ""
) -> None:
try:
log_info(
f"Sending data\n topic: {MQTT_TOPIC + '/' + topic} \n"
LOGGER.debug(
f"Sending data\ntopic: {MQTT_TOPIC + '/' + topic} \n"
f"msg: {storable_data}"
)
client.publish(
@ -88,18 +98,18 @@ def send_data(client, storable_data, topic=""):
retain=False,
)
except Exception:
log_info(f"ERROR PUBLISHING DATA TO MQTT BROKER. \n{Exception}")
LOGGER.exception("ERROR PUBLISHING DATA TO MQTT BROKER.")
def format_data_to_serialized_json(info: InverterData) -> str:
data = {"value": info.value, "name": info.name, "unit": info.unit}
json_obj = json.dumps(data)
log_info(f"json_obj: {json_obj}, type: {type(json_obj)}")
LOGGER.debug(f"json_obj: {json_obj}, type: {type(json_obj)}")
return json_obj
async def get_inverter_data(
inverter_client: AsyncHuaweiSolar, register: str, slave_id: int
inverter_client: AsyncHuaweiSolar, register: str
) -> InverterData:
if DATA_MODE == "INVERTER":
data = await get_data(inverter_client, register, slave_id)
@ -109,16 +119,19 @@ async def get_inverter_data(
return data
log_info("| === START === |")
mqtt_client = connect()
LOGGER.info("| === START === |")
try:
mqtt_client = connect()
except TimeoutError:
LOGGER.exception("---- CANT CONNECT ----")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
asyncio.ensure_future(main())
asyncio.ensure_future(main(), loop=loop)
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
log_info("| === END === |")
LOGGER.info("| === END === |")
loop.close()

View File

@ -1,11 +1,12 @@
import logging
import os
import time
import paho.mqtt.client as mqtt
from src.log import log_info
LOGGER = logging.getLogger(__name__)
mqtt_host = os.getenv("MQTT_HOST", "10.0.0.3")
mqtt_host = os.getenv("MQTT_HOST", "mqtt")
broker_port = os.getenv("BROKER_PORT", "1883")
have_credentials = os.getenv("USE_CREDENTIALS", "NO")
user_name = os.getenv("USER_NAME", "")
@ -15,9 +16,9 @@ password = os.getenv("PASSWORD", "")
def on_connect(client, userdata, flags, rc):
if rc == 0:
client.connected_flag = True
log_info("MQTT OK!")
LOGGER.info("MQTT OK!")
else:
log_info(f"MQTT FAILURE. ERROR CODE: {rc}")
LOGGER.error(f"MQTT FAILURE. ERROR CODE: {rc}")
def setup_mqtt():
@ -25,15 +26,15 @@ def setup_mqtt():
mqtt_client = mqtt.Client()
mqtt_client.on_connect = on_connect
mqtt_client.loop_start()
log_info("Connecting to MQTT broker: " + mqtt_host)
log_info("Port: " + broker_port)
if have_credentials == "YES":
LOGGER.info("Connecting to MQTT broker: " + mqtt_host)
LOGGER.info("Port: " + broker_port)
if have_credentials.upper() == "YES":
mqtt_client.username_pw_set(username=user_name, password=password)
mqtt_client.connect(mqtt_host, int(broker_port), 60)
while not mqtt_client.connected_flag:
log_info("...")
LOGGER.info("...")
time.sleep(1)
log_info("START MODBUS...")
LOGGER.info("CONNECTED")
return mqtt_client