Giter VIP home page Giter VIP logo

node-mideahvac's Introduction

Monitoring and controlling Midea-like air conditioners

Build Coverage Status npm

Note: Version 0.2.0 is a complete rewrite and not backwards compatible. The midea cloud is no longer supported, instead direct communication (over the LAN) to the airconditioner using the original SmartKey dongle is supported.

This module enables the monitoring and controlling of 'Midea'-like airconditioners. The remote control functionality via WiFi provided by various vendors of air conditioners, either as default or optional feature, is using the same type of interface and the Midea cloud. Examples of vendors using this interface are:

  • Midea
  • Qlima
  • Artel
  • Carrier

The WiFi interface is provided by a dongle, called WiFi SmartKey (sk103), either connected to an USB type-A connector or a JST-HX type of connector. This dongle wraps the UART protocol used to communicate with the AC unit with a layer for authentication and encryption for communication with a mobile app via the Midea cloud or directly via a local LAN connection. However, it turned out the dongle is just connected to a serial interface (TTL level) of the AC unit. This means an alternative is to hook up directly to this serial interface and bypass the cloud, authentication and encryption stuff. More information on creating a custom dongle can be found the prerequisites section.

This module supports direct communication using the WiFi SmartKey and direct communication via a TCP-serial bridge connected to the UART port of the appliance (e.g a custom dongle running esp-link firmware).

References and sources

The knowledge to create the logic to monitor and control the Midea-'like' AC units was gathered by reverse engineering Android applications from various vendors, analyzing the UART protocol between an Artel unit and an SK103 SmartKey, documents found on the Internet, primarily in Chinese and the work from:

Mac Zhou and Nenad Bogojevic deserve all the credits for reverse engineering the direct communication with the SmartKey. Where I had given up on ever figuring out how to obtain the key and token required, Mac persisted and eventually was successful, while Nenad was able to discover what changed in this process for users who migrated their accounts from the Midea Air app to the SmartHome app.

Status

All common functions of Airconditioners are supported, but support for specific features only available on some airconditioners might be incomplete or missing because it is unknown how they work and the inability to test. Any help is welcome. Also support for (de)humidifiers is missing.

The direct communication with the original dongle, the SmartKey, has been tested with a SK103 running firmware 3.0.8. The discover command required to obtain the token and key required for direct communication only supports accounts that have been migrated to the SmartHome app.

⚠️ The SK103 module, when using the SK103 communication method and poll the status frequently, might disconnect from your WiFi network and a powercycle is required to reconnect. Lowering the frequency of polling might prevent this.

Prerequisites

For the direct communication method using an SK103 original SmartKey dongle is required running firmware version 3.0.8 and a SmartHome account (Midea Air or NetHome Plus accounts do not work anymore because Midea removed the ability to retrieve the required key and token for these type of accounts).

For the serialbridge a custom dongle is required running the esp-link firmware). Examples of designs of custom dongles are:

Installation

npm install node-mideahvac

Usage

First create an appliance instance by specifying the following parameters:

parameter use method
communicationMethod this must be either 'sk103' or 'serialbridge' sk103 / serialbridge
host this is the address of the dongle, either the SmartKey (sk103) or the custom dongle running TCP-serial bridge firmware sk103 / serialbridge
port this is the port the TCP-serial bridge firmware is listening on (default 23) serialbridge
id the id of the appliance (as can be determined using the discovery tool) sk103
key The key can be obtained using the discover tool) sk103
token The token can be obtained using the discover tool) sk103

For each AC unit to be monitored and controlled an appliance must be instantiated.

An example of creating an appliance using the sk103 direct communication method:

const appliances = require('node-mideahvac')

var options = {
    communicationMethod: 'sk103',
    id: <the id of the device to control>,
    key: <the key for the device to control>,
    token: <the token for the device to control>
}

var ac = appliances.createAppliance(options)

An example of creating an appliance using a TCP serial bridge:

const appliances = require('node-mideahvac')

var options = {
    communicationMethod: 'serialbridge',
    host: '192.168.10.34',
    port: 23
}

var ac = appliances.createAppliance(options)

Methods

All methods return a promise and the retry parameter indicates how many times the command must be retried when a retryable error occurs (default = 0).

The following methods are provided:

  • getCapabilities(retry), this method requests the AC unit for its supported capabilities (0xB5 query). This command is not supported by all AC units and the reported values are not always correct (e.g. my Artel units report the left/right fan can be controlled while it can only be manually controlled and Fahrenheit as unit is not supported while it is).

    The default values specify which value is reported by this module when the AC unit does not report this capability at all.

    The promise resolves to a JSON object containing the following capabilities:

