Управление лампой Xiaomi Smart LED Lamp E14 Bulb (Philips) в домотикзе

Купить можно на алиэкспресс.
Предлагаемый тут метод позволяет включать/выключать лампу и отображает текущее состояние лампы.
Управление яркостью и температурой мне не нужно, поэтому я это не делал, но в скрипте есть все необходимые заготовки и при небольшой доработке можно прикрутить и яркость и оттенок а при желании и даже сцены.

Инструкцию пишу по памяти, когда уже всё давно настроено и работает, возможно некоторые мелкие нюансы подзабыл и не описал.
Источник информации: 4pda.ru

0. Подготовка


Необходим компонент: python-miio, и команда из его состава miceil .
Для проверки, можно запустить эту команду в консоли, и если все хорошо, должно выдать что-то похожее:

miceil
You have to give ip and token!

Если python-miio не установлен, устанавливаем его командой:

sudo pip3 install python-miio

Или по инструкции.

1. Сбор информации


Также, нам обязательно понадобится IP адрес и токен лампы. 
IP адрес - задаем статичный адрес на маршрутизаторе (обычно где-то в настройках DHCP)
Вариантов получения токена несколько:
    1 - сбросить лампу, и запустить команду 
        miio discover  
        (у меня лампа привязана к MiHome, отвязывать не хотелось, поэтому я этот способ не проверял)
    2 - получить токен из базы данных MiHome старой версии по инструкции. Внимание: токен не может состоять полностью из одних нулей!

2. Настройка домотикза


2.1 Создаем виртуальное (dummy) устройство с типом "переключатель" (switch) и запоминаем имя которое ему присвоили (я назвал его Lampa).

2.2 Создаем dzVents скрипт, в котором подставляем IP адрес лампы, токен лампы, и имя виртуального переключателя лампы (в скрипте имя датчика Lampa встречается два раза).
Для удобства, я выделил разными цветами то что надо менять.

-- PhilipsLampE14

return {
 on = {
  timer = {'every minute'},
  devices = {'Lampa'}     -- Device name
 },
 logging = {
  level = domoticz.LOG_ERROR
 },
 execute = function(dz, item)

  local Device   = dz.devices('Lampa')      -- dummy switch - type:Selector Switch
  local IP    = '192.168.0.77'        -- Device IP
  local Token    = 'a967827d6160f4678c432b78bbaac210'   -- token

function GetStatus()
 cmd = "miceil --ip "..IP.." --token "..Token.." status"
 --dz.utils.osExecute('('..cmd..' > /dev/null)&')
end

function PowerOn()
 cmd = "miceil --ip "..IP.." --token "..Token.." on"
 dz.utils.osExecute('('..cmd..' > /dev/null)&')
end

function PowerOff()
 cmd = "miceil --ip "..IP.." --token "..Token.." off"
 dz.utils.osExecute('('..cmd..' > /dev/null)&')
end

--[[
function SetBrightness(brightness)
 cmd = "miceil --ip "..IP.." --token "..Token.." set_brightness "..brightness
 dz.utils.osExecute('('..cmd..' > /dev/null)&')
end

function SetColorTemperature(temperature)
 cmd = "miceil --ip "..IP.." --token "..Token.." set_color_temperature "..temperature
 dz.utils.osExecute('('..cmd..' > /dev/null)&')
end
]]--

function parseInt(str)
 local retValue = 0
 if (str ~= nil and str ~= '') then
  _, _, num = string.find(str, "(%d+)")
  --print('num='..num)
  retValue = tonumber(num)
 end
 return retValue
end

function parseDec(str)
 local retValue = 0.0
 if (str ~= nil and str ~= '') then
  _, _, num1, num2 = string.find(str, "(%d+)[^%d]+(%d+)")
  --print('num1='..num1)
  --print('num2='..num2)
  retValue = tonumber(num1.."."..num2)
 end
 return retValue
end



  if (item.isDevice) then
   if (item.state == 'On') then
    PowerOn()
   else
    PowerOff()
   end
  end
  
  if (item.isTimer) then
   GetStatus()
   --print('cmd='..cmd)
   
   local h  = io.popen(cmd)
   local response = h:read("*a")
   h:close()
   --print('response='..response)
   
--[[
Power: on
Brightness: 1
Color temperature: 1
Scene: 0
Smart Night Light: False
Auto CCT: False
Countdown of the delayed turn off: 0 seconds

??? Error: Unable to discover the device...
--]]
   
   if (response == nil or response == '' or string.find(response, 'Error: Unable to discover the device')) then
    response = ''
   else 
    
    t = {}
    for k, v in string.gmatch(response, "(%w+):%s(.-)\n") do
     t[k] = v
     --print('# '..k..'='..v)
    end
    
    strState    = t['Power']   -- состояние
    --strBrightness  = t['Brightness']   -- яркость
    --strTemperature = t['temperature']   -- оттенок

    -- состояние
    if (strState == nil or strState == '') then
     State = -1
    else
     if (strState == 'on') then
      State = 1
     else
      State = 0
     end
    end
    
    --Brightness   = parseInt(strBrightness)
    --Temperature  = parseInt(strTemperature)
    --print('PhilipsLamp State='..State..';')
    
    if (State == 1) then
     if (Device.state ~= 'On') then
      Device.switchOn().checkFirst().silent()
     end
    elseif (State == 0) then
     if (Device.state ~= 'Off') then
      Device.switchOff().checkFirst().silent()
     end
    elseif (State == -1) then
     print('PhilipsLamp Не удалось узнать состояние устройства')
    end
   end
  end
 end
}


UPDATE 2022-01-03:
В последней версии python-miio статус лампы получается командой:

/usr/local/bin/miiocli philipsbulb --ip 192.168.1.55 --token 1234567890987654321 status


Комментарии

  1. Не знаю как с E14, но с E27 у меня были проблемы (используя этот скрипт).
    Иногда лампа не включалась, потому что запрос не отрабатывался корректно + какие то задержки в обработке и тогда ругался сам домотикз
    По умолчанию, если домотикз скрипт требует на обработку более 10 сек. то это ошибка.
    Пришлось делать на bash свои скрипты с разной логикой обхода ошибок и добавлять уже в сценарий.
    Теперь работает отлично.
    А так, статья отличная, все нужные ссылки для понимания как работать с лампами нашёл, но сделал по своему.

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения