示例#1
0
 def __init__(self, device_ip, device_id):
     # Get this from any of the Midea based apps, you can find one on Yitsushi's github page
     self.device_ip = device_ip
     self.device_id = device_id
     self.device_port = 6444
     self.security = security()
     self._retries = 0
示例#2
0
 def __init__(self, device_id):
     self.command = None
     self.security = security()
     # aa20ac00000000000003418100ff03ff000200000000000000000000000006f274
     # Init the packet with the header data.
     self.packet = bytearray([
         # 2 bytes - StaicHeader
         0x5a,
         0x5a,
         # 2 bytes - mMessageType
         0x01,
         0x11,
         # 1 bytes - PacketLenght
         0x68,
         # 3 bytes
         0x00,
         0x20,
         0x00,
         # 4 bytes - MessageId
         0x00,
         0x00,
         0x00,
         0x00,
         # 8 bytes - Date&Time
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         # 6 bytes - mDeviceID
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         # 14 bytes
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00
     ])
     _LOGGER.debug("add packet_time")
     self.packet[12:20] = self.packet_time()
     self.packet[20:26] = bytearray.fromhex(device_id)
示例#3
0
 def __init__(self, device_id: int):
     self.command = None
     self.security = security()
     # aa20ac00000000000003418100ff03ff000200000000000000000000000006f274
     # Init the packet with the header data.
     self.packet = bytearray([
         # 2 bytes - StaicHeader
         0x5a,
         0x5a,
         # 2 bytes - mMessageType
         0x01,
         0x11,
         # 2 bytes - PacketLenght
         0x00,
         0x00,
         # 2 bytes
         0x20,
         0x00,
         # 4 bytes - MessageId
         0x00,
         0x00,
         0x00,
         0x00,
         # 8 bytes - Date&Time
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         # 6 bytes - mDeviceID
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         # 12 bytes
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00,
         0x00
     ])
     self.packet[12:20] = self.packet_time()
     self.packet[20:28] = device_id.to_bytes(8, 'little')
示例#4
0
def discover(debug: int):
    """Discover Midea Devices with UDP Broadcast"""
    if debug:
        logging.basicConfig(level=logging.DEBUG)
        _LOGGER.info("Debug mode active")
    else:
        logging.basicConfig(level=logging.INFO)

    _security = security()

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.settimeout(5)
    found_devices = {}
    _LOGGER.info("msmart version: {}".format(VERSION))
    _LOGGER.info(
        "Discovering devices with UDP Broadcast, press CTRL-C to quit...")
    for i in range(10):
        try:
            sock.sendto(BROADCAST_MSG, ("255.255.255.255", 6445))
            while True:
                data, addr = sock.recvfrom(512)
                m_ip = addr[0]
                m_id, m_type, m_sn, m_ssid = 'unknown', 'unknown', 'unknown', 'unknown'
                if len(data) >= 104 and (data[:2].hex() == '5a5a'
                                         or data[8:10].hex() == '5a5a'
                                         ) and m_ip not in found_devices:
                    _LOGGER.info("Midea Local Data {} {}".format(
                        m_ip, data.hex()))
                    if data[8:10].hex() == '5a5a':
                        data = data[8:-16]
                    m_id = convert_device_id_int(data[20:26].hex())
                    found_devices[m_ip] = m_id
                    encrypt_data = data[40:-16]
                    reply = _security.aes_decrypt(encrypt_data)

                    m_sn = reply[14:14 + 26].decode("utf-8")
                    # ssid like midea_xx_xxxx net_xx_xxxx
                    m_ssid = reply[14 + 27:14 + 27 + 13].decode("utf-8")
                    m_type = m_ssid.split('_')[1]

                    m_support = support_test(m_ip, int(m_id))

                    _LOGGER.info(
                        "*** Found a {} '0x{}' at {} - id: {} - sn: {} - ssid: {}"
                        .format(m_support, m_type, m_ip, m_id, m_sn, m_ssid))
                elif m_ip not in found_devices:
                    _LOGGER.info("Maybe not midea local data {} {}".format(
                        m_ip, data.hex()))

        except socket.timeout:
            continue
        except KeyboardInterrupt:
            sys.exit(0)
