1111# Author: Michael Oberdorf
1212# Date: 2025-04-11
1313# Last modified by: Michael Oberdorf
14- # Last modified at: 2026-01-11
14+ # Last modified at: 2026-01-18
1515###############################################################################
1616"""
1717
3030from lib .weather_codes import WeatherCodes
3131from retry_requests import retry # seeAlso: https://pypi.org/project/retry-requests/
3232
33- __version__ = "1.3.4 "
33+ __version__ = "1.4.0 "
3434__script_path__ = os .path .dirname (__file__ )
3535__config_path__ = os .path .join (os .path .dirname (__script_path__ ), "etc" )
3636__local_tz__ = pytz .timezone ("UTC" )
@@ -134,7 +134,7 @@ def load_config_file() -> dict:
134134 return config
135135
136136
137- def initialize_mqtt_client () -> mqtt .Client :
137+ def __initialize_mqtt_client () -> mqtt .Client :
138138 """
139139 Initialize the MQTT client with the given configuration from environment.
140140
@@ -174,7 +174,7 @@ def initialize_mqtt_client() -> mqtt.Client:
174174 client .tls_set (
175175 ca_certs = os .environ .get ("REQUESTS_CA_BUNDLE" ),
176176 cert_reqs = ssl .CERT_NONE ,
177- tls_version = ssl .PROTOCOL_TLS ,
177+ tls_version = ssl .PROTOCOL_TLSv1_2 ,
178178 ciphers = None ,
179179 )
180180 client .tls_insecure_set (True )
@@ -183,7 +183,7 @@ def initialize_mqtt_client() -> mqtt.Client:
183183 client .tls_set (
184184 ca_certs = os .environ .get ("REQUESTS_CA_BUNDLE" ),
185185 cert_reqs = ssl .CERT_REQUIRED ,
186- tls_version = ssl .PROTOCOL_TLS ,
186+ tls_version = ssl .PROTOCOL_TLSv1_2 ,
187187 ciphers = None ,
188188 )
189189 client .tls_insecure_set (False )
@@ -338,6 +338,58 @@ def parse_daily_weather(data: any, fields: list = []) -> dict:
338338 return parsed_data
339339
340340
341+ def publish_weather_data (topic : str , payload : dict ) -> None :
342+ """
343+ Publish the weather data to the MQTT broker.
344+
345+ :param topic str: The MQTT topic to publish the weather data to.
346+ :param payload dict: The weather data to publish.
347+ :raise ssl.SSLCertVerificationError: If there is an SSL certificate verification error.
348+ :raise Exception: If the weather data cannot be published.
349+ """
350+ log .debug (f"Publish weather data to MQTT topic { topic } with payload: { json .dumps (payload )} " )
351+
352+ # Initialize MQTT client
353+ client = __initialize_mqtt_client ()
354+ log .debug ("MQTT client initialized" )
355+
356+ log .debug ("Connecting to MQTT server {}:{}" .format (os .environ .get ("MQTT_SERVER" ), os .environ .get ("MQTT_PORT" )))
357+ try :
358+ client .connect (os .environ .get ("MQTT_SERVER" ), int (os .environ .get ("MQTT_PORT" )), 60 )
359+ except ssl .SSLCertVerificationError as e :
360+ log .error ("SSL certificate verification error: {}" .format (e ))
361+ sys .exit (1 )
362+ log .debug ("Connected to MQTT server" )
363+
364+ mqtt_retain = False
365+ if os .environ .get ("MQTT_RETAIN" , "false" ).lower () == "true" :
366+ mqtt_retain = True
367+ mqtt_qos = int (os .environ .get ("MQTT_QOS" , "0" ))
368+ if mqtt_qos not in [0 , 1 , 2 ]:
369+ log .warning ("Invalid MQTT QoS level: {}. Using QoS 0." .format (mqtt_qos ))
370+ mqtt_qos = 0
371+ log .debug (
372+ "Publishing weather data to MQTT topic: {}, using retain: {}, qos: {}" .format (
373+ os .environ .get ("MQTT_TOPIC" ), mqtt_retain , mqtt_qos
374+ )
375+ )
376+
377+ result , mid = client .publish (
378+ topic = topic ,
379+ payload = json .dumps (payload , ensure_ascii = False ),
380+ qos = mqtt_qos ,
381+ retain = mqtt_retain ,
382+ )
383+
384+ if result != mqtt .MQTT_ERR_SUCCESS :
385+ raise Exception (f"Failed to publish weather data to MQTT topic { topic } . Error code: { result } " )
386+
387+ log .debug (f"Published weather data to MQTT topic { topic } with message ID { mid } " )
388+
389+ client .disconnect ()
390+ log .debug ("Disconnected from MQTT server" )
391+
392+
341393"""
342394###############################################################################
343395# M A I N
@@ -381,28 +433,11 @@ def parse_daily_weather(data: any, fields: list = []) -> dict:
381433
382434 log .debug ("Payload: {}" .format (json .dumps (weather_result , ensure_ascii = False )))
383435
384- # initialize MQTT client and connect to broker
385- client = initialize_mqtt_client ()
386- log .debug ("MQTT client initialized" )
387- log .debug ("Connecting to MQTT server {}:{}" .format (os .environ .get ("MQTT_SERVER" ), os .environ .get ("MQTT_PORT" )))
388- try :
389- client .connect (os .environ .get ("MQTT_SERVER" ), int (os .environ .get ("MQTT_PORT" )), 60 )
390- except ssl .SSLCertVerificationError as e :
391- log .error ("SSL certificate verification error: {}" .format (e ))
392- sys .exit (1 )
393-
394- retain = False
395- if os .environ .get ("MQTT_RETAIN" , "false" ).lower () == "true" :
396- retain = True
397- log .debug (
398- "Publishing weather data to MQTT topic: {}, using retain: {}" .format (os .environ .get ("MQTT_TOPIC" ), retain )
399- )
400- client .publish (
401- topic = os .environ .get ("MQTT_TOPIC" ), payload = json .dumps (weather_result , ensure_ascii = False ), qos = 0 , retain = retain
436+ # Publish weather data
437+ publish_weather_data (
438+ topic = os .environ .get ("MQTT_TOPIC" ),
439+ payload = weather_result ,
402440 )
403441
404- client .disconnect ()
405- log .debug ("Disconnected from MQTT server" )
406-
407442 log .info (f"Stop weather2mqtt version { __version__ } " )
408443 sys .exit (0 )
0 commit comments