Завтракаем среди красок погоды.

Хорошая привычка, чтобы начать день с правильной ноги, — встать с постели и включить мягкий свет по дому. С помощью RGB-лампы или цветной светодиодной ленты вы можете выбрать цвет освещения комнаты с прогнозом погоды, чтобы сочетать эффект приятного мягкого и динамичного цветного света с настроением дня.

Предпосылки и ингредиенты.

  • Цветная лампа или rgb-полоска, управляемая сервером домашней автоматизации (в моем случае я использую rgb-полоски, подключенные к очень хорошему Shelly RGBW2)
  • сервер домашней автоматизации, куда вставить логику преобразования цвета, в моем случае я использую Openhab (посмотрите мой пост на Openhab)
  • плагин на сервере домашней автоматизации, позволяющий выполнять скрипты Javascript (JSScripting)
  • бесплатная регистрация на погодном провайдере для соответствующего ApiKey.
  • плагин или поставщик данных о погоде, в моем случае я использую бесплатный плагин Openhab под названием OpenWeatherMap Binding. Плагин должен быть настроен с помощью ApiKey провайдера и должны быть созданы элементы Item, связанные с переменными Облачность, Дождь, Снег.

Давайте подберем цвета

Для начала давайте сопоставим цвета с прогнозом погоды, чтобы вы могли сразу получить ясное и интуитивное представление о погодных условиях, просто взглянув на цвет. Это лишь одна из возможных комбинаций, которые можно составить, если у вас есть предложения, пишите их в комментариях!

  • Для дождя, очевидно, идея состоит в том, чтобы перейти от светло-голубого к сплошному синему для сильного дождя, к фиолетовому в случае грозы с ударами молнии в теме.
  • В случае ясного дня мы обязательно начнем с приятного желтого цвета.
  • По мере увеличения облачности этот цвет может измениться на серый.

Координаты ВПГ

Транскрипция этой логики при работе с координатами RGB может быть сложной, поскольку для сопоставления процента облачности или количества дождя с желаемыми цветовыми шкалами нам пришлось бы найти математические функции, которые не являются интуитивно понятными. Как учит нас инженерия, когда дела идут плохо, необходима смена координат! Для идентификации цветов существует не только кодирование RGB, в котором каждое измерение является одним из трех основных цветов: красного, зеленого и синего. Другая кодировка, которая очень удобна в этом случае, — HSV или HSB, пространство значений которой мы можем представить в виде цилиндра, имеющего на верхней окружности различные оттенки (отождествляемые с градусами от 0 до 360), которые исчезают к центру. верхнюю базу за счет уменьшения насыщенности (в процентах). Внизу основание черное, а в продольном направлении мы можем измерить яркость (в процентах).

Цвета

Сценарий

Нам нужно перенести эту логику на наш сервер домашней автоматизации. В моем случае я выбрал сценарий JavaScript (ECMA 262 Edition 11). Элементы, на которые я ссылаюсь в коде и которые уже должны присутствовать:

  • те, которые связаны с погодой, в моем случае я выбрал 6-часовой прогноз: LocalWeatherandForecast_ForecastedWeatherCondition6H, LocalWeatherandForecast_ForecastedCloudiness, LocalWeatherandForecast_ForecastedRain, LocalWeatherandForecast_ForecastedSnow. * Элемент, связанный с цветом нашей лампы LightRgbSounce_Color.

Вот сценарий:

// compatibility with older Openhab script
var runtime = require("@runtime");
var itemRegistry =runtime.itemRegistry, events=runtime.events, HSBType=runtime.HSBType, rules=runtime.rules;

// some functions
var randomColor =function(){
  return (Math.random()*360).toString() +","+((Math.random()*50)+50).toString() +"," + ((Math.random()*50)+50).toString()
}
var hsvColor =function(h,s,v){
  return h.toString() +","+s.toString() +"," + v.toString()
}
var hsvColorRandomIntensity =function(h){
  var intensity=Math.random()*50+50; return h.toString() +","+"100" +"," + intensity.toString()
}

