# Path: cbus/common.py
# class Application(IntEnum):
#     TEMPERATURE = 0x19
#     LIGHTING_FIRST = LIGHTING_30 = 0x30
#     LIGHTING_31 = 0x31
#     LIGHTING_32 = 0x32
#     LIGHTING_33 = 0x33
#     LIGHTING_34 = 0x34
#     LIGHTING_35 = 0x35
#     LIGHTING_36 = 0x36
#     LIGHTING_37 = 0x37
#     LIGHTING = LIGHTING_38 = 0x38
#     LIGHTING_39 = 0x39
#     LIGHTING_3a = 0x3a
#     LIGHTING_3b = 0x3b
#     LIGHTING_3c = 0x3c
#     LIGHTING_3d = 0x3d
#     LIGHTING_3e = 0x3e
#     LIGHTING_3f = 0x3f
#     LIGHTING_40 = 0x40
#     LIGHTING_41 = 0x41
#     LIGHTING_42 = 0x42
#     LIGHTING_43 = 0x43
#     LIGHTING_44 = 0x44
#     LIGHTING_45 = 0x45
#     LIGHTING_46 = 0x46
#     LIGHTING_47 = 0x47
#     LIGHTING_48 = 0x48
#     LIGHTING_49 = 0x49
#     LIGHTING_4a = 0x4a
#     LIGHTING_4b = 0x4b
#     LIGHTING_4c = 0x4c
#     LIGHTING_4d = 0x4d
#     LIGHTING_4e = 0x4e
#     LIGHTING_4f = 0x4f
#     LIGHTING_50 = 0x50
#     LIGHTING_51 = 0x51
#     LIGHTING_52 = 0x52
#     LIGHTING_53 = 0x53
#     LIGHTING_54 = 0x54
#     LIGHTING_55 = 0x55
#     LIGHTING_56 = 0x56
#     LIGHTING_57 = 0x57
#     LIGHTING_58 = 0x58
#     LIGHTING_59 = 0x59
#     LIGHTING_5a = 0x5a
#     LIGHTING_5b = 0x5b
#     LIGHTING_5c = 0x5c
#     LIGHTING_5d = 0x5d
#     LIGHTING_5e = 0x5e
#     LIGHTING_LAST = LIGHTING_5f = 0x5f
#     CLOCK = 0xDF
#     ENABLE = 0xCB
#     MASTER_APPLICATION = STATUS_REQUEST = 0xff
# 
# class ClockAttribute(IntEnum):
#     TIME = 0x01
#     DATE = 0x02
# 
# class ClockCommand(IntEnum):
#     UPDATE_NETWORK_VARIABLE = 0x08
#     REQUEST_REFRESH = 0x11
# 
# Path: cbus/protocol/application/sal.py
# class BaseApplication(abc.ABC):
#     """
#     Describes an decoder for all commands sent to an application.
#     """
# 
#     @staticmethod
#     @abc.abstractmethod
#     def supported_applications() -> FrozenSet[Union[int, Application]]:
#         """
#         Gets a list of supported Application IDs for the application.
# 
#         All application IDs must be in the range 0x00 - 0xff.
#         """
#         raise NotImplementedError('supported_applications')
# 
#     @staticmethod
#     @abc.abstractmethod
#     def decode_sals(data: bytes) -> Sequence[SAL]:
#         """
#         Decodes a SAL message
# 
#         """
#         raise NotImplementedError('decode_sals')
# 
# class SAL(abc.ABC):
#     """
#     Describes an decoder/encoder
# 
#     """
#     @abc.abstractmethod
#     def encode(self) -> bytes:
#         return bytes()
# 
#     @property
#     @abc.abstractmethod
#     def application(self) -> Union[int, Application]:
#         raise NotImplementedError('application')


import abc
import warnings
from datetime import date, time, datetime
from struct import unpack, pack
from typing import Union, Set, Sequence, Tuple, Optional
from six import byte2int
from cbus.common import Application, ClockAttribute, ClockCommand
from cbus.protocol.application.sal import BaseApplication, SAL
            return cls(date(year, month, day)), data

        elif variable == ClockAttribute.TIME:
            # time (23.5.1.1)
            # length must be 0x05
            if data_length != 0x05:
                warnings.warn(
                    f'Ignoring date variable with length {data_length} '
                    f'(expected 5)', UserWarning)
                return None, data

            # now decode the time
            hour, minute, second, dst = unpack('>BBBB', val)
            # note: dst / daylight savings flag is ignored

            return cls(time(hour, minute, second)), data
        else:
            warnings.warn(
                f'Tried to decode unknown clock update variable {variable:x}',
                UserWarning)

            # attempt to skip the bad data and recover
            return None, data[data_length:]

    def encode(self) -> bytes:
        if isinstance(self.val, time):
            # time
            # TODO: implement DST flag
            val = pack(
                '>BBBB', self.val.hour, self.val.minute, self.val.second, 255)

