12.10.2021, 11:32
Many thanks to admin to make it working again
Code:
--[[
https://www.npmjs.com/package/homebridge-dyson-pure-cool
https://github.com/lukasroegner/homebridge-dyson-pure-cool
9-10-2021
Sniff passwords with an Android phone and the Dyson link app and Netcapture (also sniff SSL traffic).
You receive data like this and fill them inside the dyson devices (theres a X between username/serial and the password):
.MQTT.<paho3949609190773A1B-EU-MKA0000AXn0MYFEYNRMCk7n9nCxW/F3bDFGQuLtBjQy3W4rg46ZqPc0+wkqqSVTdSVXXXXQnxc2NqgbQPABzbCe81xWQ==
--]]
local json = require('json')
debug = false
-- product types
DYSON_PURE_COOL_LINK_TOUR = '475'
DYSON_PURE_COOL_LINK_DESK = '469'
DYSON_PURE_HOT_COOL_LINK_TOUR = '455'
DYSON_360_EYE = 'N223'
DYSON_PURE_HOT_COOL_2018 = '527' --HP04 Dyson Pure Hot+Cool 2018 (244289-01)
CMD_ON = { fpwr = 'ON' }
CMD_OFF = { fpwr = 'OFF' }
CMD_AUTO_ON = { auto = 'ON' }
CMD_AUTO_OFF = { auto = 'OFF' }
CMD_NIGHT_ON = { nmod = 'ON' }
CMD_NIGHT_OFF = { nmod = 'OFF' }
CMD_HEAT_ON = { hmod = 'HEAT' }
CMD_HEAT_OFF = { hmod = 'OFF' }
function CMD_HEAT(iTemp) -- in graden celcius
return ({ hmax = tostring(2932+((iTemp-20)*10)) }) --2912=18 2932=20 2952=22 2982=25 3012=28 enz
end
-- all dyson devices
dysons = {} -- room(not used), ip, port(default 1883), type, username/serial, password
dysons[1] = {'Room 1 ', '192.168.0.14', 1883, DYSON_PURE_HOT_COOL_2018, 'A1B-EU-MKA0000A', 'n0MYFEYNRMCk7n9nCxW/F3bDFGQuLtBjQy3W4rg46ZqPc0+wkqqSVTdSVXXXXQnxc2NqgbQPABzbCe81xWQ=='}
-- debug logger
function debugLog(iLog)
if debug then
log(iLog)
end
end
-- send data to dyson
function mqsend(ip, username, password, prefix, cmddata)
local function datetime()
return os.date('!%Y-%m-%dT%H:%M:%SZ')
end
local ts, tu = os.microtime()
local clientid = 'lm-' .. ts .. '-' .. tu
local mq = require('mosquitto').new(clientid)
mq:login_set(username, password)
mq.ON_CONNECT = function(res, ...)
debugLog('mqtt connect status', res, ...)
if res then
local topic = prefix .. '/command'
local cmd = {
f = topic,
time = datetime(),
msg = 'STATE-SET',
data = cmddata,
['mode-reason'] = 'LAPP',
}
mq:publish(topic, json.encode(cmd), 1)
else
mq:disconnect()
end
end
mq.ON_PUBLISH = function(mid, rc)
debugLog('published', mid, rc)
mq:disconnect()
end
mq.ON_DISCONNECT = function(...)
debugLog('mqtt disconnect', ...)
end
mq.ON_LOG = function(...)
debugLog(...)
end
local res, rc, errno = mq:connect(ip)
if not res then
debugLog('connect failed', rc, errno)
return
end
-- process mqtt messages
for i = 1, 20 do
local res, err = mq:loop()
if not res then
break
end
end
end
-- receive current dyson state
function mqstatus(ip, username, password, prefix)
local function datetime()
return os.date('!%Y-%m-%dT%H:%M:%SZ')
end
local ts, tu = os.microtime()
local clientid = 'lm-' .. ts .. '-' .. tu
local mq = require('mosquitto').new(clientid)
local count = 0
local status = {}
mq:login_set(username, password)
mq.ON_CONNECT = function(res, ...)
log('mqtt connect status', res, ...)
if res then
local cmd = {
time = datetime(),
msg = 'REQUEST-CURRENT-STATE',
}
mq:subscribe(prefix .. '/status/current')
mq:publish(prefix .. '/command', json.encode(cmd))
else
mq:disconnect()
end
end
mq.ON_MESSAGE = function(rc, topic, payload)
payload = json.pdecode(payload)
if type(payload) ~= 'table' then
return
end
local data
if payload.msg == 'CURRENT-STATE' then
data = payload['product-state']
elseif payload.msg == 'ENVIRONMENTAL-CURRENT-SENSOR-DATA' then
data = payload['data']
end
if type(data) == 'table' then
for key, value in pairs(data) do
if value:match('^%d+$') then
value = tonumber(value)
end
status[ key ] = value
end
count = count + 1
end
if count == 2 then
mq:disconnect()
end
end
mq.ON_DISCONNECT = function(...)
debugLog('mqtt disconnect', ...)
end
local res, rc, errno = mq:connect(ip)
if not res then
debugLog('connect failed', rc, errno)
return
end
-- process mqtt messages
for i = 1, 20 do
local res, err = mq:loop()
if not res then
break
end
end
debugLog(status)
return status
end
-- run dyson command
function runCommand(IDevice, iCmd)
broker = dysons[IDevice][2]
port = dysons[IDevice][3]
producttype = dysons[IDevice][4]
username = dysons[IDevice][5]
password = dysons[IDevice][6]
mqsend(
broker,
username,
password,
producttype..'/'..username,
iCmd
)
end
-- runCommand(1,CMD_OFF)
-- get dyson command
function getState(IDevice)
broker = dysons[IDevice][2]
port = dysons[IDevice][3]
producttype = dysons[IDevice][4]
username = dysons[IDevice][5]
password = dysons[IDevice][6]
return mqstatus(
broker,
username,
password,
producttype..'/'..username
)
end
-- log(getState(1))