Capability Type Default Description
activeClean boolean false active cleaning mode
autoMode boolean false auto mode (cooling or heating is automatically selected)
autoSetHumidity boolean false humidity setpoint automatically determined
breezeControl boolean false breeze mode can be controlled
buzzer boolean false buzzer can be disabled
coolMode boolean false cooling mode
decimals boolean false setpoint in decimals
downNoWindFeel boolean false
dryMode boolean false dry mode
ecoMode boolean false eco mode
electricAuxHeating boolean false
fanSpeedControl boolean true fan speed can be controlled
frostProtectionMode boolean false temperature is maintained at 8C to protect against frost
heatMode boolean false heat mode
indoorHumidity boolean false indoor humidity is reported
leftrightFan boolean false left/right fan can be controlled
lightControl boolean false display can be dimmed
manualSetHumidity boolean false humidity setpoint can be specified
maxTempAuto number 30 maximum setpoint in auto mode
maxTempCool number 30 maximum setpoint in cool mode
maxTempHeat number 30 maximum setpoint in heat mode
minTempAuto number 17 minimum setpoint in auto mode
minTempCool number 17 minimum setpoint in cool mode
minTempHeat number 17 minimum setpoint in heat mode
nestCheck boolean false
nestNeedChange boolean false
oneKeyNoWindOnMe boolean false
oneKeyNoWindOnMe boolean false
powerCal boolean false power usage can be reported
powerCalSetting boolean false
silkyCool boolean false
smartEye boolean false
specialEco boolean false
turboCool boolean false cool mode supports turbo mode
turboHeat boolean false heat mode supports turbo mode
unitChangeable boolean false the temperature unit can be changed from Celsius to Fahrenheit
updownFan boolean false up/down fan can be controlled
upNoWindFeel boolean false
windOffMe boolean false
windOnMe boolean false
  • getPowerUsage(retry), this method requests the current power usage of the unit (specific 0x41 command). The promise resolves to a JSON object containing the property values when successful. The following properties are reported:
Property Type Description
powerUsage number Power usage in kWh
  • getStatus(retry), this method requests the current status of the unit (0x41 command). The promise resolves to a JSON object containing the property values when successful. The following properties are reported:
Property Values Description
braceletControl true/false
braceletSleep true/false
catchCold true/false
childSleep true/false
coolFan true/false
cosySleep 0: no sleep
1: sleep 1
2: sleep 2
3: sleep 3
sleep mode, reported as the following JSON object:
{ value: n, description: text }
downWindControl true/false
downWindControlLR true/false
dryClean true/false
dualControl true/false probably to the follow me mode is active where the remote control acts as the temperature sensor
dustFull true/false
ecoMode true/false eco mode is enabled
ecoSleepRunningHours 0-15
ecoSleepRunningMinutes 0-59
ecoSleepRunningSeconds 0-59
fanSpeed 0-20: silent
21-59: low
60-79: medium
80-100: high
101: fixed
102: auto
reported as the following JSON object:
{ value: n, description: text }
fastCheck true/false
feelOwn true/false
frostProtection true/false frost protection is active
humiditySetpoint 0-100% humidity setpoint
indoorTemperature -25-102°C
-13-215°F
indoor temprature
inError true/false the unit is in error
keepWarm true/false
leftrightFan true/false left/right fan is active
light 0-7 brightness level of display light
lowFrequencyFan true/false
mode 1: auto
2: cool
3: dry
4: heat
5: fanonly
6: customdry
reported as the following JSON object:
{ value: n, description: text }
naturalFan true/false
nightLight true/false
offTimer true/false scheduled to turn on
offTimerHours 0 - 24 number of hours until the unit will be turned off
offTimerMinutes 0 - 59 number of minutes until the unit will be turned off
onTimer true/false scheduled to turn on
onTimerHours 0 - 24 number of hours until the unit will be turned on
onTimerMinutes 0 - 59 number of minutes until the unit will be turned on
outdoorTemperature -25-102°C
-13-215°F
outdoor temperature
peakValleyElectricitySaving true/false
pmv 99: off
-3: cold
-2.5: chill
-2: chill
-1.5: cool
-1: cool
-0.5: comfortable
0: comfortable
0.5: comfortable
1: slightly warm
1.5: slightly warm
2: warm
2.5: warm
predicted mean vote (the experienced temperature), reported as the following JSON object:
{ value: n, description: text }
powerOn true/false power status
ptcHeater true/false
purify true/false
resume true/false automatically resume after recovery from power failure
save true/false
selfCosySleep true/false
selfFeelOwn true/false
sleepMode true/false sleep mode is activated
smartEye true/false
smartWind true/false
statusCode see Status codes reported as the following JSON object:
{ value: n, description: text }
temp 0-32 probably the temperature reported by the remote control sensor in follow me mode
tempDecimal true/false probably indicates decimals are supported for the temperature reported by the remote control
temperatureSetpoint 17 - 30°C
62-86°F
temperature setpoint
temperatureUnit 0: Celsius
1: Fahrenheit
unit used to report temperatures
timerMode 0: relative
1: absolute
how to specify the time for the timer (only relative mode is supported)
turboMode true/false turbo mode enabled
updownFan true/false up/down fan is active
ventilation true/false
windBlowing true/false

Properties with a name like bytenbitm can also be reported. These are properties where I do not have a clue whether they are used. For instance byte3bit3 means the value of bit 3 in byte 3, or byte3bit34 means the value of bit3-4 in byte 3. You would help me to determine the meaning of these bits when you report them in the issues section with their values and possibly what happened.

Status codes:

Code Description
0 ok
1 interior board and display board communication failure
2 indoor main control board failure
3 indoor board and outdoor board communication failure
4 zero crossing detection failure
5 indoor board fan stall failure
6 outdoor condenser sensor failure
7 outdoor ambient temperature sensor failure
8 outdoor compression engine exhaust temperature sensor failure
9 outdoor failure
10 indoor temperature sensor failure
11 indoor evaporator temperature sensor failure
12 outdoor wind speed stall failure
13 ipm module protection
14 voltage protection
15 outdoor compressor top temperature protection
16 outdoor temperature too low protection
17 compressor position protection
18 display panel fault
21 outer pipe temperature protection
23 exhaust high temperature protection
25 heating and cold wind protection
26 current protection
29 evaporator high and low temperature protection
30 condenser high and low temperature protection frequency limit
31 exhaust high and low temperature protection
32 indoor and outdoor communication mismatch protocol
33 refrigerant leakage protection
38 water tank full or missing
  • initialize(), this method can be used to perform some initializion:

    • The getCapabilities command is issued to determine the supported capabilities
    • The setStatus command is issued to determine the current values of all properties
    • The sendNetworkStatusNotification command (only when the serialbridge method is used) is scheduled to be issued every 2 minutes to make sure the WiFi connected symbol is show on the AC display. The response is a JSON object merging the responses from the getCapabilities and getStatus mthods.
  • sendNetworkStatusNotification(), this method is only available for the serialbridge communication method must be called at least once every 2 minutes in order to display the WiFi connected symbol in the display of the AC.

  • setStatus(properties, retry), this method must be used to change the status of the unit. The properties parameter is an object containing all the properties and their values that need to be changed. To prevent changing properties unintentionaly, before calling the setStatus command a getStatus command must be send to retrieve the current values of all properties. The response is a JSON object containing all the properties with their values, just like returned by the getStatus method.

The following properties can be set:

Property Type Possible values Description
beep boolean true, false en/disable a beep as feedback
fanSpeed string number silent, low, medium, high, auto or 0 - 100%
frostProtectionMode boolean true, false turn frost protection mode (min. temperature is 8°C) on/off. This is only supported in heat mode
humiditySetpoint number 35 - 85 set the desired humidity in %
leftrightFan boolean true, false turn the left/right (vertical) fan on/off
mode string cool, heat, fanonly, dry, auto, customdry set the operational mode
powerOn boolean true, false power the unit on/off
temperatureSetpoint number 16 - 31 / 60 - 87 set the desired temperature in °C or °F
sleepMode boolean true, false turn the sleep mode on/off
temperatureUnit string fahrenheit, celsius set the temperature unit to fahrenheit/celsius
turboMode boolean true, false turn turbo mode on/off
updownFan boolean true, false turn the up/down (horizontal) fan on/off

Example: Turn the unit on, set the temperature setpoint to 24°C and retry max. 3 times.

ac.setStatus({ powerOn: true, setpoint: 24 }, 3)
.catch(error => {
    console.log(error.message)
})

Events

The following events are emitted:

  • connected, this event is emitted when using the serialbridge communication method and the connection to the bridge has been established.

  • disconnected,this event is emitted when using the serialbridge communication method and the connection is disconnected.

  • status-update, this event is emitted when the value of one or more properties is updated. The data is a JSON object containing all updated properties with their values.

Logging

The Winston module is used for logging. You can configure the logging by creating your own logger, e.g.:

const logger = require('winston')

logger.remove(logger.transports.Console)
logger.add(new logger.transports.Console({
  format: logger.format.combine(
    logger.format.timestamp(),
    logger.format.colorize(),
    logger.format.printf(event => {
      return `${event.timestamp} ${event.level}: ${event.message}`
    })
  ),
  level: 'silly'
}))

By specifying the level you can control the amount of logging generated.

More information on Winston can be found here: https://www.npmjs.com/package/winston

Discovery

The module installs the midea-discover command line tool in the node_modules/.bin directory. This tool tries to find any appliances on the local network with a SmartKey and displays all relevant information required for configuring this module. When the userId and password of a SmartHome account are specified on the command line, the discovery tool will also retrieve the values for the token and key required. These values are retrieved from the Midea cloud so an Internet connection is required, but these values only need to be retrieved once.

# node_modules/.bin/midea-discover [--user=<SmartHome user>, --password=<SmartHome password>]

or

# npx midea-discover [--user=<SmartHome user>, --password=<SmartHome password>]

By default the discover command uses the 255.255.255.255 broadcast address which means only appliances on the same subnet network as the computer running the discover command will be discovered. If the appliances are on another network either specify the broadcast IP address of that network, e.g. 192.168.3.255, or use the IP address of the appliance itself using the -T or --target parameter:

# npx midea-discover --target=[target IP address]

Example response:

Found 2 appliances:

Appliance 1:
- Id: 20330721052279
- Host: 192.168.5.124
- Port: 6444
- MAC Address: c4:dc:9a:4a:1d:26
- Serial No.: 000000P0000000Q1833C9B4A14360000
- Appliance Type: Air Conditioner
- Firmware Version: 3.0.8
- New Encryption Version: true
- UDP Id: fbf0c1b2c39223c07cd284590aed9003
- Authentication Key: 022BA2C782A41BFFBED33B769AA0889E6EC858D43DB74306A207EFD74C1066B5
- Authentication Token: 9C06A28C7223C0268765BADE044DA029E933CF12C6280241C18BAF992D47B3227A15DE88FEAA0829FAA33AD684311495F43DF7D2E740E52D68220C183045D557