示例#5
0
文件: lan.py 项目: rokam/midea-msmart
 def __init__(self, device_ip, device_id, device_port=6444):
     self.device_ip = device_ip
     self.device_id = device_id
     self.device_port = device_port
     self.security = security()
     self._retries = 0
     self._socket = None
     self._token = None
     self._key = None
     self._timestamp = time.time()
     self._tcp_key = None
     self._local = None
     self._remote = device_ip + ":" + str(device_port)
示例#6
0
文件: cli.py 项目: zvldz/midea-msmart
def discover(debug: int):
    """Discover Midea Devices with UDP Broadcast"""
    if debug:
        logging.basicConfig(level=logging.DEBUG)
        _LOGGER.info("Debug mode active")
    else:
        logging.basicConfig(level=logging.INFO)

    _security = security()

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    sock.settimeout(5)
    found_devices = {}
    _LOGGER.info(
        "Discovering devices with UDP Broadcast, press CTRL-C to quit...")
    for i in range(10):
        try:
            sock.sendto(BROADCAST_MSG, ("255.255.255.255", 6445))
            while True:
                data, addr = sock.recvfrom(512)
                m_ip = addr[0]
                if len(data) >= 41 and m_ip not in found_devices:
                    m_id = convert_device_id_int(data[20:26].hex())
                    found_devices[m_ip] = m_id
                    data = data[40:40 + 64]
                    reply = _security.aes_decrypt(data)

                    m_sn = reply[14:14 + 26].decode("utf-8")
                    m_ssid = reply[14 + 27:].decode("utf-8")
                    m_type = m_ssid.split('_')[1]
                    m_support = 'unknown'
                    if m_type == 'ac':
                        m_support = support_test(m_ip, int(m_id))

                    _LOGGER.info(
                        "Found a {} '0x{}' at {} - id: {} - sn: {} - ssid: {}".
                        format(m_support, m_type, m_ip, m_id, m_sn, m_ssid))

        except socket.timeout:
            continue
        except KeyboardInterrupt:
            sys.exit(0)
示例#7
0
    def __init__(self, email, password):
        # Get this from any of the Midea based apps, you can find one on Yitsushi's github page
        # self.app_key = app_key
        self.login_account = email  # Your email address for your Midea account
        self.password = password

        # An obscure log in ID that is seperate to the email address
        self.login_id = None

        # A session dictionary that holds the login information of the current user
        self.session = {}

        # A list of home groups used by the API to seperate "zones"
        self.home_groups = []

        # A list of appliances associated with the account
        self.appliance_list = []

        self._api_lock = Lock()

        self.security = security()
        self._retries = 0
