1 /* 2 * TemperatureUnit.js - Unit conversions for temperature measurements 3 * 4 * Copyright © 2014-2015, 2018 JEDLSoft 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 /* 21 !depends 22 Measurement.js 23 */ 24 25 var Measurement = require("./Measurement.js"); 26 27 /** 28 * @class 29 * Create a new Temperature measurement instance. 30 * 31 * @constructor 32 * @extends Measurement 33 * @param options {{unit:string,amount:number|string|undefined}} Options controlling 34 * the construction of this instance 35 */ 36 var TemperatureUnit = function (options) { 37 this.unit = "celsius"; 38 this.amount = 0; 39 40 this.ratios = TemperatureUnit.ratios; 41 this.aliases = TemperatureUnit.aliases; 42 this.aliasesLower = TemperatureUnit.aliasesLower; 43 this.systems = TemperatureUnit.systems; 44 45 this.parent.call(this, options); 46 }; 47 48 TemperatureUnit.prototype = new Measurement(); 49 TemperatureUnit.prototype.parent = Measurement; 50 TemperatureUnit.prototype.constructor = TemperatureUnit; 51 52 TemperatureUnit.ratios = { 53 /* index, C K F */ 54 "celsius": [ 1, 1, 1, 9/5 ], 55 "kelvin": [ 2, 1, 1, 9/5 ], 56 "fahrenheit": [ 3, 5/9, 5/9, 1 ] 57 }; 58 59 /** 60 * Return the type of this measurement. Examples are "mass", 61 * "length", "speed", etc. Measurements can only be converted 62 * to measurements of the same type.<p> 63 * 64 * The type of the units is determined automatically from the 65 * units. For example, the unit "grams" is type "mass". Use the 66 * static call {@link Measurement.getAvailableUnits} 67 * to find out what units this version of ilib supports. 68 * 69 * @return {string} the name of the type of this measurement 70 */ 71 TemperatureUnit.prototype.getMeasure = function() { 72 return "temperature"; 73 }; 74 75 /** 76 * Return a new instance of this type of measurement. 77 * 78 * @param {Object} params parameters to the constructor 79 * @return {Measurement} a measurement subclass instance 80 */ 81 TemperatureUnit.prototype.newUnit = function(params) { 82 return new TemperatureUnit(params); 83 }; 84 85 TemperatureUnit.systems = { 86 "metric": [ 87 "celsius", 88 "kelvin" 89 ], 90 "uscustomary": [ 91 "fahrenheit" 92 ], 93 "imperial": [ 94 "fahrenheit" 95 ], 96 "conversions": { 97 "metric": { 98 "uscustomary": { 99 "celsius": "fahrenheit", 100 "kelvin": "fahrenheit" 101 }, 102 "imperial": { 103 "celsius": "fahrenheit", 104 "kelvin": "fahrenheit" 105 } 106 }, 107 "uscustomary": { 108 "metric": { 109 "fahrenheit": "celsius" 110 } 111 }, 112 "imperial": { 113 "metric": { 114 "fahrenheit": "celsius" 115 } 116 } 117 } 118 }; 119 120 TemperatureUnit.aliases = { 121 "Celsius": "celsius", 122 "C": "celsius", 123 "Centegrade": "celsius", 124 "Centigrade": "celsius", 125 "Fahrenheit": "fahrenheit", 126 "F": "fahrenheit", 127 "K": "kelvin", 128 "Kelvin": "kelvin", 129 "°F": "fahrenheit", 130 "℉": "fahrenheit", 131 "℃": "celsius", 132 "°C": "celsius" 133 }; 134 135 (function() { 136 TemperatureUnit.aliasesLower = {}; 137 for (var a in TemperatureUnit.aliases) { 138 TemperatureUnit.aliasesLower[a.toLowerCase()] = TemperatureUnit.aliases[a]; 139 } 140 })(); 141 142 /** 143 * Return a new measurement instance that is converted to a new 144 * measurement unit. Measurements can only be converted 145 * to measurements of the same type.<p> 146 * 147 * @param {string} to The name of the units to convert to 148 * @return {number|undefined} the converted measurement 149 * or undefined if the requested units are for a different 150 * measurement type 151 */ 152 TemperatureUnit.prototype.convert = function(to) { 153 if (!to || typeof(TemperatureUnit.ratios[this.normalizeUnits(to)]) === 'undefined') { 154 return undefined; 155 } 156 return TemperatureUnit.convert(to, this.unit, this.amount); 157 }; 158 159 /** 160 * Convert a temperature to another measure. 161 * @static 162 * @param to {string} unit to convert to 163 * @param from {string} unit to convert from 164 * @param temperature {number} amount to be convert 165 * @returns {number|undefined} the converted amount 166 */ 167 TemperatureUnit.convert = function(to, from, temperature) { 168 var result = 0; 169 from = Measurement.getUnitIdCaseInsensitive(TemperatureUnit, from) || from; 170 to = Measurement.getUnitIdCaseInsensitive(TemperatureUnit, to) || to; 171 if (from === to) { 172 return temperature; 173 } else if (from === "celsius") { 174 if (to === "fahrenheit") { 175 result = ((temperature * 9 / 5) + 32); 176 } else if (to === "kelvin") { 177 result = (temperature + 273.15); 178 } 179 } else if (from === "fahrenheit") { 180 if (to === "celsius") { 181 result = ((5 / 9 * (temperature - 32))); 182 } else if (to === "kelvin") { 183 result = ((temperature + 459.67) * 5 / 9); 184 } 185 } else if (from === "kelvin") { 186 if (to === "celsius") { 187 result = (temperature - 273.15); 188 } else if (to === "fahrenheit") { 189 result = ((temperature * 9 / 5) - 459.67); 190 } 191 } 192 193 return result; 194 }; 195 196 /** 197 * Scale the measurement unit to an acceptable level. The scaling 198 * happens so that the integer part of the amount is as small as 199 * possible without being below zero. This will result in the 200 * largest units that can represent this measurement without 201 * fractions. Measurements can only be scaled to other measurements 202 * of the same type. 203 * 204 * @param {string=} measurementsystem system to use (uscustomary|imperial|metric), 205 * or undefined if the system can be inferred from the current measure 206 * @return {Measurement} a new instance that is scaled to the 207 * right level 208 */ 209 TemperatureUnit.prototype.scale = function(measurementsystem) { 210 // no scaling for temp units 211 return this; 212 }; 213 214 /** 215 * @private 216 * @static 217 */ 218 TemperatureUnit.getMeasures = function () { 219 return ["celsius", "kelvin", "fahrenheit"]; 220 }; 221 222 //register with the factory method 223 Measurement._constructors["temperature"] = TemperatureUnit; 224 225 module.exports = TemperatureUnit; 226