This is what the Google Script (javascript) routine looks like for the Environment Canada weather page. Modify as necessary for any other weather page by saving the html source and checking the format for where the key elements are located that you need to pick out.
function getCurrWeather() {
/* Get current 7-day forecast web page from Environment Canada for Toronto */
var response = UrlFetchApp.fetch('https://weather.gc.ca/city/pages/on-143_metric_e.html');
var pagecontent = String(response);
/* Find the weather parameters in the html response string. The format looks like this:
<dt>Temperature:</dt>
<dd class=3D"mrgn-bttm-0 wxo-metric-hide">7.1<
so we will search for the keyword, skip two right angle brackets, then look for the terminating left angle bracket
*/
/* Find the current condition text in the response string, something like "Mostly cloudy" */
var n = pagecontent.indexOf('Condition:');
n = pagecontent.indexOf('>', n+12);
n = pagecontent.indexOf('>', n+1);
var n1 = pagecontent.indexOf('<', n+1);
var curcond = pagecontent.substr(n+1, n1-n-1);
/* Logger.log(curcond); */
/* Find the temperature in deg in the response string */
var n = pagecontent.indexOf('Temperature:', n+70);
n = pagecontent.indexOf('>', n+12);
n = pagecontent.indexOf('>', n+1);
var n1 = pagecontent.indexOf('<', n+1);
var curtemp = pagecontent.substr(n+1, n1-n-2);
/* Logger.log(curtemp); */
/* Find the pressure in kPa in the response string */
var n = pagecontent.indexOf('Pressure:', n+70);
n = pagecontent.indexOf('>', n+12);
n = pagecontent.indexOf('>', n+1);
var n1 = pagecontent.indexOf('<', n+1);
var pkpa = pagecontent.substr(n+1, n1-n-2);
/* convert to hPa / millibars */
var curpressure = String(pkpa * 10);
/* Logger.log(curpressure); */
/* Find the icon number in the response string (full url is present, but only need icon number */
var n = pagecontent.indexOf('weathericons/', n+70);
n = n+12;
var n1 = pagecontent.indexOf('.', n+1); /* .gif is the terminator 8?
var curicon = pagecontent.substr(n+1, n1-n-1);
/* Logger.log(curicon); */
/* Use http Get with /? parameters to pass values to Node Red on home system */
var actionurl = 'http://myhomeid.noip.me:1880/weatherep/?temp=' + curtemp + '&press=' + curpressure + '&cond=' + curcond + '&icon=' + curicon
/* Logger.log(actionurl); */
var response = UrlFetchApp.fetch(actionurl);
/* No need to check the response, don't care
}
You go to https://www.google.com/script/start/, log into your account, create a “Project”, create a new script within that Project, and paste in the above code. Select the Run command to test that the script is working. Then you go to Triggers, select Time trigger, and set the script to once per hour (or whatever interval you want). Google scripts are free, as long as you don’t exceed a reasonable run time per day - no danger here.
On the Home Assistant side, the final fetch command in the above script sends the weather parameters to a Node Red flow beginning with a web trigger named “weatherep”. If you instead want to send it to a Home Assistant automation, you have to create an webhook-triggered automation named something similar, and use POST format for the fetch command (see https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch for how to structure POST).
On the Node Red side, to set the temperature (for example), I use a Call Service node, domain python_script, service set_state, entity_id sensor.yr_temperature, data {“state”:"{{payload.temp}}",“attribution”:“Environment Canada”}. You can experiment with the set_state service in the Home Assistant interface if you want.
For the icon, it’s: entity_id sensor.yr.symbol and data {“entity_picture”:“http://weather.gc.ca/weathericons/{{payload.icon}}.gif”,“attribution”:“Environment Canada”}
If you want to replace the old yr sensor with new template sensors of the same name, it’s:
- platform: template
sensors:
yr_temperature:
friendly_name: "Temperature"
unit_of_measurement: "°C"
value_template: "-"
yr_pressure:
friendly_name: "Pressure"
unit_of_measurement: "hPa"
value_template: "-"
yr_symbol:
friendly_name: "Weather"
value_template: "unknown"