Skip to content

Commit

Permalink
powermon update mqtt refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jblance committed Jan 10, 2023
1 parent ee09361 commit 670bc0e
Show file tree
Hide file tree
Showing 26 changed files with 906 additions and 493 deletions.
3 changes: 2 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ t: tests/*.py

pypi:
rm -rf dist/*
python3 -m build
#python3 -m build
poetry build
ls -l dist/

pypi-upload:
Expand Down
22 changes: 15 additions & 7 deletions mppsolar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from argparse import ArgumentParser

from .helpers import get_device_class
from .libs.mqttbroker import MqttBroker
from .libs.mqttbrokerc import MqttBroker
from .outputs import get_outputs, list_outputs
from .protocols import list_protocols
from .version import __version__ # noqa: F401
Expand Down Expand Up @@ -45,7 +45,7 @@ def main():
type=str,
const="help",
help="Specifies the device command and response protocol, (default: JK04)",
default="JK04"
default="JK04",
)
else:
parser.add_argument(
Expand All @@ -55,7 +55,7 @@ def main():
type=str,
const="help",
help="Specifies the device command and response protocol, (default: PI30)",
default="PI30"
default="PI30",
)
parser.add_argument(
"-T",
Expand Down Expand Up @@ -226,11 +226,19 @@ def main():
op.output(data=list_protocols())
exit()

# mqttbroker:
# name: null
# port: 1883
# user: null
# pass: null

mqtt_broker = MqttBroker(
name=args.mqttbroker,
port=args.mqttport,
username=args.mqttuser,
password=args.mqttpass,
config={
"name": args.mqttbroker,
"port": args.mqttport,
"user": args.mqttuser,
"pass": args.mqttpass,
}
)
mqtt_broker.set(
"results_topic", (args.mqtttopic if args.mqtttopic is not None else prog_name)
Expand Down
5 changes: 2 additions & 3 deletions mppsolar/devices/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,8 @@ def run_command(self, command) -> dict:
]
}
# dict is returned on exception

if isinstance(raw_response, dict):
return raw_response
# if isinstance(raw_response, dict):
# return raw_response

# Decode response
decoded_response = self._protocol.decode(raw_response, command)
Expand Down
47 changes: 26 additions & 21 deletions mppsolar/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ def key_wanted(key, filter=None, excl_filter=None):
return False


def get_value(_list, _index):
"""
get the value from _list or return None if _index is out of bounds
"""
# print(_list, len(_list))
if _index >= len(_list):
return None
return _list[_index]


def get_resp_defn(key, defns):
"""
look for a definition for the supplied key
Expand All @@ -52,27 +62,6 @@ def get_resp_defn(key, defns):
return [key, key, "", ""]


# def get_outputs(output_list):
# """
# Take a comma separated list of output names
# attempt to find and instantiate the corresponding module
# return array of modules
# """
# ops = []
# outputs = output_list.split(",")
# for output in outputs:
# log.info(f"attempting to create output processor: {output}")
# try:
# output_module = importlib.import_module("mppsolar.outputs." + output, ".")
# output_class = getattr(output_module, output)
# ops.append(output_class())
# except ModuleNotFoundError:
# # perhaps raise a Powermon exception here??
# # maybe warn and keep going, only error if no outputs found?
# log.critical(f"No module found for output processor {output}")
# return ops


def get_device_class(device_type=None):
"""
Take a device type string
Expand All @@ -90,3 +79,19 @@ def get_device_class(device_type=None):
return None
device_class = getattr(device_module, device_type)
return device_class


def getMaxLen(d):
_maxLen = 0
for i in d:
if type(i) == list:
i = i[0]
if len(i) > _maxLen:
_maxLen = len(i)
return _maxLen


def pad(text, length):
if len(text) > length:
return text
return text.ljust(length, " ")
127 changes: 0 additions & 127 deletions mppsolar/libs/mqttbroker.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ class MqttBroker:
mqttc: mqtt_client.Client = mqtt_client.Client()
_isConnected: bool = False

# def __init__(self,):
# self.mqtt_broker = args.mqttbroker
# self.mqtt_port = args.mqttport
# # mqtt_topic = args.mqtttopic
# # if mqtt_topic is None:
# # mqtt_topic = prog_name
# self.mqtt_user = args.mqttuser
# self.mqtt_pass = args.mqttpass

def on_connect(self, client, userdata, flags, rc):
# 0: Connection successful
# 1: Connection refused - incorrect protocol version
Expand Down Expand Up @@ -97,124 +88,6 @@ def subscribe(self, topic, callback):
self.mqttc.subscribe(topic, qos=0)


class MqttBrokerC:
# name: str
# port: int = 1883
# username: Optional[str] = None
# password: Optional[str] = None
# results_topic: Optional[str] = None
# mqttc: mqtt_client.Client = mqtt_client.Client()
# _isConnected: bool = False
def __str__(self):
return (
f"MqttBrokerC name: {self.name}, port: {self.port}, user: {self.username}"
)

def __init__(self, *args, **kwargs):

# mqttbroker:
# name: localhost
# port: 1883
# user: null
# pass: null
# adhoc_commands:
# topic: test/command_topic

config = kwargs["config"]
if config is None:
config = {}
self.name = config.get("name")
self.port = config.get("port", 1883)
self.username = config.get("user")
self.password = config.get("pass")
self.mqttc = mqtt_client.Client()
self._isConnected = False

def on_connect(self, client, userdata, flags, rc):
# 0: Connection successful
# 1: Connection refused - incorrect protocol version
# 2: Connection refused - invalid client identifier
# 3: Connection refused - server unavailable
# 4: Connection refused - bad username or password
# 5: Connection refused - not authorised
# 6-255: Currently unused.
connection_result = [
"Connection successful",
"Connection refused - incorrect protocol version",
"Connection refused - invalid client identifier",
"Connection refused - server unavailable",
"Connection refused - bad username or password",
"Connection refused - not authorised",
]
log.debug(
f"MqttBroker connection returned result: {rc} {connection_result[rc]}"
)
if rc == 0:
self._isConnected = True
return
self._isConnected = False

def on_disconnect(self, client, userdata, rc):
print(f"Disconnection returned result: {rc}")
self._isConnected = False

def connect(self):
self.mqttc.on_connect = self.on_connect
self.mqttc.on_disconnect = self.on_disconnect
# if a name is supplied, connect
if self.name:
log.debug(f"Connecting to {self.name} on port {self.port}")
try:
self.mqttc.connect(self.name, self.port, keepalive=60)
except ConnectionRefusedError as exc:
log.warn(f"{self.name} refused connection '{exc}'")
else:
log.debug(f"Did not connect as no broker name '{self.name}'")

def start(self):
if self._isConnected:
self.mqttc.loop_start()

def stop(self):
if self.name:
self.mqttc.loop_stop()
if self._isConnected:
self.mqttc.disconnect

def set(self, variable, value):
setattr(self, variable, value)

def update(self, variable, value):
# only override if value is not None
if value is None:
return
setattr(self, variable, value)

def subscribe(self, topic, callback):
# subscribe to mqtt topic
if not self.name:
return
# check if connected, connect if not
if not self._isConnected:
log.debug("Not connected, connecting")
self.connect()
# Register callback
self.mqttc.on_message = callback
if self._isConnected:
# Subscribe to command topic
log.debug(f"Subscribing to topic {topic}")
self.mqttc.subscribe(topic, qos=0)
else:
log.warn(f"Did not subscribe to topic {topic} as not connected to broker")

def setAdhocCommands(self, adhoc_commands={}, callback=None):
# sub to command topic if defined
adhoc_commands_topic = adhoc_commands.get("topic")
if adhoc_commands_topic is not None:
log.info(f"Setting adhoc commands topic to {adhoc_commands_topic}")
self.subscribe(adhoc_commands_topic, callback)


if __name__ == "__main__":
broker = MqttBroker("brokername")
print(broker)
Expand Down
Loading

0 comments on commit 670bc0e

Please sign in to comment.