It is currently April 13th, 2021, 3:59 pm

JSBarometer

Weather skins
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

Corrected a bug in the .lua code that was discovered by user GDias. Also fine-tuned a couple of things in the .ini skin.

Get the new .rmskin in the first post of this thread.

Thanks GDias!
Wim
Posts: 69
Joined: September 22nd, 2010, 8:30 pm

Re: JSBarometer

Post by Wim »

I ran into a thing while editing the code

My location code is: LocationCode=faf2085544837e50ac18277c439ed18adcb75a1741d90280781897ef78a22878
Language=nl-NL

It's about this bit in the Lua code :

if string.lower(currentUnitOfMeasure) == 'mb' then
convertedPressure = tostring(Round(tonumber(currentPressure) * 0.0295300, 2))
unitPosfix = ' mb'
else
convertedPressure = currentPressure
unitPosfix = ' in'
end

The barometer shows "Falling" and '1.0131 mb' (which is 1013.1 mb or 29.91 in) but the the description on right gives the one from <=28.59 (in) (Íncreasingly Stormy')

In Dutch 1.000 is a thousand and 1,000 is one. In US English it's the other way round.

I would suspect that the code is reading 'one-point-zero-one-three-one' where it should be 'one thousand-point-zero-one-three-one', so the conversion of 0.0295300 gives a way too low number in inches.

I changed the conversion 0.0295300 to 0029.5300 and it seems to be giving the right results (from >= 29.51 and <= 30.09)

I can't check the raw input/number from weather.com but 1.0131 is problematic in both languages. In Dutch it's either 1013,1 mb or 1.013,1 mb and in English it would be 1013.1 or 1,013.1

Adjusting the conversion number seems to do the trick but it took me some head scratching to figure it out. I hope this is helpful.
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

Wim wrote: January 26th, 2020, 1:42 pm I ran into a thing while editing the code

My location code is: LocationCode=faf2085544837e50ac18277c439ed18adcb75a1741d90280781897ef78a22878
Language=nl-NL

It's about this bit in the Lua code :

if string.lower(currentUnitOfMeasure) == 'mb' then
convertedPressure = tostring(Round(tonumber(currentPressure) * 0.0295300, 2))
unitPosfix = ' mb'
else
convertedPressure = currentPressure
unitPosfix = ' in'
end

The barometer shows "Falling" and '1.0131 mb' (which is 1013.1 mb or 29.91 in) but the the description on right gives the one from <=28.59 (in) (Íncreasingly Stormy')

In Dutch 1.000 is a thousand and 1,000 is one. In US English it's the other way round.

I would suspect that the code is reading 'one-point-zero-one-three-one' where it should be 'one thousand-point-zero-one-three-one', so the conversion of 0.0295300 gives a way too low number in inches.

I changed the conversion 0.0295300 to 0029.5300 and it seems to be giving the right results (from >= 29.51 and <= 30.09)

I can't check the raw input/number from weather.com but 1.0131 is problematic in both languages. In Dutch it's either 1013,1 mb or 1.013,1 mb and in English it would be 1013.1 or 1,013.1

Adjusting the conversion number seems to do the trick but it took me some head scratching to figure it out. I hope this is helpful.

I think the most straightforward way to deal with this is to simply change your Language to en-GB. There is no need to use Dutch as the language, as I don't use any of the "strings" returned from the site, and simply using British English as the language will cause the pressure to be returned in metric millibars, but with the English method of formatting numbers. If you really want the Dutch number formatting, it might be easier to just use gsub() in Lua on the converted pressure number, after the fact.


1.png


Good catch though, it certainly doesn't react well to this. I'll chew on it. Be an interesting challenge, as the number can have both . and , in it, and figuring out which is which based on position will take some thought.

It's even a bit more difficult, as fr-FR (French) returns 1 0129. Mon Dieu!
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

Bad enough you Europeans drive on the wrong side of the road... At least get numbers right for crying out loud! :-)
Wim
Posts: 69
Joined: September 22nd, 2010, 8:30 pm

Re: JSBarometer

Post by Wim »

Simple and straightforward solution. I hadn't thought of that one. The thing is of course when you set your location code and variables in the WeatherComVariables.inc you don't realize that. I just selected nl-Nl because i'm Dutch. I would think others might run into the same thing. Thanks for the solution, anyway. It's obviously better than my own (though i always like solving the puzzle myself first).
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

Wim wrote: January 26th, 2020, 2:05 pm Simple and straightforward solution. I hadn't thought of that one. The thing is of course when you set your location code and variables in the WeatherComVariables.inc you don't realize that. I just selected nl-Nl because i'm Dutch. I would think others might run into the same thing. Thanks for the solution, anyway. It's obviously better than my own (though i always like solving the puzzle myself first).
I fully understand why you would use the same Language code that you use in other weather skins, so I really need to figure out how to gracefully handle this.

The rub is that the only thing the site tells me is that the return values are either imperial (F) or metric (C).

The number might be any of:

1,0129.1
1.0129,1
1 0129,1

https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html
User avatar
SilverAzide
Rainmeter Sage
Posts: 1208
Joined: March 23rd, 2015, 5:26 pm

Re: JSBarometer

Post by SilverAzide »

jsmorley wrote: January 26th, 2020, 2:08 pm I fully understand why you would use the same Language code that you use in other weather skins, so I really need to figure out how to gracefully handle this.
I don't know the perfect solution to this, but I do know one way to handle it based on the assumption that the user wants the weather in the locale that matches how their Windows is configured.

In the regsitry, see:
HKEY_CURRENT_USER\Control Panel\International\LocaleName = locale name (TWC does not support all locales, but does quite a lot of them)
HKEY_CURRENT_USER\Control Panel\International\sDecimal = decimal point symbol
HKEY_CURRENT_USER\Control Panel\International\sThousand = thousands separator

You could construct a Substitute to convert any number format to the English style that Rainmeter/Lua will understand.
And you (not me, but you ;-)) could probably figure out how to build one that goes the other way as well.
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