// prende in input:
// minGradoColore numero da 0 a 360 che indica nella scala HSV il minimo valore da considerare per un intervallo di colori (quindi il colore scelto nel caso il valore sia minimo)
// maxGradoColore numero da 0 a 360 che indica nella scala HSV il minimo valore da considerare per un intervallo di colori (quindi il colore scelto nel caso il valore sia uguale o superiore al maxValore)
// maxValore numero da 0 a INF che indica il massimo che può raggiungere valore
// valore numero da 0 a INF che indica il valore attuale e che viene considerato fino a maxValore
// ritorna un valore da 0 a 360 (da minGradoColore a maxGradoColore) che indica il valore rapportato al maxValore nell'intervallo fra maxGradoColore e minGradoColore
var calcolaTinta = function(minGradoColore, maxGradoColore, maxValore, valore){
  valore =  valore<=maxValore ? valore : maxValore;
  valore = valore >= 0 ? valore : 0;
  return (valore*1.0/maxValore)*(maxGradoColore-minGradoColore)+minGradoColore;
};

// recupero dei valori del meteo
var previsioni = items.getItem("LocalWeatherandForecast_ForecastedWeatherCondition6H").getState()+"";
var cloudiness = items.getItem('LocalWeatherandForecast_ForecastedCloudiness').rawState.floatValue()/100.0;// 0 to 1 
var rain = items.getItem('LocalWeatherandForecast_ForecastedRain').rawState.floatValue(); // 0 to inf
var snow = items.getItem('LocalWeatherandForecast_ForecastedSnow').rawState.floatValue() ; // 0 to inf

// stampa nei log dei dati attuali
console.info("triggered rule " + 'org.openhab.rule.' + ctx.ruleUID)
console.info(JSON.stringify({cloudiness:cloudiness, rain:rain, snow:snow, previsioni:previsioni}));

// scelgo il colore in base al meteo
var color = hsvColor(0,0,100 ); // di default è bianco
if (snow > 0){
  var minSnow = 0;
  var maxSnow = 20;
  var limiteSnow = 2.0;
  
  color = hsvColorRandomIntensity(calcolaTinta(minSnow, maxSnow, limiteSnow, snow),100);
  console.info("dal meteo imposto il colore per NEVE: " + color);
} else if (rain > 0.04){
  var minRain = 160;
  var maxRain = 280;
  var limiteRain = 3.0;
  
  color = hsvColorRandomIntensity(calcolaTinta(minRain, maxRain, limiteRain, rain),100);
  console.info("dal meteo imposto il colore per PIOGGIA: " + color);
} else if (cloudiness > 0.04){
  var minCloud = 95;
  var maxCloud = 95;
  var limiteCloud = 1.0;
  
  var saturation = 100-cloudiness*50.0;
  color = hsvColorRandomIntensity(calcolaTinta(minCloud, maxCloud, limiteCloud, cloudiness),saturation);
  console.info("dal meteo imposto il colore per NUVOLOSO: " + color);
} else {
  var minSun = 35;
  var maxSun = 45;
  var limiteSun = 0.04;
  
  color = hsvColorRandomIntensity(calcolaTinta(minSun, maxSun, limiteSun, cloudiness),100);
  console.info("dal meteo imposto il colore per SOLE: " + color);
}

// impostiamo il colore e accendiamo la luce!
events.sendCommand("LuceRgbSoggiorno_Color", color); 
events.sendCommand("LuceRgbSoggiorno_Color", "ON");

Применение

После того, как сценарий протестирован, остается только вызвать его или сопоставить с домашними сценариями.

  • вы можете вызвать скрипт после нажатия кнопки физического сценария, поэтому утром, нажав на дневной сценарий, можно было бы вызвать логику, мягко подсветив дом (я уже обсуждал это здесь)
  • можно использовать время Openhab, чтобы запускать его в заранее определенное время дня, например, на восходе солнца.
  • вы можете вызвать его после другого события, такого как включение лампы или прибора
  • вы можете запустить сценарий из голосовых помощников Google Home или Amazon Alexa, создав элемент в Openhab, опубликованный на облачных платформах (если вам интересна эта тема, я мог бы написать статью, дайте мне знать в Комментарии)