# Path: mysensors/const_14.py
# AUTO_CHANGE_OVER = "AutoChangeOver"
# 
# COOL_ON = "CoolOn"
# 
# FORECASTS = (STABLE, SUNNY, CLOUDY, UNSTABLE, THUNDERSTORM, UNKNOWN)
# 
# HEAT_ON = "HeatOn"
# 
# LOGICAL_ONE = "1"
# 
# LOGICAL_ZERO = "0"
# 
# MAX_NODE_ID = 254
# 
# OFF = "Off"
# 
# VALID_INTERNAL = {
#     Internal.I_BATTERY_LEVEL: vol.All(
#         percent_int,
#         vol.Coerce(str),
#         msg=f"value must be integer between {0} and {100}",
#     ),
#     Internal.I_TIME: vol.Any("", vol.All(vol.Coerce(int), vol.Coerce(str))),
#     Internal.I_VERSION: str,
#     Internal.I_ID_REQUEST: "",
#     Internal.I_ID_RESPONSE: vol.All(
#         vol.Coerce(int), vol.Range(min=1, max=MAX_NODE_ID), vol.Coerce(str)
#     ),
#     Internal.I_INCLUSION_MODE: vol.In([LOGICAL_ZERO, LOGICAL_ONE]),
#     Internal.I_CONFIG: vol.Any(
#         vol.All(vol.Coerce(int), vol.Range(min=0, max=MAX_NODE_ID)),
#         CONF_METRIC,
#         CONF_IMPERIAL,
#     ),
#     Internal.I_FIND_PARENT: "",
#     Internal.I_FIND_PARENT_RESPONSE: vol.All(
#         vol.Coerce(int), vol.Range(min=0, max=MAX_NODE_ID), vol.Coerce(str)
#     ),
#     Internal.I_LOG_MESSAGE: str,
#     Internal.I_CHILDREN: str,
#     Internal.I_SKETCH_NAME: str,
#     Internal.I_SKETCH_VERSION: str,
#     Internal.I_REBOOT: "",
#     Internal.I_GATEWAY_READY: str,
# }
# 
# VALID_STREAM = {
#     Stream.ST_FIRMWARE_CONFIG_REQUEST: str,
#     Stream.ST_FIRMWARE_CONFIG_RESPONSE: str,
#     Stream.ST_FIRMWARE_REQUEST: str,
#     Stream.ST_FIRMWARE_RESPONSE: str,
#     Stream.ST_SOUND: str,
#     Stream.ST_IMAGE: str,
# }
# 
# class BaseConst(IntEnum):
#     """MySensors message types."""
# 
#     def get_handler(self, handler_registry):
#         """Return correct message handler."""
#         return handler_registry.get(self.name)
# 
#     def set_handler(self, handler_registry, function):
#         """Set message handler for name."""
#         handler_registry[self.name] = function
# 
# class MessageType(BaseConst):
#     """MySensors message types."""
# 
#     # pylint: disable=invalid-name
#     presentation = 0  # sent by a node when presenting attached sensors
#     set = 1  # sent from/to sensor when value should be updated
#     req = 2  # requests a variable value
#     internal = 3  # internal message
#     stream = 4  # OTA firmware updates
# 
# class Stream(BaseConst):
#     """MySensors stream sub-types."""
# 
#     # Request new FW, payload contains current FW details
#     ST_FIRMWARE_CONFIG_REQUEST = 0
#     # New FW details to initiate OTA FW update
#     ST_FIRMWARE_CONFIG_RESPONSE = 1
#     ST_FIRMWARE_REQUEST = 2  # Request FW block
#     ST_FIRMWARE_RESPONSE = 3  # Response FW block
#     ST_SOUND = 4  # Sound
#     ST_IMAGE = 5  # Image
# 
# def get_handler_registry():
#     """Return handler registry for this version."""
#     return HANDLERS
# 
# Path: mysensors/validation.py
# _LOGGER = logging.getLogger(__name__)
# def is_version(value):
# def safe_is_version(value):
# def is_battery_level(value):
# def is_heartbeat(value):


import binascii
import voluptuous as vol
from mysensors.const_14 import (  # noqa: F401
    AUTO_CHANGE_OVER,
    COOL_ON,
    FORECASTS,
    HEAT_ON,
    LOGICAL_ONE,
    LOGICAL_ZERO,
    MAX_NODE_ID,
    OFF,
    VALID_INTERNAL,
    VALID_STREAM,
    BaseConst,
    MessageType,
    Stream,
    get_handler_registry,
)
from mysensors.validation import is_version, percent_int
    # Optional sketch name that can be used to identify sensor in the
    # Controller GUI
    I_SKETCH_NAME = 11
    # Optional sketch version that can be reported to keep track of the version
    # of sensor in the Controller GUI.
    I_SKETCH_VERSION = 12
    # Used by OTA firmware updates. Request for node to reboot.
    I_REBOOT = 13
    # Send by gateway to controller when startup is complete
    I_GATEWAY_READY = 14
    # Used between sensors when initialting signing.
    I_REQUEST_SIGNING = 15
    # Used between sensors when requesting nonce.
    I_GET_NONCE = 16
    # Used between sensors for nonce response.
    I_GET_NONCE_RESPONSE = 17


VALID_MESSAGE_TYPES = {
    MessageType.presentation: list(Presentation),
    MessageType.set: list(SetReq),
    MessageType.req: list(SetReq),
    MessageType.internal: list(Internal),
    MessageType.stream: list(Stream),
}