示例#8
0
def discover(debug: int):
    """Send Device Scan Broadcast"""
    if debug:
        logging.basicConfig(level=logging.DEBUG)
        _LOGGER.info("Debug mode active")
    else:
        logging.basicConfig(level=logging.INFO)

    _security = security()

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    try:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    except AttributeError:
        # Will be raised when executed in Windows. Safe to ignore.
        pass

    sock.settimeout(5)
    found_devices = {}
    _LOGGER.info("msmart version: {}".format(VERSION))
    _LOGGER.info("Sending Device Scan Broadcast...")
    for i in range(10):
        try:
            sock.sendto(BROADCAST_MSG, ("255.255.255.255", 6445))
            sock.sendto(BROADCAST_MSG, ("255.255.255.255", 20086))
            while True:
                data, addr = sock.recvfrom(512)
                m_ip = addr[0]
                if m_ip in found_devices:
                    continue
                m_id, m_type, m_sn, m_ssid, m_version, m_support = 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown'
                if len(data) >= 104 and (data[:2].hex() == '5a5a'
                                         or data[8:10].hex() == '5a5a'):
                    _LOGGER.info("Midea Local Data {} {}".format(
                        m_ip, data.hex()))
                    data_string = data.decode("utf-8", errors="replace")
                    # _LOGGER.info(data.decode("utf-8", errors="replace"))
                    # root=ET.fromstring(data.decode(encoding="utf-8", errors="replace"))
                    if data[:2].hex() == '5a5a':
                        m_version = 'V2'
                    if data[:2].hex() == '8370':
                        m_version = 'V3'
                    if data[8:10].hex() == '5a5a':
                        data = data[8:-16]
                    m_id = convert_device_id_int(data[20:26].hex())
                    found_devices[m_ip] = m_id
                    encrypt_data = data[40:-16]
                    reply = _security.aes_decrypt(encrypt_data)
                    _LOGGER.info("Decrypt Reply: {} {}".format(
                        m_ip, reply.hex()))

                    m_ip = '.'.join([str(i) for i in reply[3::-1]])
                    m_port = str(bytes2port(reply[4:8]))
                    m_sn = reply[8:40].decode("utf-8")
                    # ssid like midea_xx_xxxx net_xx_xxxx
                    m_ssid = reply[41:41 + reply[40]].decode("utf-8")
                    # if len(reply) > 54:

                    m_type = m_ssid.split('_')[1]

                    m_support = support_test(m_ip, int(m_id), int(m_port))

                    _LOGGER.info(
                        "*** Found a {} device - type: '0x{}' - version: {} - ip: {} - port: {} - id: {} - sn: {} - ssid: {}"
                        .format(m_support, m_type, m_version, m_ip, m_port,
                                m_id, m_sn, m_ssid))

                if data[:6].hex() == '3c3f786d6c20':
                    m_version = 'V1'
                    root = ET.fromstring(
                        data.decode(encoding="utf-8", errors="replace"))
                    child = root.find('body/device')
                    m = child.attrib
                    m_port, m_sn, m_type = m['port'], m['apc_sn'], str(
                        hex(int(m['apc_type'])))[2:]
                    response = get_device_info(m_ip, int(m_port))
                    m_id = get_id_from_response(response)

                    _LOGGER.info(
                        "*** Found a {} device - type: '0x{}' - version: {} - ip: {} - port: {} - id: {} - sn: {} - ssid: {}"
                        .format(m_support, m_type, m_version, m_ip, m_port,
                                m_id, m_sn, m_ssid))

        except socket.timeout:
            continue
        except KeyboardInterrupt:
            sys.exit(0)
示例#9
0
parser.add_argument('-f',
                    "--fiter_type",
                    type=str,
                    dest="fiter_type",
                    help='fliter type from midea message',
                    default='all',
                    choices=['all', 'get', 'reply', 'set', 'unknown', 'error'])
parser.add_argument("--tcp-raw", action='store_true')
parser.add_argument("--msg-raw", action='store_true')
args = parser.parse_args()
cap = pyshark.FileCapture(
    args.pcapfile,
    display_filter=("tcp && data.len == 104 && data[:2] == 5a5a"))

_security = security()

for packet in cap:
    packet.data.raw_mode = True
    tcp_data = packet.data.data
    tcp_data_bytes = bytearray.fromhex(tcp_data)
    tcp_data_len = int(tcp_data_bytes[4:5].hex(), 16)
    if len(tcp_data_bytes) != tcp_data_len:
        continue
    device_id = tcp_data_bytes[20:26].hex()
    midea_data = tcp_data_bytes[40:88]
    reply = _security.aes_decrypt(midea_data)

    msg_type_hex = 255
    msg_type = 'error'
示例#10
0
 def __init__(self, device_ip, device_id, device_port=6444):
     self.device_ip = device_ip
     self.device_id = device_id
     self.device_port = device_port
     self.security = security()
     self._retries = 0