Appliance 2:
- Id: 12691694762294
- Host: 192.168.5.121
- Port: 6444
- MAC Address: c4:7c:2b:26:59:29
- Serial No.: 000000P0000000Q1833C9B265A190000
- Appliance Type: Air Conditioner
- Firmware Version: 3.0.8
- New Encryption Version: true
- UDP Id: 8b8c0c88c8276edde9a8acd139022118
- Authentication Key: B848C224F28E4C2AAF112C1C557707FBAF76593F95EE45DC8F693AE682BCDD0F
- Authentication Token: CF24662D8309FA055460B4E67A00EDE09117455DCBDEA7A90C97CE3B9EEDC1DF0305C36B1399C2F07FFA0935336991C856A0E13705FD7D5C79AF80D70C8322C7C

node-mideahvac's People

Contributors

hypfer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-mideahvac's Issues

Turbo mode question

Hello,

I am currently using this for my midea ac:

https://github.com/ashevchuk/midea-ac/

With the script mentioned above I am able to control every single part of the AC except the turbo mode.

My question now is do you handle the setting of the turbo mode differently?
If yes what exactly is the difference ?

(I am searching for a long time for a solution where the turbo mode would also work for me)

"No response received" error

Thank you for this amazing repo! I have a Midea AC and I'm getting "No response received" error when I try to run your code.

I'm using my custom TCP-Serial bridge using the standard Aliexpress components which worked normally via Home Assistant app. However, since I would like to create my custom app for the control of my a/c and get rid of Home Assistant I decided to try your repo. So I used the exact same hardware, I just flashed ESP-Link to my ESP-01, added my wifi credentials and set my static ip 192.168.1.90.

However I keep getting above error, you can also find log with details to the bottom of my message.

When I connect it to the serial of my AC, the IP works normally, so I think that the only part missing is the connection between the ESP-01 and the AC. Since I use the exact same cable that I use with HA, connecting it to the exact same way as with HA app, the only I can think of is that maybe I did something wrong with the pin assignment within the settings of ESP-Link, where I chose the ESP-01 preset.

Is there any suggestion you can give me to help me about the pin assignment, as I really don't know what to change there? Or maybe do you have any other idea what I may did wrong?

Thank you in advance!

My code:

const appliances = require('node-mideahvac');

// Specify your specific information
const ac = appliances.createAppliance({
  communicationMethod: 'serialbridge',
  host: '192.168.1.90',
  port: '23'
});

// Any updated status properties will be printed
ac.on('status-update', data => {
  console.log(`Received updates: ${JSON.stringify(data)}`);
});

ac.initialize()
  .then(response => {
    console.log('Initialized, start polling');

    // The status will be polled each 30s, when properties are changed these will be emitted as a
    // status-update
    setInterval(() => {
      ac.getStatus()
        .catch(error => {
          console.log(`Error: ${error.message}`);
        });
    }, 30000);
  })
  .catch(error => {
    console.log(`Error: Failed to initialize (${error.message})`);
  });
  
const logger = require('winston')

logger.remove(logger.transports.Console)
logger.add(new logger.transports.Console({
  format: logger.format.combine(
    logger.format.timestamp(),
    logger.format.colorize(),
    logger.format.printf(event => {
      return `${event.timestamp}: ${event.message}`
    })
  ),
  level: 'silly'
}))

My log:
2023-11-11T01:46:36.571Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:36.580Z: SerialBridge._processQueue: Sending 'sendNetworkStatusNotification' command
2023-11-11T01:46:38.589Z: SerialBridge._processQueue: No response received in time for 'sendNetworkStatusNotification' command
2023-11-11T01:46:38.590Z: SerialBridge.initialize: Failed to send network status notification for 192.168.1.90:23 - No response received
2023-11-11T01:46:38.591Z: AC.getCapabilities: Entering
2023-11-11T01:46:38.592Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:38.592Z: SerialBridge._processQueue: Sending 'getCapabilities' command
2023-11-11T01:46:39.090Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:39.091Z: SerialBridge._processQueue: Command in progress
2023-11-11T01:46:40.606Z: SerialBridge._processQueue: No response received in time for 'getCapabilities' command
2023-11-11T01:46:40.607Z: SerialBridge._write: Retry getCapabilities, 0 retries left
2023-11-11T01:46:41.109Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:41.110Z: SerialBridge._processQueue: Sending 'getCapabilities' command
2023-11-11T01:46:43.113Z: SerialBridge._processQueue: No response received in time for 'getCapabilities' command
2023-11-11T01:46:43.114Z: SerialBridge.initialize: Failed to get capabilities of 192.168.1.90:23 - No response received
2023-11-11T01:46:43.116Z: AC.getStatus: Entering
2023-11-11T01:46:43.116Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:43.117Z: SerialBridge._processQueue: Sending 'getStatus' command
2023-11-11T01:46:43.629Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:43.630Z: SerialBridge._processQueue: Command in progress
2023-11-11T01:46:45.132Z: SerialBridge._processQueue: No response received in time for 'getStatus' command
2023-11-11T01:46:45.133Z: SerialBridge._write: Retry getStatus, 0 retries left
2023-11-11T01:46:45.647Z: SerialBridge._processQueue: Entering
2023-11-11T01:46:45.648Z: SerialBridge._processQueue: Sending 'getStatus' command
2023-11-11T01:46:47.661Z: SerialBridge._processQueue: No response received in time for 'getStatus' command
2023-11-11T01:46:47.662Z: SerialBridge.initialize: Failed to get current status of 192.168.1.90:23 - No response received
Error: Failed to initialize (undefined)