VALID_PRESENTATION = {member: str for member in list(Presentation)}
VALID_PRESENTATION.update(
    {
        Presentation.S_ARDUINO_NODE: is_version,

# Path: mysensors/const_14.py
# AUTO_CHANGE_OVER = "AutoChangeOver"
# 
# COOL_ON = "CoolOn"
# 
# FORECASTS = (STABLE, SUNNY, CLOUDY, UNSTABLE, THUNDERSTORM, UNKNOWN)
# 
# HEAT_ON = "HeatOn"
# 
# LOGICAL_ONE = "1"
# 
# LOGICAL_ZERO = "0"
# 
# MAX_NODE_ID = 254
# 
# OFF = "Off"
# 
# VALID_INTERNAL = {
#     Internal.I_BATTERY_LEVEL: vol.All(
#         percent_int,
#         vol.Coerce(str),
#         msg=f"value must be integer between {0} and {100}",
#     ),
#     Internal.I_TIME: vol.Any("", vol.All(vol.Coerce(int), vol.Coerce(str))),
#     Internal.I_VERSION: str,
#     Internal.I_ID_REQUEST: "",
#     Internal.I_ID_RESPONSE: vol.All(
#         vol.Coerce(int), vol.Range(min=1, max=MAX_NODE_ID), vol.Coerce(str)
#     ),
#     Internal.I_INCLUSION_MODE: vol.In([LOGICAL_ZERO, LOGICAL_ONE]),
#     Internal.I_CONFIG: vol.Any(
#         vol.All(vol.Coerce(int), vol.Range(min=0, max=MAX_NODE_ID)),
#         CONF_METRIC,
#         CONF_IMPERIAL,
#     ),
#     Internal.I_FIND_PARENT: "",
#     Internal.I_FIND_PARENT_RESPONSE: vol.All(
#         vol.Coerce(int), vol.Range(min=0, max=MAX_NODE_ID), vol.Coerce(str)
#     ),
#     Internal.I_LOG_MESSAGE: str,
#     Internal.I_CHILDREN: str,
#     Internal.I_SKETCH_NAME: str,
#     Internal.I_SKETCH_VERSION: str,
#     Internal.I_REBOOT: "",
#     Internal.I_GATEWAY_READY: str,
# }
# 
# VALID_STREAM = {
#     Stream.ST_FIRMWARE_CONFIG_REQUEST: str,
#     Stream.ST_FIRMWARE_CONFIG_RESPONSE: str,
#     Stream.ST_FIRMWARE_REQUEST: str,
#     Stream.ST_FIRMWARE_RESPONSE: str,
#     Stream.ST_SOUND: str,
#     Stream.ST_IMAGE: str,
# }
# 
# class BaseConst(IntEnum):
#     """MySensors message types."""
# 
#     def get_handler(self, handler_registry):
#         """Return correct message handler."""
#         return handler_registry.get(self.name)
# 
#     def set_handler(self, handler_registry, function):
#         """Set message handler for name."""
#         handler_registry[self.name] = function
# 
# class MessageType(BaseConst):
#     """MySensors message types."""
# 
#     # pylint: disable=invalid-name
#     presentation = 0  # sent by a node when presenting attached sensors
#     set = 1  # sent from/to sensor when value should be updated
#     req = 2  # requests a variable value
#     internal = 3  # internal message
#     stream = 4  # OTA firmware updates
# 
# class Stream(BaseConst):
#     """MySensors stream sub-types."""
# 
#     # Request new FW, payload contains current FW details
#     ST_FIRMWARE_CONFIG_REQUEST = 0
#     # New FW details to initiate OTA FW update
#     ST_FIRMWARE_CONFIG_RESPONSE = 1
#     ST_FIRMWARE_REQUEST = 2  # Request FW block
#     ST_FIRMWARE_RESPONSE = 3  # Response FW block
#     ST_SOUND = 4  # Sound
#     ST_IMAGE = 5  # Image
# 
# def get_handler_registry():
#     """Return handler registry for this version."""
#     return HANDLERS
# 
# Path: mysensors/validation.py
# _LOGGER = logging.getLogger(__name__)
# def is_version(value):
# def safe_is_version(value):
# def is_battery_level(value):
# def is_heartbeat(value):


# Path: mysensors/const_15.py
import binascii
import voluptuous as vol
from mysensors.const_14 import (  # noqa: F401
    AUTO_CHANGE_OVER,
    COOL_ON,
    FORECASTS,
    HEAT_ON,
    LOGICAL_ONE,
    LOGICAL_ZERO,
    MAX_NODE_ID,
    OFF,
    VALID_INTERNAL,
    VALID_STREAM,
    BaseConst,
    MessageType,
    Stream,
    get_handler_registry,
)
from mysensors.validation import is_version, percent_int

    # Optional sketch name that can be used to identify sensor in the
    # Controller GUI
    I_SKETCH_NAME = 11
    # Optional sketch version that can be reported to keep track of the version
    # of sensor in the Controller GUI.
    I_SKETCH_VERSION = 12
    # Used by OTA firmware updates. Request for node to reboot.
    I_REBOOT = 13
    # Send by gateway to controller when startup is complete
    I_GATEWAY_READY = 14
    # Used between sensors when initialting signing.
    I_REQUEST_SIGNING = 15
    # Used between sensors when requesting nonce.
    I_GET_NONCE = 16
    # Used between sensors for nonce response.
    I_GET_NONCE_RESPONSE = 17


VALID_MESSAGE_TYPES = {
    MessageType.presentation: list(Presentation),
    MessageType.set: list(SetReq),
    MessageType.req: list(SetReq),
    MessageType.internal: list(Internal),
    MessageType.stream: list(Stream),
}

VALID_PRESENTATION = {member: str for member in list(Presentation)}
VALID_PRESENTATION.update(
    {
        Presentation.S_ARDUINO_NODE: is_version,

        Presentation.S_ARDUINO_REPEATER_NODE: is_version,