SilverAzide wrote: January 26th, 2020, 3:12 pm I don't know the perfect solution to this, but I do know one way to handle it based on the assumption that the user wants the weather in the locale that matches how their Windows is configured.

In the regsitry, see:
HKEY_CURRENT_USER\Control Panel\International\LocaleName = locale name (TWC does not support all locales, but does quite a lot of them)
HKEY_CURRENT_USER\Control Panel\International\sDecimal = decimal point symbol
HKEY_CURRENT_USER\Control Panel\International\sThousand = thousands separator

You could construct a Substitute to convert any number format to the English style that Rainmeter/Lua will understand.
And you (not me, but you ;-)) could probably figure out how to build one that goes the other way as well.

I'm just not willing to make that kind of assumption in my weather skins. I need to "react" to what I get in this case, not try to "force" some result.
Wim
Posts: 69
Joined: September 22nd, 2010, 8:30 pm

Re: JSBarometer

Post by Wim »

An additional issue is going to be that the code only distinguishes between inches (in) and millibars (mb). I was trying settings with different language codes and i found that the German language settings don't do inches or millibars at all; they use the modern version of HPa (hectoPascal). 1 mb is 1 hPa but because the hPa value is not recognized by the code it gives the number (in the wrong format) in mb but designates it as 'in' on the barometer display.
Baro_duits_2.PNG
Here's how it looks on weather.com
Baro_DE.PNG
Two more: Dutch
Baro_NL.PNG
and French
Baro_Fr.PNG
Both are in mb
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 21619
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: JSBarometer

Post by jsmorley »

Ok Wim,

I think I have corrected for all eventualities, see if the new .rmskin in the first post of this thread doesn't correct things for any of:

Language=en-US
Language=en-GB
Language=nl-NL
Language=fr-FR
Language=de-DE
Language=zh-CN

All the "calculating" will be done on the number converted to English format inches of mercury, and the "display" will be in the original number format and unit of measure.

I no longer depend on the textual unit of measure for anything... Hopefully we won't find that some country returns the actual value in something other than in / inHg or mb / hPa.

So for example, German will result in 1.012,2 hPa

Code: Select all

function Initialize()

	measurePressure = SKIN:GetMeasure('MeasurePressure')
	measureChange = SKIN:GetMeasure('MeasurePressureChange')
	unitOfMeasure = SKIN:GetMeasure('MeasurePressureUnit')
	
end

