1414"""
1515import logging
1616from datetime import timedelta
17+ from math import exp
1718
1819from .airthings import AirthingsWaveDetect
1920
2021import homeassistant .helpers .config_validation as cv
2122import voluptuous as vol
2223from homeassistant .components .sensor import PLATFORM_SCHEMA
2324from homeassistant .const import (ATTR_DEVICE_CLASS , ATTR_ICON , CONF_MAC ,
24- CONF_NAME , CONF_SCAN_INTERVAL ,
25+ CONF_NAME , CONF_SCAN_INTERVAL , CONF_ELEVATION ,
2526 CONF_UNIT_SYSTEM , CONF_UNIT_SYSTEM_IMPERIAL ,
2627 CONF_UNIT_SYSTEM_METRIC , TEMPERATURE ,
2728 TEMP_CELSIUS , DEVICE_CLASS_HUMIDITY ,
8182PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend ({
8283 vol .Optional (CONF_MAC , default = '' ): cv .string ,
8384 vol .Optional (CONF_SCAN_INTERVAL , default = SCAN_INTERVAL ): cv .time_period ,
85+ vol .Optional (CONF_ELEVATION , default = 0 ): vol .Any (vol .Coerce (float ), None )
8486})
8587
8688
@@ -91,14 +93,43 @@ def __init__(self, unit, unit_scale, device_class, icon):
9193 self .device_class = device_class
9294 self .icon = icon
9395
96+ def set_parameters (self , parameters ):
97+ self .parameters = parameters
98+
9499 def set_unit_scale (self , unit , unit_scale ):
95100 self .unit = unit
96101 self .unit_scale = unit_scale
97102
103+ def transform (self , value ):
104+ if self .unit_scale is None :
105+ return value
106+ return round (float (value * self .unit_scale ), 2 )
107+
98108 def get_extra_attributes (self , data ):
99109 return {}
100110
101111
112+ class PressureSensor (Sensor ):
113+ def __init__ (self , * args , ** kwargs ):
114+ super ().__init__ (* args , ** kwargs )
115+ self .offset = 0
116+
117+ def set_parameters (self , parameters ):
118+ super ().set_parameters (parameters )
119+ p0 = 101325 # Pa
120+ g = 9.80665 # m/s^2
121+ M = 0.02896968 # kg/mol
122+ T0 = 288.16 # K
123+ R0 = 8.314462618 # J/(mol K)
124+ h = self .parameters ['elevation' ] # m
125+ self .offset = (p0 - (p0 * exp (- g * h * M / (T0 * R0 ))))/ 100.0 # mbar
126+ self .offset = round (self .offset , 2 )
127+
128+ def transform (self , value ):
129+ value = super ().transform (value ) + self .offset
130+ return value
131+
132+
102133class RadonSensor (Sensor ):
103134 def get_extra_attributes (self , data ):
104135 if VERY_LOW [0 ] <= float (data ) <= VERY_LOW [1 ]:
@@ -115,7 +146,7 @@ def get_extra_attributes(self, data):
115146DEVICE_SENSOR_SPECIFICS = { "date_time" :Sensor ('time' , None , None , None ),
116147 "temperature" :Sensor (TEMP_CELSIUS , None , DEVICE_CLASS_TEMPERATURE , None ),
117148 "humidity" : Sensor (PERCENT , None , DEVICE_CLASS_HUMIDITY , None ),
118- "rel_atm_pressure" : Sensor (ATM_METRIC_UNITS , None , DEVICE_CLASS_PRESSURE , None ),
149+ "rel_atm_pressure" : PressureSensor (ATM_METRIC_UNITS , None , DEVICE_CLASS_PRESSURE , None ),
119150 "co2" : Sensor (CO2_METRIC_UNITS , None , DEVICE_CLASS_CO2 , 'mdi:molecule-co2' ),
120151 "voc" : Sensor (VOC_METRIC_UNITS , None , DEVICE_CLASS_VOC , 'mdi:cloud' ),
121152 "illuminance" : Sensor (ILLUMINANCE_LUX , None , DEVICE_CLASS_ILLUMINANCE , None ),
@@ -131,10 +162,15 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
131162 mac = config .get (CONF_MAC )
132163 mac = None if mac == '' else mac
133164
165+ elevation = config .get (CONF_ELEVATION ) or 0.0
166+ DEVICE_SENSOR_SPECIFICS ["rel_atm_pressure" ].set_parameters (
167+ {'elevation' : elevation })
168+
134169 if not hass .config .units .is_metric :
135170 DEVICE_SENSOR_SPECIFICS ["radon_1day_avg" ].set_unit_scale (VOLUME_PICOCURIE , BQ_TO_PCI_MULTIPLIER )
136171 DEVICE_SENSOR_SPECIFICS ["radon_longterm_avg" ].set_unit_scale (VOLUME_PICOCURIE , BQ_TO_PCI_MULTIPLIER )
137172
173+
138174 _LOGGER .debug ("Searching for Airthings sensors..." )
139175 airthingsdetect = AirthingsWaveDetect (scan_interval , mac )
140176 try :
@@ -231,8 +267,5 @@ def update(self):
231267 """
232268 self .device .get_sensor_data ()
233269 value = self .device .sensordata [self ._mac ][self ._sensor_name ]
234- if self ._sensor_specifics .unit_scale is None :
235- self ._state = value
236- else :
237- self ._state = round (float (value * self ._sensor_specifics .unit_scale ), 2 )
270+ self ._state = self ._sensor_specifics .transform (value )
238271 _LOGGER .debug ("State {} {}" .format (self ._name , self ._state ))
0 commit comments