No response received (possibly my adapter?)

Thank you for this amazing repo. I wanted to share my "No response received" error with you, but I'm not sure if it is code or hardware to be honest.

My Hardware
I have a Pioneer WYS024GMFI22RL-10 with a separate OSK-103 Smart Key adapter.

My Mod
I ordered an ESP-01s with a level shifter (dipswitch PROG / UART version) and flashed ESP-Link 2.2.3v and successfully configured it for remote connections. It turns out the USB for my OSK-103 was "keyed" and wouldn't fit in the port. So, I de-soldered the USB port off of my OSK-103, and soldered it to my ESP-01S to USB adapter. After completing the USB transplant, the Pioneer powers on the custom ESP key.

The Problem
I can't seem to successfully control the unit with any repos from Home Assistant / HACS, and the node project I created with your repo keeps giving me "No response received." I'm wondering if the the custom ESP key might need to bypass the built-in USB to TTL adapter that comes with the Pioneer? In other words, maybe it will work if I:

[ESP + Level Shifter] ----> (bypass built-in USB port / TTL adapter) -----> [custom USB cable directly to control board]

Before I mess with code any further, do you happen to know if my hardware config would be problematic?

Typo in README.md

Hi Rene,

you got a typo in the two examples in README.md:
"applicances" instead of "appliances"

Sorry for the lazy-fix method, I thought a PR would have been way too much for such a small change :-D

No Authentication Key and Token

Hi

Midea-discover finds my appliance, but when I try to get an authentication key and token, I get:

  • Authentication Key: An unknown error occurred
  • Authentication Token: An unknown error occurred

The credentials work on the SmartHome App on my Android phone, but the App is now called SmartHome, not MSmartHome any more. Would appreciate a hint!

OSK103 Discovery fail

