residential-window-cleaning-2026 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c7b97d475c6b6c90e731be8271a5cf3e783e42150d527e50ccb4fab8e8d7f3e1
4
+ data.tar.gz: d23246245df6248fb182b8ccf3e70177ce77a8687eb4ae1d13dfa3a6bdb10dec
5
+ SHA512:
6
+ metadata.gz: 784f182f62cfcea45d0dfe7ec2bfe4ae4843c2fe15d4a91a953a309fab98624a10a5ed1f26861831fc02f11dd041adc0fbe4fd1eba38e987409830c2ee6b1727
7
+ data.tar.gz: '08f1b9d8085a69bf4e042de796c7af5b528b283d06fbba24a03b5e7bd9e8eab748056b380ae42faba4206dda53033e1e19d3ff8efd984530b121742c07d5b962'
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ # ResidentialWindowCleaning2026
4
+ #
5
+ # Thermal shock risk and WFP solution freeze-point calculator for
6
+ # cold-weather residential window cleaning in Northern Ontario.
7
+ #
8
+ # Reference: https://www.binx.ca/guides/residential-window-cleaning-2026.pdf
9
+
10
+ module ResidentialWindowCleaning2026
11
+ VERSION = "0.1.0"
12
+
13
+ GLASS_PARAMS = {
14
+ single_annealed: { min_surface: -10.0, max_delta: 30.0, low_max: 10.0, med_max: 20.0 },
15
+ single_tempered: { min_surface: -15.0, max_delta: 55.0, low_max: 18.0, med_max: 36.0 },
16
+ double_igu: { min_surface: -20.0, max_delta: 40.0, low_max: 13.0, med_max: 26.0 },
17
+ double_igu_lowe: { min_surface: -25.0, max_delta: 45.0, low_max: 15.0, med_max: 30.0 },
18
+ triple_igu: { min_surface: -30.0, max_delta: 50.0, low_max: 16.0, med_max: 33.0 },
19
+ triple_igu_lowe: { min_surface: -30.0, max_delta: 52.0, low_max: 17.0, med_max: 34.0 },
20
+ laminated: { min_surface: -10.0, max_delta: 35.0, low_max: 11.0, med_max: 23.0 },
21
+ wired: { min_surface: -10.0, max_delta: 25.0, low_max: 8.0, med_max: 16.0 },
22
+ }.freeze
23
+
24
+ # Estimate glass surface temperature from ambient conditions.
25
+ #
26
+ # @param ambient_temp_c [Float] outdoor air temperature (°C)
27
+ # @param wind_speed_kmh [Float] wind speed (km/h)
28
+ # @param sun_factor [Float] solar exposure 0.0–1.0
29
+ # @return [Float] estimated glass surface temperature (°C)
30
+ def self.estimate_glass_surface_temp(ambient_temp_c, wind_speed_kmh, sun_factor)
31
+ solar_gain = sun_factor * 8.0
32
+ wind_factor = [wind_speed_kmh / 40.0, 1.0].min
33
+ solar_adjusted = solar_gain * (1.0 - 0.6 * wind_factor)
34
+ convective = ambient_temp_c < 5.0 ? -0.5 * wind_factor : 0.0
35
+ (ambient_temp_c + solar_adjusted + convective).round(1)
36
+ end
37
+
38
+ # Assess thermal shock risk for a cleaning operation.
39
+ #
40
+ # @param glass_type [Symbol] one of GLASS_PARAMS keys
41
+ # @param ambient_temp_c [Float]
42
+ # @param wind_speed_kmh [Float]
43
+ # @param sun_factor [Float]
44
+ # @param solution_temp_c [Float] cleaning solution temperature at application (°C)
45
+ # @return [Hash] assessment result
46
+ def self.assess_thermal_shock_risk(glass_type:, ambient_temp_c:, wind_speed_kmh:, sun_factor:, solution_temp_c:)
47
+ params = GLASS_PARAMS.fetch(glass_type) { raise ArgumentError, "Unknown glass_type: #{glass_type}" }
48
+ glass_temp = estimate_glass_surface_temp(ambient_temp_c, wind_speed_kmh, sun_factor)
49
+ delta_t = (solution_temp_c - glass_temp).abs.round(1)
50
+
51
+ band, proceed, advisory =
52
+ if glass_temp < params[:min_surface]
53
+ [:do_not_clean, false,
54
+ "Glass surface at #{glass_temp}°C is below minimum safe temp of #{params[:min_surface]}°C. Do not clean."]
55
+ elsif delta_t > params[:max_delta]
56
+ [:high, false,
57
+ "ΔT of #{delta_t}°C exceeds safe maximum of #{params[:max_delta]}°C. Cool solution or warm glass."]
58
+ elsif delta_t > params[:med_max]
59
+ [:moderate, true,
60
+ "Moderate risk (ΔT = #{delta_t}°C). Apply in small sections; avoid pooling at edges."]
61
+ elsif delta_t > params[:low_max]
62
+ [:low, true,
63
+ "Low risk (ΔT = #{delta_t}°C). Pre-wet glass before applying solution."]
64
+ else
65
+ [:safe, true,
66
+ "Safe conditions (ΔT = #{delta_t}°C). Proceed with normal technique."]
67
+ end
68
+
69
+ {
70
+ glass_type: glass_type,
71
+ estimated_glass_surface_temp_c: glass_temp,
72
+ delta_t_c: delta_t,
73
+ risk_band: band,
74
+ proceed: proceed,
75
+ advisory: advisory,
76
+ }
77
+ end
78
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: residential-window-cleaning-2026
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Veronica Caledon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-04-13 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Assess glass thermal shock risk and water-fed pole solution freeze feasibility
14
+ for residential window cleaning in cold-weather Northern Ontario conditions.
15
+ email:
16
+ - service@binx.ca
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - lib/residential_window_cleaning_2026.rb
22
+ homepage: https://www.binx.ca/residential-windows.php
23
+ licenses:
24
+ - MIT
25
+ metadata:
26
+ source_code_uri: https://github.com/veronica_caledon/residential-window-cleaning-2026
27
+ documentation_uri: https://residential-window-cleaning-2026.readthedocs.io
28
+ homepage_uri: https://www.binx.ca/residential-windows.php
29
+ post_install_message:
30
+ rdoc_options: []
31
+ require_paths:
32
+ - lib
33
+ required_ruby_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '2.7'
38
+ required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ requirements: []
44
+ rubygems_version: 3.4.20
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Thermal shock risk and WFP freeze-point calculator for cold-weather residential
48
+ window cleaning
49
+ test_files: []