function Update()

	currentUnitOfMeasure = unitOfMeasure:GetStringValue()
	currentPressure = measurePressure:GetStringValue()
	currentChange = string.lower(measureChange:GetStringValue())
	
	if currentPressure == '' then return currentPressure end
	
	-- Removes the unicode "non-breaking space" used as separator in some languages
	formattedPressure = currentPressure:gsub('[^%d\.,]', '')
	
	-- Converts languages that use '.' as separator and ',' as decimal places to the opposite
	if formattedPressure:match('%..*,') or formattedPressure:match('.*,[%d*]$')then 
		formattedPressure = formattedPressure:gsub('%.', 'dot')
		formattedPressure = formattedPressure:gsub(',', '%.')
		formattedPressure = formattedPressure:gsub('dot', '')
	end

	-- Removes commas from all values, so they can be treated as a number
	formattedPressure = formattedPressure:gsub(',', '')	
	
	if  tonumber(formattedPressure) >= 870 and tonumber(formattedPressure) <= 1084 then
		convertedPressure = tostring(Round(tonumber(formattedPressure) * 0.0295300, 2))
	else
		convertedPressure = currentPressure
	end

	unitPosfix = ' '..currentUnitOfMeasure
		
	SKIN:Bang('!SetOption', 'CurrentPressurePercent', 'Formula', tonumber(convertedPressure))
	SKIN:Bang('!EnableMeasure', 'CurrentPressurePercent')
	SKIN:Bang('!UpdateMeasure', 'CurrentPressurePercent')
	
	if tonumber(convertedPressure) <= 28.59 then
		if string.find(currentChange, 'falling') then
			currentDescription = 'Increasingly Stormy'
		elseif string.find(currentChange, 'steady') then
			currentDescription = 'Remaining Stormy'
		elseif string.find(currentChange, 'rising') then
			currentDescription = 'Stormy, but Improving'
		end
	end
		
	if tonumber(convertedPressure) >= 28.60 and tonumber(convertedPressure) <= 29.50 then
		if string.find(currentChange, 'falling') then
			currentDescription = 'Rain Forecasted'
		elseif string.find(currentChange, 'steady') then
			currentDescription = 'Remaining Rainy'
		elseif string.find(currentChange, 'rising') then
			currentDescription = 'Rainy, but Improving'
		end
	end
	
	if tonumber(convertedPressure) >= 29.51 and tonumber(convertedPressure) <= 30.09 then
		if string.find(currentChange, 'falling') then
			currentDescription = 'Changing toward Rain'
		elseif string.find(currentChange, 'steady') then
			currentDescription = 'Change Possible'
		elseif string.find(currentChange, 'rising') then
			currentDescription = 'Changing toward Fair'
		end
	end
	
	if tonumber(convertedPressure) >= 30.10 and tonumber(convertedPressure) <= 30.59 then
		if string.find(currentChange, 'falling') then
			currentDescription = 'Fair, but Degrading'
		elseif string.find(currentChange, 'steady') then
			currentDescription = 'Remaining Fair'
		elseif string.find(currentChange, 'rising') then
			currentDescription = 'Fair, and Improving'
		end
	end
	
	if tonumber(convertedPressure) >= 30.60 then
		if string.find(currentChange, 'falling') then
			currentDescription = 'Very Dry, but Degrading'
		elseif string.find(currentChange, 'steady') then
			currentDescription = 'Remaining Very Dry'
		elseif string.find(currentChange, 'rising') then
			currentDescription = 'Increasingly Very Dry'
		end		
	end
	
	SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern2', '^$')
	SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern3', '^$')
	SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern4', '^$')
	SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern5', '^$')
	
	if string.find(currentChange, 'falling') and string.find(currentChange, 'rapidly') then
		SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern2', '(◀ ◀)')
	elseif string.find(currentChange, 'falling') and not string.find(currentChange, 'rapidly') then
		SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern3', '◀ (◀)')
	elseif string.find(currentChange, 'rising') and string.find(currentChange, 'rapidly') then
		SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern4', '(▶ ▶)')
	elseif string.find(currentChange, 'rising') and not string.find(currentChange, 'rapidly') then
		SKIN:Bang('!SetOption', 'MeterChange', 'InlinePattern5', '(▶) ▶')
	end
	
	SKIN:Bang('!SetOption', 'MeterPressure', 'Text', currentPressure..unitPosfix)
	SKIN:Bang('!SetOption', 'MeterDescription', 'Text', currentDescription)
	
	return currentDescription

end

function Round(num, idp)

  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
  
end