Hello,
After the update, I'm trying to reconnect my Midea air conditioners with the original OSK103 dongle in NodeRed, I've finally managed to get the discovery function to work halfway (it doesn't want to work under Docker)
However, when I run it, I get the following message:

root@raspberrypi:~# node_modules/.bin/midea-discover --user=[email protected] --password=yyy
/root/node_modules/node-mideahvac/discover.js:167
macAddress: ${data[63 + data[40]].toString(16)}:${data[64 + data[40]].toString(16)}:${data[65 + data[40]].toString(16)}:${data[66 + data[40]].toString(16)}:${data[67 + data[40]].toString(16)}:${data[68 + data[40]].toString(16)},
TypeError: Cannot read properties of undefined (reading 'toString')
at Socket. (/root/node_modules/node-mideahvac/discover.js:167:42)
at Socket.emit (node:events:527:28)
at UDP.onMessage [as onmessage] (node:dgram:922:8)
Node.js v17.9.0

Account or password incorrect, please re-enter (3102)

if use app https://apps.apple.com/ru/app/midea-air/id1007999530 or https://apps.apple.com/us/app/nethome-plus/id1008001920 everything is working and control AC

~/Downloads/node-red ❯ node ~/.node-red/node_modules/node-mideahvac/discover.js --user=USER --password=***
Found 1 appliances:

Appliance 1:
- Id: 20890720943592
- Host: 192.168.0.116
- Port: 6444
- MAC Address: 84:7c:9b:4a:1:39
- Serial No.: 000000P0000000Q1847C9B4A01390000
- Appliance Type: Air Conditioner
- Firmware Version: 3.0.6
- New Encryption Version: true
- UDP Id: 91c8168fe3d27e17c8643716f17e8fb7
2022-05-14T05:45:09.241Z silly: MideaCloudClient._getToken: Entering with udpId = 91c8168fe3d27e17c8643716f17e8fb7
2022-05-14T05:45:09.242Z silly: MideaCloudClient._authenticate: Entering
2022-05-14T05:45:09.242Z silly: MideaCloudClient._getLoginId: Entering with uid = USER
2022-05-14T05:45:09.244Z silly: MideaCloudClient._apiRequest: Entering
2022-05-14T05:45:09.245Z debug: MideaCloudClient._apiRequest: Options = {"method":"POST","path":"/mas/v5/app/proxy?alias=/v1/user/login/id/get","hostname":"mp-prod.appsmb.com","agent":{"_events":{},"_eventsCount":2,"defaultPort":443,"protocol":"https:","options":{"path":null},"requests":{},"sockets":{},"freeSockets":{},"keepAliveMsecs":1000,"keepAlive":false,"maxSockets":null,"maxFreeSockets":256,"scheduling":"lifo","maxTotalSockets":null,"totalSocketCount":0,"maxCachedSessions":100,"_sessionCache":{"map":{},"list":[]}},"timeout":5000,"body":"{\"appId\":\"1010\",\"format\":2,\"clientType\":1,\"language\":\"en_US\",\"src\":\"1010\",\"stamp\":\"20220514084509\",\"reqId\":\"55e5d0b565665f49f1eef54b9db42d05\",\"loginAccount\":\"USER\"}","headers":{"Authorization":"Basic MTAxM********","sign":"816c65a9e5e8fcbef7328254bab4dac1807258d95d75a0ea3ea6f292391c872f","secretVersion":"1","random":"1652507109","Content-Type":"application/json","accessToken":null}}
2022-05-14T05:45:10.251Z debug: dnsLookup: Returning 18.198.115.88 for mp-prod.appsmb.com
2022-05-14T05:45:10.868Z debug: MideaCloudClient._apiRequest: Response {"code":"3102","msg":"Account or password incorrect, please re-enter"}
2022-05-14T05:45:10.870Z error: MideaCloudClient._getLoginId: Account or password incorrect, please re-enter (3102) (UnknownError)
- Authentication Key: An unknown error occurred
- Authentication Token: An unknown error occurred

OSK-105 - Is this also supported? Failed to authenticate

Hey,

I have a Rotenso AC at home that I can control using MSmartHome app. I was trying to use this package to build some automation, but I'm getting Failed to authenticate error

The discover process works and I'm getting authentication keys


Appliance 1:
- Id: 31885837901911
- Host: 192.168.15.114
- Port: 6444
- MAC Address: 3c:20:93:93:12:60
- Serial No.: 0000C331xxxxxxxxxxxxxxxxxx1002849GLL
- Appliance Type: Air Conditioner
- Firmware Version: 8.33.21
- New Encryption Version: true
- UDP Id: f5c03a8834dxxxxxxxxxxxc4bb9aa17f
- Authentication Key: f5c03a8834dxxxxxxxxxxxc4bb9aa17f
- Authentication Token: 38DFB889F783ED24A4A9xxxxxxxxxxxxxxxxxxxxxxxxxxx316166407A9E38A264AE4xxxxxxxxxxxxxxEA240ACC6DA77

Appliance 2:
- Id: 31885837901913
- Host: 192.168.15.115
- Port: 6444
- MAC Address: 3c:20:93:93:13:94
- Serial No.: 0000C331xxxxxxxxxxxxxxxxxx1002849GLL
- Appliance Type: Air Conditioner
- Firmware Version: 8.33.21
- New Encryption Version: true
- UDP Id: f5c03a8834dxxxxxxxxxxxc4bb9aa17f
- Authentication Key: 4142ACFFD260436084C8149C664xxxxxxxxxxxxxxxxxxxxxxxxF546BB73F9507CE
- Authentication Token: 38DFB889F783ED24A4A9xxxxxxxxxxxxxxxxxxxxxxxxxxx316166407A9E38A264AE4xxxxxxxxxxxxxxEA240ACC6DA77

But when trying to connect using this script, it's not working anymore



// This example required the following modules to be installed:
// npm install node-mideahvac

const appliances = require('node-mideahvac');
const logger = require('winston')

logger.remove(logger.transports.Console)
logger.add(new logger.transports.Console({
  format: logger.format.combine(
    logger.format.timestamp(),
    logger.format.colorize(),
    logger.format.printf(event => {
      return `${event.timestamp}: ${event.message}`
    })
  ),
  level: 'silly'
}))

// Specify your specific information (this information can be determined using the midea-discover tool)
const ac = appliances.createAppliance({
  communicationMethod: 'sk103',
  host: '192.168.15.114',
  id: '',
  key: '',
  token: ''
});

// Any updated status properties will be printed
ac.on('status-update', data => {
  console.log(`Received updates: ${JSON.stringify(data)}`);
});

ac.initialize()
  .then(response => {
    console.log('Initialized, start polling');

    // The status will be polled each 30s, when properties are changed these will be emitted as a
    // status-update
    setInterval(() => {
      ac.getStatus()
        .catch(error => {
          console.log(`Error: ${error.message}`);
        });
    }, 30000);
  })
  .catch(error => {
    console.log(error);
    console.log(`Error: Failed to initialize (${error})`);
  });
2022-06-27T22:08:08.697Z: SK103.initialize: Entering
2022-06-27T22:08:08.698Z: AC.getCapabilities: Entering
2022-06-27T22:08:08.699Z: SK103._request: Entering with getCapabilities=xxxx
2022-06-27T22:08:08.699Z: SK103._queueCommand: Entering
2022-06-27T22:08:08.699Z: SK103._processQueue: Entering
2022-06-27T22:08:08.699Z: CALL AUTHNTICXATE
2022-06-27T22:08:08.699Z: SK103._authenticate: Entering
2022-06-27T22:08:08.700Z: SK103._connect: Entering
2022-06-27T22:08:08.706Z: SK103._connect: Connected
2022-06-27T22:08:08.707Z: SK103._encode0x8370: Entering with xxxx and msgType=0
2022-06-27T22:08:08.707Z: SK103._queueCommand: Entering
2022-06-27T22:08:08.707Z: SK103._processQueue: Entering
2022-06-27T22:08:08.707Z: SK103._processQueue: Sending 'authenticate' command
2022-06-27T22:08:08.764Z: SK103._dataHandler: Entering with xxxx
2022-06-27T22:08:08.764Z: SK103._dataHandler: Calling handler for the command 'authenticate' in progress
2022-06-27T22:08:08.764Z: SK103._authenticate: Entering callback
2022-06-27T22:08:08.764Z: SK103._authenticate: Received xxxx
2022-06-27T22:08:08.765Z: SK103._processQueue: Failed to authenticate ERROR
2022-06-27T22:08:08.765Z: SK103._request: Entering callback
2022-06-27T22:08:08.765Z: SK103.initialize: Failed to get capabilities of xxx - Failed to authenticate
2022-06-27T22:08:08.765Z: AC.getStatus: Entering
2022-06-27T22:08:08.765Z: SK103._request: Entering with getStatus=xxx
2022-06-27T22:08:08.765Z: SK103._queueCommand: Entering
2022-06-27T22:08:08.765Z: SK103._processQueue: Entering
2022-06-27T22:08:08.765Z: CALL AUTHNTICXATE
2022-06-27T22:08:08.765Z: SK103._authenticate: Entering
2022-06-27T22:08:08.765Z: SK103._connect: Entering
2022-06-27T22:08:08.771Z: SK103._connect: Connected
2022-06-27T22:08:08.771Z: SK103._encode0x8370: Entering with xxx and msgType=0
2022-06-27T22:08:08.771Z: SK103._queueCommand: Entering
2022-06-27T22:08:08.771Z: SK103._processQueue: Entering
2022-06-27T22:08:08.771Z: SK103._processQueue: Sending 'authenticate' command
2022-06-27T22:08:08.875Z: SK103._dataHandler: Entering with xxxx
2022-06-27T22:08:08.875Z: SK103._dataHandler: Calling handler for the command 'authenticate' in progress
2022-06-27T22:08:08.876Z: SK103._authenticate: Entering callback
2022-06-27T22:08:08.876Z: SK103._authenticate: Received xxxx
2022-06-27T22:08:08.876Z: SK103._processQueue: Failed to authenticate ERROR
2022-06-27T22:08:08.876Z: SK103._request: Entering callback
2022-06-27T22:08:08.876Z: SK103.initialize: Failed to get current status of xxxx - Failed to authenticate
<ref *1> DerivedLogger {
  _readableState: ReadableState {
    objectMode: true,
    highWaterMark: 16,
    buffer: BufferList { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [
      [Console],
      [Console],
      [Console],
      [Console],
      [Console],
      [Console],
      [Console]
    ],
    pipesCount: 7,
    flowing: true,
    ended: false,
    endEmitted: false,
    reading: false,
    sync: false,
    needReadable: true,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    paused: false,
    emitClose: true,
    autoDestroy: false,
    destroyed: false,
    defaultEncoding: 'utf8',
    awaitDrain: 0,
    readingMore: true,
    decoder: null,
    encoding: null
  },
  readable: true,
  _events: [Object: null prototype] {
    prefinish: [Function: prefinish],
    end: [
      [Function],
      [Function],
      [Function],
      [Function],
      [Function],
      [Function],
      [Function]
    ],
    data: [
      [Function: ondata],
      [Function: ondata],
      [Function: ondata],
      [Function: ondata],
      [Function: ondata],
      [Function: ondata],
      [Function: ondata]
    ]
  },
  _eventsCount: 3,
  _maxListeners: undefined,
  _writableState: WritableState {
    objectMode: true,
    highWaterMark: 16,
    finalCalled: false,
    needDrain: false,
    ending: false,
    ended: false,
    finished: false,
    destroyed: false,
    decodeStrings: true,
    defaultEncoding: 'utf8',
    length: 0,
    writing: false,
    corked: 0,
    sync: false,
    bufferProcessing: false,
    onwrite: [Function (anonymous)],
    writecb: null,
    writelen: 0,
    bufferedRequest: null,
    lastBufferedRequest: null,
    pendingcb: 0,
    prefinished: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: false,
    bufferedRequestCount: 0,
    corkedRequestsFree: CorkedRequest {
      next: null,
      entry: null,
      finish: [Function (anonymous)]
    }
  },
  writable: true,
  allowHalfOpen: true,
  _transformState: {
    afterTransform: [Function: bound afterTransform],
    needTransform: true,
    transforming: false,
    writecb: null,
    writechunk: null,
    writeencoding: 'utf8'
  },
  silent: undefined,
  format: Format { options: {} },
  defaultMeta: null,
  levels: {
    error: 0,
    warn: 1,
    info: 2,
    http: 3,
    verbose: 4,
    debug: 5,
    silly: 6
  },
  level: 'info',
  exceptions: ExceptionHandler { logger: [Circular *1], handlers: Map(0) {} },
  rejections: RejectionHandler { logger: [Circular *1], handlers: Map(0) {} },
  profilers: {},
  exitOnError: true,
  [Symbol(kCapture)]: false
}
Error: Failed to initialize ([object Object])
2022-06-27T22:08:09.266Z: SK103._processQueue: Entering
2022-06-27T22:08:09.267Z: DISCONNECT BECAUSE MPTY QUEUE
2022-06-27T22:08:09.268Z: SK103._processQueue: No queued commands
2022-06-27T22:08:09.269Z: SK103._connect: Connection closed
2022-06-27T22:08:09.377Z: SK103._processQueue: Entering
2022-06-27T22:08:09.377Z: DISCONNECT BECAUSE MPTY QUEUE
2022-06-27T22:08:09.377Z: SK103._processQueue: No queued commands
2022-06-27T22:08:38.785Z: SK103._connect: Disconnect received from appliance
2022-06-27T22:08:38.788Z: SK103._connect: Connection closed

Am I assuming right that API for OSK-105 is different than for the OSK-103 and it won't work unless I replace the module?

Invalid data length (19)

- Id: 20890720943592
- Host: 192.168.0.116
- Port: 6444
- MAC Address: 84:7c:9b:4a:****
- Serial No.: 000000P00000************
- Appliance Type: Air Conditioner
- Firmware Version: 3.0.6
- New Encryption Version: true
- UDP Id: 91c8168fe3d27e17c8643716********
2022-05-28T02:45:17.074Z info: SK103._request: Entering with getStatus=aa20ac00000000000003418100ff03ff000200000000000000000000000003cd9c
2022-05-28T02:45:17.074Z debug: SK103._processQueue: Entering
2022-05-28T02:45:17.075Z debug: SK103._processQueue: Sending 'getStatus' command
2022-05-28T02:45:17.729Z debug: SK103._dataHandler: Entering with 8370007e206356ac9033057da1551bad6383a9596999f3679ee090da9875129fe11b5e596997f494ff089c08f7166568df7d1176f30c5118f7cd4a494366a098d1e6b4728a9ef1bd07decaf3521d28ed719546d7ab6fbba987df061d9463bb82993c0e64b1da7f7d5a1707f1c4714bf49dd27501257fac9d9bdc632929398359bd35635112fe
2022-05-28T02:45:17.730Z debug: SK103._dataHandler: Calling handler for the command 'getStatus' in progress
2022-05-28T02:45:17.730Z debug: SK103._decode: Entering with 8370007e206356ac9033057da1551bad6383a9596999f3679ee090da9875129fe11b5e596997f494ff089c08f7166568df7d1176f30c5118f7cd4a494366a098d1e6b4728a9ef1bd07decaf3521d28ed719546d7ab6fbba987df061d9463bb82993c0e64b1da7f7d5a1707f1c4714bf49dd27501257fac9d9bdc632929398359bd35635112fe
2022-05-28T02:45:17.730Z debug: SK103._request: Entering callback
2022-05-28T02:45:17.730Z debug: C0.parser: Entering with c0008c507f7f00000000006140000000000000 - 19
2022-05-28T02:45:17.731Z error: C0.parser: Invalid data length (19)
2022-05-28T02:45:17.731Z debug: AC._updateStatus: Entering with {}

Problem with Rotenso AC

I have a Rotenso AC at home that I can control using MSmartHome app. I was trying to discover Key/Token pair but I got following results:

Appliance 1:

  • Id: 146235046505367
  • Host: 192.168.0.235
  • Port: 6444
  • MAC Address: d4:84:57:4a:62:90
  • Serial No.: 000000P0000000Q1D484574A62900000
  • Appliance Type: Air Conditioner
  • Firmware Version: 9.33.34
  • New Encryption Version: true
  • UDP Id: 42aaadaf7bxxxxxx2b832b2fdb2f3952
  • Authentication Key: An unknown error occurred
  • Authentication Token: An unknown error occurred

Any ideas whats then?

Status feedback SerialBridge

Hello,
I switched over in the meantime and use the whole thing with the serial bridge. I control the whole thing via NodeRed, but I have problems or I don't get any "feedback". I can switch on and control the air conditioning, but there is no status back via the module... Do I have to set or "request" something?

TypeScript typedefs

Hello, first off thanks for this project, however I would like to ask whether you have any plans to add type definitions for typescript?

Code snippet from README.md throws an error

Hi,

I have to admit, that I am a total novice to nodejs and I am not used to how things work with it ;-)
I tried to put together some lines of code to control the AC, like in the example and in README.md:

const appliances = require('node-mideahvac')

var options = {
    communicationMethod: 'serialbridge',
    host: '192.168.42.126',
    port: 23
}

var ac = new appliances.createAppliance(options)



ac.on('status-update', data => {
  console.log(`Received updates: ${JSON.stringify(data)}`)
})

ac.initialize()
  .then(response => {
    console.log(`Initialized: ${JSON.stringify(response)}`)

    setInterval(() => {
      ac.getStatus()
        .catch(error => {
          console.log(`Error: ${error.message}`)
        })
    }, 30000)
  })
  .catch(error => {
    console.log(`Error: Failed to initialize (${error.message})`)
  })

ac.setStatus({ powerOn: true, setpoint: 24 }, true, true)
  .catch(error => {
    console.log(error.message)
  })

if I start this code I get the following error:

var ac = new appliances.createAppliance(options)
         ^

TypeError: appliances.createAppliance is not a constructor
    at Object.<anonymous> (/home/fhem/midea-ac/serial.js:9:10)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)

What did I do wrong?

Should it works with Qlima SC5248 ?

May be , it s me or it s not compatible.
I'm not an expert with ESP module but I think I ve done the correct setup.

I bought : https://www.amazon.fr/gp/product/B07Y8JZNCQ/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
i've flash with esp-link V2.2.3 ( and 3.0.14 to test)
I can connect to the esp-link web page and configure wifi and other params (perhaps it s something there)

but , after that , I think i 'skip' something.
if I run the serialbridge sample (and yes I put my ip and port ;) ) and go step by step in visual studio code
the connect step is ok , but the following operation catch error "No response receive".

Capture d’écran 2020-09-16 à 21 51 37

If I look at the "Microcontroller Console" on the esp web interface, nothing appears.
and in the debug console , I get "286732> Accept port 23, conn=0x3fff7580, pool slot 0"
Capture d’écran 2020-09-16 à 21 50 13
Capture d’écran 2020-09-16 à 21 50 27
Capture d’écran 2020-09-16 à 21 50 52

getStatus, getPowerUsage and getCapabilities error request

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.