import paho.mqtt.client as mqtt
import caspia.reactive
[docs]class MeadowError(Exception):
""" Represents an error within the Meadow protocol """
code = -1
message = 'unknown error'
extra = {}
_error_classes = dict()
def __init_subclass__(cls, code, message, **kwargs):
super().__init_subclass__(**kwargs)
cls.code = code
cls.message = message
cls._error_classes[code] = cls
def __init__(self, message=None, code=None, **extra):
super().__init__()
if code is not None:
self.code = code
if message is not None:
self.message = message
if extra:
self.extra = extra
def __repr__(self):
components = dict(code=self.code, message=self.message)
components.update(self.extra)
components_str = ', '.join(f'{k}={v}' for k, v in components.items())
return f'{type(self).__name__}({components_str})'
def __str__(self):
return repr(self)
[docs] @staticmethod
def from_dict(data):
code, message = data.pop('code', None), data.pop('message', None)
cls = MeadowError._error_classes.get(code, MeadowError)
return cls(code=code, message=message, **data)
[docs] @staticmethod
def from_exception(exc):
if isinstance(exc, MeadowError):
return exc
else:
return MeadowError(message=repr(exc))
[docs] def to_dict(self):
data = dict(**self.extra)
data['code'] = self.code
data['message'] = self.message
return data
[docs]class NotSupportedError(MeadowError, code=1, message='not supported'):
pass
[docs]class InvalidValueError(MeadowError, code=2, message='invalid value'):
pass
[docs]class NotReadyError(MeadowError, caspia.reactive.errors.ValueNotReady, code=3, message='not ready'):
pass
[docs]class CommunicationError(MeadowError, code=4, message='communication error'):
[docs] @staticmethod
def from_mqtt(mqtt_err_no):
return CommunicationError(message=mqtt.error_string(mqtt_err_no))
[docs]class NotAvailableError(MeadowError, code=5, message='resource not available'):
pass
[docs]class SensorFailureError(MeadowError, code=101, message='sensor failure'):
pass