Код элемента весьма большой. Его раздувают несколько картинок векторной графики, но сложного в нем ничего нет.
Нужно найти и заменить все _114 на свой номер элемента, или на что то жутко уникальное для всего сайта.
Объект.Свойства:
weather_now.image - код картинки
weather_now.temperature - температура
weather_now.windSpeed - скорость ветра
weather_now.windDirection - направление ветра
weather_now.humidity - влажность
weather_now.pressure - давление
today_day.temperature - прогноз температуры на день
today_night.temperature - прогноз температуры на ночь
weather_now.yesterday_text - сравнение со вчера
Код: Выделить всё
<style>
div.element_114 {
border-radius:10px;
padding:5px;
width:110px;
height:120px;
background: linear-gradient(135deg, rgba(100,160,220,1) 1%,rgba(170,230,280,1) 100%);
}
</style>
<script>
var r, t, f;
// Направление ветра
t="%weather_now.windDirection%";
f='#231F20';
r=0;
switch (t.toLowerCase()) {
case 's': case 'ю': r=0; t='южный'; break;
case 'sw': case 'юз': r=45; t='Ю-З'; break;
case 'w': case 'з': r=90; t='Зап'; break;
case 'nw': case 'сз': r=135; t='С-З'; break;
case 'n': case 'с': r=180; t='Сев'; break;
case 'ne': case 'св': r=225; t='С-В'; break;
case 'e': case 'в': r=270; t='Вост'; break;
case 'se': case 'юв': r=315; t='Ю-В'; break;
case 'calm': case 'штиль': f='transparent'; t='штиль'; break;
}
document.getElementById('e_114_wind_arrow').setAttribute('transform', 'rotate(' + r + ')');
document.getElementById('e_114_wind_arrow').setAttribute('fill', f);
document.getElementById('e_114_wind_text').innerHTML = t;
</script>
<!-- Картинка -->
<img width="40" height="40" style="position:absolute" src="/images/weather_yandex_v3/%weather_now.image%.png" >
<svg width="100%" height="100%">
<!-- Градусы -->
<text x="43" y="30" fill="black" stroke="none" font-size="24px">%weather_now.temperature%℃</text>
<!-- Ветер -->
<g transform="translate(-1, 56)" >
<text x="25" y="0" fill="black" stroke="none" font-size="12px">%weather_now.windSpeed%мс</text>
<g transform="scale(0.4) translate(-5, -42)">
<path fill="#231F20" d="M57.174,22.839c-1.747-2.43-4.421-4.235-7.33-4.954c-0.976-0.251-1.994-0.379-3.025-0.379
c-2.12,0-4.092,0.558-5.696,1.608c-2.588,1.629-4.359,4.396-4.736,7.383c-0.496,3.06,0.801,6.309,3.221,8.082
c1.389,1.051,3.212,1.653,5.001,1.653c1.348,0,2.594-0.333,3.599-0.959c2.746-1.653,3.952-5.254,2.689-8.028
c-0.648-1.41-1.917-2.509-3.393-2.937c-0.434-0.128-0.874-0.199-1.311-0.214l-0.053,0.999c0.363,0.026,0.72,0.1,1.063,0.221
c1.156,0.394,2.121,1.304,2.582,2.443c0.231,0.547,0.348,1.142,0.335,1.72c-0.013,0.629-0.121,1.207-0.341,1.813
c-0.435,1.144-1.281,2.145-2.331,2.752c-1.888,1.146-4.895,0.796-6.834-0.767c-1.913-1.522-2.855-4.021-2.457-6.532
c0.331-2.466,1.811-4.727,3.964-6.051c1.021-0.646,2.219-1.067,3.469-1.22c0.519-0.066,1.217-0.076,1.891-0.024
c0.643,0.057,1.293,0.166,1.881,0.315c2.456,0.632,4.711,2.181,6.19,4.257c1.538,2.082,2.266,4.589,2.103,7.258
c-0.108,2.592-0.997,5.204-2.504,7.358c-1.5,2.162-3.66,3.926-6.087,4.969c-1.114,0.488-2.403,0.841-3.83,1.047
c-0.883,0.125-1.831,0.147-2.979,0.164l-32.375,0.43l-5.482,0.214l0.02,1l36.59,0.024c0.422,0,0.845,0,1.265,0.004l0.782,0.005
c0.705,0,1.54-0.013,2.388-0.109c1.537-0.19,2.99-0.572,4.314-1.134c2.744-1.141,5.2-3.108,6.914-5.539
c1.733-2.428,2.771-5.398,2.922-8.354C59.805,28.331,58.923,25.225,57.174,22.839z"/>
<path fill="#231F20" d="M23.979,42.956c0.122-0.005,0.269-0.007,0.41-0.007l1.001,0.012c0.281,0.005,0.544,0.009,0.808,0.009
c0.515,0,1.197-0.014,1.919-0.119c1.402-0.229,2.73-0.822,3.836-1.712c2.275-1.793,3.47-4.78,3.045-7.61
c-0.436-2.877-2.933-5.276-5.8-5.58c-1.57-0.193-3.019,0.18-4.119,1.033c-1.186,0.887-1.965,2.223-2.135,3.648
c-0.226,1.485,0.332,3.05,1.409,3.978c1.067,0.972,2.837,1.366,4.116,0.926c0.938-0.313,1.732-1.066,2.126-2.017l-0.906-0.42
c-0.334,0.647-0.937,1.126-1.611,1.279c-0.224,0.051-0.426,0.075-0.619,0.075c-0.796,0-1.611-0.343-2.131-0.899
c-0.705-0.736-0.965-1.675-0.753-2.714c0.192-0.934,0.792-1.858,1.562-2.413c0.818-0.584,1.707-0.788,2.822-0.626
c2.045,0.265,3.788,2.012,4.059,4.087c0.367,2.084-0.529,4.415-2.238,5.807c-0.843,0.711-1.874,1.194-2.985,1.398
c-0.454,0.088-0.905,0.105-1.406,0.118L7.175,41.715c-0.911,0.08-1.854,0.149-2.798,0.218l0.035,0.999L23.979,42.956z"/>
</g></g>
<!-- направление ветра -->
<g transform="translate(55, 56)" >
<text id="e_114_wind_text" x="20" y="0" fill="black" stroke="none" font-size="12px" />
<g transform="translate(11, -3)">
<path id="e_114_wind_arrow" d="M0,-6 l-4,12 l4,-3 l4,3 z"/>
</g></g>
<!-- Влажность -->
<g transform="translate(55, 78)" >
<text x="20" y="0" fill="black" stroke="none" font-size="12px">%weather_now.humidity%%</text>
<g transform="scale(0.04) translate(120,-280)">
<path d="M264.412,147.72c-27.014-36.93-54.944-75.132-57.594-112.3L204.309,0l-25.456,24.748
c-46.365,45.045-115.13,161.197-115.13,229.329c0,69.852,56.81,126.645,126.638,126.645c69.834,0,126.638-56.793,126.638-126.645
C316.998,219.604,291.448,184.685,264.412,147.72z M190.36,347.701c-51.622,0-93.623-41.989-93.623-93.624
c0-45.51,43.163-130.698,84.357-182.395c11.717,34.066,35.263,66.267,56.664,95.529c23.771,32.491,46.207,63.188,46.207,86.866
C283.966,305.711,241.977,347.701,190.36,347.701z"/>
<path d="M163.533,300.831c-2.835-2.939-5.438-6.332-8.011-9.853c-2.736-3.718-4.647-6.913-6.913-11.271l-1.807-3.438l-0.918-1.731
l-0.221-0.418l-0.063-0.104c-0.215-0.384,0.25,0.441,0.203,0.349l-0.012-0.047l-0.069-0.186l-0.297-0.768l-2.486-6.146
c-0.563-2.149-1.29-4.241-1.94-6.367c-0.441-2.185-0.871-4.38-1.405-6.542c-0.628-4.426-1.249-8.864-1.511-13.291
c-0.296-8.854,0.146-17.475,0.831-25.05c1.586-15.093,3.416-26.119,3.416-26.119s-8.72,7.343-15.906,22.54
c-1.894,3.765-3.509,8.041-4.915,12.699c-0.627,2.371-1.284,4.799-1.952,7.285c-0.377,2.568-0.761,5.193-1.162,7.877
c-0.192,2.719-0.384,5.508-0.575,8.32c0.023,2.834,0.261,5.727,0.418,8.644c0.727,5.833,1.999,11.735,4.09,17.451
c1.109,2.812,2.405,5.577,3.741,8.284l0.5,1.011l0.471,0.884l0.267,0.418l1.022,1.661l2.057,3.288
c3.091,4.461,7.175,9.527,10.898,13.223c3.84,3.938,8.22,7.029,12.374,9.817c4.177,2.753,8.574,4.589,12.577,6.146
c8.121,2.951,15.249,3.625,20.117,3.556c4.915-0.104,7.575-0.849,7.575-0.849s-10.445-4.101-21.854-13.326
C169.156,306.524,166.432,303.667,163.533,300.831z"/>
</g></g>
<!-- давление -->
<g transform="translate(-1, 78)" >
<text x="17" y="0" fill="black" stroke="none" font-size="12px">%weather_now.pressure%мм</text>
<g transform="scale(0.5) translate(3, -24)">
<path style="fill:#030104;" d="M20,21.527V4.006C20,1.793,18.205,0,16,0c-2.209,0-4,1.787-4,4.006v17.521
c-1.228,1.099-2,2.696-2,4.473c0,3.312,2.687,6,6,6c3.312,0,6-2.688,6-6C22,24.223,21.229,22.626,20,21.527z M16,30
c-2.209,0-4-1.791-4-4c0-1.48,0.805-2.773,2-3.465V4.005C14,2.897,14.896,2,16,2c1.111,0,2,0.897,2,2.005v18.53
c1.195,0.691,2,1.984,2,3.465C20,28.209,18.209,30,16,30z"/>
<path style="fill:#030104;" d="M17,23.171V7.993C17,7.444,16.557,7,16,7c-0.553,0-1,0.445-1,0.993v15.178
c-1.165,0.411-2,1.522-2,2.829c0,1.657,1.343,3,3,3s3-1.343,3-3C19,24.693,18.165,23.582,17,23.171z"/>
</g></g>
<!-- Температуры День Ночь -->
<text x="55" y="100" text-anchor="middle" fill="black" stroke="none" font-size="9px">Днем %today_day.temperature%℃ Ночью %today_night.temperature%℃</text>
<!-- Сравнение со вчера -->
<text x="55" y="115" text-anchor="middle" fill="black" stroke="none" font-size="9px">Сейчас %weather_now.yesterday_text%</text>
</svg>
Класс содержит несколько объектов, у которых есть метод sayWeather для проговаривания прогноза погоды. Для сбора данных используется сценарий getWeather который читает xml Яндекса. Запускать его нужно из объекта класса Timer.
Инструкция:
1. Создать пустую папку с именем weather_yandex_v3 в папке ./images/ или скопировать эту папку из вложения уже сразу с картинками. В итоге должно получиться <корневой каталог>/images/weather_yandex_v3/файлы.png
2. Импортировать элемент из файла или скопировать его код.
3. Найти и заменить в коде элемента все _114 на свой номер элемента, или на что то жутко уникальное.
4. Если данные погоды у Вас уже есть, замените в html коде элемента имена объект.свойств на свои, и на этом все.
5. Импортировать класс Weather или взять его в коннекте.
6. Создать сценарий getWeather.
7. Добавить код в метод onNewMinute для вызова сценария getWeather.
Код: Выделить всё
$data_file='http://export.yandex.ru/weather-ng/forecasts/27321.xml?'.rand(); // адрес xml файла. 27321 - id города
$urlimg='http://yandex.st/weather/1.2.61/i/icons/48x48/'; // адрес картинок на сайте Яндекс
$path='./images/weather_yandex_v3/'; // локальный путь к базе картинок
$xml = simplexml_load_file($data_file); // раскладываем xml на массив
/*
$obj->setProperty('SunRise',$xml->day[0]->sunrise);
$obj->setProperty('SunSet',$xml->day[0]->sunset);
*/
$ot='today_day';
$obj=getObject($ot);
$obj->setProperty('temperature',$xml->day[0]->day_part[4]->temperature);
$s=$xml->day[0]->day_part[4]->weather_type;
// если в текущем прогнозе есть дождь, а ранее его небыло
if (strpos($s, 'дожд') !== false) {
if (strpos($obj->getProperty('weatherType'), 'дожд') === false) {
say('Прогноз погоды предупреждает о возможном дожде.');
}}
$obj->setProperty('weatherType', $s);
$obj->setProperty('pressure',$xml->day[0]->day_part[4]->pressure);
$obj->setProperty('humidity',$xml->day[0]->day_part[4]->humidity);
$obj->setProperty('windSpeed',$xml->day[0]->day_part[4]->wind_speed);
$obj->setProperty('image',$xml->day[0]->day_part[4]->{'image-v3'});
$obj->setProperty('windDirection',$xml->day[0]->day_part[4]->wind_direction);
$ot='today_night';
$obj=getObject($ot);
$obj->setProperty('temperature',$xml->day[0]->day_part[5]->temperature);
$obj->setProperty('weatherType',$xml->day[0]->day_part[5]->weather_type);
$obj->setProperty('pressure',$xml->day[0]->day_part[5]->pressure);
$obj->setProperty('humidity',$xml->day[0]->day_part[5]->humidity);
$obj->setProperty('windSpeed',$xml->day[0]->day_part[5]->wind_speed);
$obj->setProperty('image',$xml->day[0]->day_part[5]->{'image-v3'});
$obj->setProperty('windDirection',$xml->day[0]->day_part[5]->wind_direction);
$ot='tomorrow_day';
$obj=getObject($ot);
$obj->setProperty('temperature',$xml->day[1]->day_part[4]->temperature);
$obj->setProperty('weatherType',$xml->day[1]->day_part[4]->weather_type);
$obj->setProperty('pressure',$xml->day[1]->day_part[4]->pressure);
$obj->setProperty('humidity',$xml->day[1]->day_part[4]->humidity);
$obj->setProperty('windSpeed',$xml->day[1]->day_part[4]->wind_speed);
$obj->setProperty('image',$xml->day[1]->day_part[4]->{'image-v3'});
$obj->setProperty('windDirection',$xml->day[1]->day_part[4]->wind_direction);
$ot='tomorrow_night';
$obj=getObject($ot);
$obj->setProperty('temperature',$xml->day[1]->day_part[5]->temperature);
$obj->setProperty('weatherType',$xml->day[1]->day_part[5]->weather_type);
$obj->setProperty('pressure',$xml->day[1]->day_part[5]->pressure);
$obj->setProperty('humidity',$xml->day[1]->day_part[5]->humidity);
$obj->setProperty('windSpeed',$xml->day[1]->day_part[5]->wind_speed);
$obj->setProperty('image',$xml->day[1]->day_part[5]->{'image-v3'});
$obj->setProperty('windDirection',$xml->day[1]->day_part[5]->wind_direction);
$ot='weather_now';
$obj=getObject($ot);
$obj->setProperty('updated',time());
$obj->setProperty('updatedTime',date('H:i',time()));
$obj->setProperty('alive',1);
$alive_timeout=(int)$obj->getProperty('aliveTimeOut');
if (!$alive_timeout) { $alive_timeout=12*60*60; }
setTimeOut($ot.'_alive',"sg('".$ot.".alive',0);",$alive_timeout);
$obj->setProperty('weatherType',$xml->fact->weather_type);
$obj->setProperty('pressure',$xml->fact->pressure);
$obj->setProperty('humidity',$xml->fact->humidity);
$obj->setProperty('windDirection',$xml->fact->wind_direction);
$obj->setProperty('uptime',$xml->fact->uptime);
$s=$xml->fact->wind_speed;
if ($s>=10) {$s=round($s);}
if ($s==0) {$s=0;}
$obj->setProperty('windSpeed',$s);
$s=$xml->fact->{'image-v3'};
$obj->setProperty("image",$s);
// скачать файл картинки с яндекса, если ее у нас нет
if (!file_exists($path.$s.'.png')) {
file_put_contents($path.$s.'.png', file_get_contents($urlimg.$s.'.png'));
}
$s=$xml->fact->temperature;
if ($s>0) {$s='+'.$s;} // добавить "+"
$obj->setProperty('temperature',$s);
// $s будет использована ниже при сравнении температур
$obj_title = $ot; // 'weather_now'; //имя объекта
$prop_title = 'temperature'; //имя свойства
// Имена объектов находятся в таблице objects и они должны быть уникальными
// Для начала нам нужно получить id нашего объекта и id класса которому принадлежит объект
$arr_s = SQLSelectOne("SELECT * FROM objects WHERE TITLE='".$obj_title."'");
$obj_id = $arr_s['ID'];
$class_id = $arr_s['CLASS_ID'];
/* Имена свойств находятся в таблице properties
с указанием id класса если свойство заданно на уровне класса,
или id объекта если свойство принадлежит объекту лично.
*/
// Получим id свойства по его имени И (id класса ИЛИ id объекта)
$arr_s = SQLSelectOne("SELECT * FROM properties WHERE TITLE='".$prop_title."' AND (CLASS_ID='".$class_id."' OR OBJECT_ID='".$obj_id."')");
$prop_id = $arr_s['ID'];
// значения свойств находятся в таблице pvalues
// Нам нужен id. (уточнить необходимость сортировки по UPDATED)
$arr_s = SQLSelectOne("SELECT * FROM pvalues WHERE OBJECT_ID='".$obj_id."' AND PROPERTY_ID='".$prop_id."'");
$pvalue = $arr_s['ID'];
/* Можно использовать альтернативный вариант, который будет работать намного быстрее.
Получить id из таблицы pvalues сразу по имени Объект.Свойство
Способ довольно простой и короткий, но пока что рекомендую его не использовать
ввиду возможных проблем с не обновленными системами.
$prop_name = 'ts_kitchen.status'; //Объект.Свойство
$arr_s = SQLSelectOne("SELECT * FROM pvalues WHERE PROPERTY_NAME='".$prop_name."'");
$pvalue = $arr_s['ID'];
*/
/* Зная $pvalue можно слазать за данными истории в таблицу phistory
Для нашей задачи нужна одна ближайшая запись до указанного времени
*/
$arr_s = SQLSelectOne("SELECT * FROM phistory WHERE VALUE_ID=".$pvalue." AND ADDED<='".date('Y-m-d H:i:s', strtotime('-1 day'))."' ORDER BY ADDED DESC LIMIT 0 , 1");
$os=$arr_s['VALUE'];
$msg='';
if (strlen($os)) {
if ($os>$s) { $msg = 'холоднее на '.($os-$s).'℃'; } // Вчера было теплее на
elseif ($os<$s) { $msg = 'теплее на '.($s-$os).'℃'; } // Вчера было холоднее на
else { $msg = 'так же как вчера'; }
}
$obj->setProperty('yesterday_text', $msg);
Код: Выделить всё
if (!($m%30)) { runScript('getWeather'); } // Обновить погоду