# Path: cbus/common.py
# class Application(IntEnum):
#     TEMPERATURE = 0x19
#     LIGHTING_FIRST = LIGHTING_30 = 0x30
#     LIGHTING_31 = 0x31
#     LIGHTING_32 = 0x32
#     LIGHTING_33 = 0x33
#     LIGHTING_34 = 0x34
#     LIGHTING_35 = 0x35
#     LIGHTING_36 = 0x36
#     LIGHTING_37 = 0x37
#     LIGHTING = LIGHTING_38 = 0x38
#     LIGHTING_39 = 0x39
#     LIGHTING_3a = 0x3a
#     LIGHTING_3b = 0x3b
#     LIGHTING_3c = 0x3c
#     LIGHTING_3d = 0x3d
#     LIGHTING_3e = 0x3e
#     LIGHTING_3f = 0x3f
#     LIGHTING_40 = 0x40
#     LIGHTING_41 = 0x41
#     LIGHTING_42 = 0x42
#     LIGHTING_43 = 0x43
#     LIGHTING_44 = 0x44
#     LIGHTING_45 = 0x45
#     LIGHTING_46 = 0x46
#     LIGHTING_47 = 0x47
#     LIGHTING_48 = 0x48
#     LIGHTING_49 = 0x49
#     LIGHTING_4a = 0x4a
#     LIGHTING_4b = 0x4b
#     LIGHTING_4c = 0x4c
#     LIGHTING_4d = 0x4d
#     LIGHTING_4e = 0x4e
#     LIGHTING_4f = 0x4f
#     LIGHTING_50 = 0x50
#     LIGHTING_51 = 0x51
#     LIGHTING_52 = 0x52
#     LIGHTING_53 = 0x53
#     LIGHTING_54 = 0x54
#     LIGHTING_55 = 0x55
#     LIGHTING_56 = 0x56
#     LIGHTING_57 = 0x57
#     LIGHTING_58 = 0x58
#     LIGHTING_59 = 0x59
#     LIGHTING_5a = 0x5a
#     LIGHTING_5b = 0x5b
#     LIGHTING_5c = 0x5c
#     LIGHTING_5d = 0x5d
#     LIGHTING_5e = 0x5e
#     LIGHTING_LAST = LIGHTING_5f = 0x5f
#     CLOCK = 0xDF
#     ENABLE = 0xCB
#     MASTER_APPLICATION = STATUS_REQUEST = 0xff
# 
# class ClockAttribute(IntEnum):
#     TIME = 0x01
#     DATE = 0x02
# 
# class ClockCommand(IntEnum):
#     UPDATE_NETWORK_VARIABLE = 0x08
#     REQUEST_REFRESH = 0x11
# 
# Path: cbus/protocol/application/sal.py
# class BaseApplication(abc.ABC):
#     """
#     Describes an decoder for all commands sent to an application.
#     """
# 
#     @staticmethod
#     @abc.abstractmethod
#     def supported_applications() -> FrozenSet[Union[int, Application]]:
#         """
#         Gets a list of supported Application IDs for the application.
# 
#         All application IDs must be in the range 0x00 - 0xff.
#         """
#         raise NotImplementedError('supported_applications')
# 
#     @staticmethod
#     @abc.abstractmethod
#     def decode_sals(data: bytes) -> Sequence[SAL]:
#         """
#         Decodes a SAL message
# 
#         """
#         raise NotImplementedError('decode_sals')
# 
# class SAL(abc.ABC):
#     """
#     Describes an decoder/encoder
# 
#     """
#     @abc.abstractmethod
#     def encode(self) -> bytes:
#         return bytes()
# 
#     @property
#     @abc.abstractmethod
#     def application(self) -> Union[int, Application]:
#         raise NotImplementedError('application')


# Path: cbus/protocol/application/clock.py
import abc
import warnings
from datetime import date, time, datetime
from struct import unpack, pack
from typing import Union, Set, Sequence, Tuple, Optional
from six import byte2int
from cbus.common import Application, ClockAttribute, ClockCommand
from cbus.protocol.application.sal import BaseApplication, SAL

            return cls(date(year, month, day)), data

        elif variable == ClockAttribute.TIME:
            # time (23.5.1.1)
            # length must be 0x05
            if data_length != 0x05:
                warnings.warn(
                    f'Ignoring date variable with length {data_length} '
                    f'(expected 5)', UserWarning)
                return None, data

            # now decode the time
            hour, minute, second, dst = unpack('>BBBB', val)
            # note: dst / daylight savings flag is ignored

            return cls(time(hour, minute, second)), data
        else:
            warnings.warn(
                f'Tried to decode unknown clock update variable {variable:x}',
                UserWarning)

            # attempt to skip the bad data and recover
            return None, data[data_length:]

    def encode(self) -> bytes:
        if isinstance(self.val, time):
            # time
            # TODO: implement DST flag
            val = pack(
                '>BBBB', self.val.hour, self.val.minute, self.val.second, 255)

            attr = ClockAttribute.TIME