def outdoorAir(Msg, wfpiconsole): """ Handles Websocket messages received from outdoor AIR module INPUTS: Msg Websocket messages received from outdoor AIR module wfpiconsole wfpiconsole object """ # Replace missing observations in latest outdoor AIR Websocket JSON with NaN Ob = [x if x != None else NaN for x in Msg['obs'][0]] # Discard duplicate outdoor AIR Websocket messages if 'outAirMsg' in wfpiconsole.Obs: if wfpiconsole.Obs['outAirMsg']['obs'][0] == Ob[0]: print('Discarding duplicate outdoor AIR Websocket message') return # Extract outdoor AIR device ID and API flag, and station configuration # object Device = wfpiconsole.config['Station']['OutAirID'] flagAPI = wfpiconsole.flagAPI[2] Config = wfpiconsole.config # Extract required observations from latest outdoor AIR Websocket JSON Time = [Ob[0], 's'] Pres = [Ob[1], 'mb'] Temp = [Ob[2], 'c'] Humidity = [Ob[3], '%'] Strikes = [Ob[4], 'count'] # Extract lightning strike data from the latest outdoor AIR Websocket JSON # "Summary" object StrikeTime = [ Msg['summary']['strike_last_epoch'] if 'strike_last_epoch' in Msg['summary'] else NaN, 's' ] StrikeDist = [ Msg['summary']['strike_last_dist'] if 'strike_last_dist' in Msg['summary'] else NaN, 'km' ] Strikes3hr = [ Msg['summary']['strike_count_3h'] if 'strike_count_3h' in Msg['summary'] else NaN, 'count' ] # Extract required derived observations minPres = wfpiconsole.Obs['MinPres'] maxPres = wfpiconsole.Obs['MaxPres'] minTemp = wfpiconsole.Obs['outTempMin'] maxTemp = wfpiconsole.Obs['outTempMax'] StrikeCount = { 'Today': wfpiconsole.Obs['StrikesToday'], 'Month': wfpiconsole.Obs['StrikesMonth'], 'Year': wfpiconsole.Obs['StrikesYear'] } # Request outdoor AIR data from the previous three hours Data3h = requestAPI.weatherflow.Last3h(Device, Time[0], Config) # Store latest outdoor AIR Websocket message wfpiconsole.Obs['outAirMsg'] = Msg # Extract required observations from latest SKY Websocket JSON while not 'SkyMsg' in wfpiconsole.Obs: time.sleep(0.01) Ob = [x if x != None else NaN for x in wfpiconsole.Obs['SkyMsg']['obs'][0]] WindSpd = [Ob[5], 'mps'] # Calculate derived variables from AIR observations DewPoint = derive.DewPoint(Temp, Humidity) SLP = derive.SLP(Pres, Config) PresTrend = derive.SLPTrend(Pres, Time, Data3h, Config) FeelsLike = derive.FeelsLike(Temp, Humidity, WindSpd, Config) MaxTemp, MinTemp = derive.TempMaxMin(Time, Temp, maxTemp, minTemp, Device, Config, flagAPI) MaxPres, MinPres = derive.SLPMaxMin(Time, Pres, maxPres, minPres, Device, Config, flagAPI) StrikeCount = derive.StrikeCount(Strikes, StrikeCount, Device, Config, flagAPI) StrikeFreq = derive.StrikeFrequency(Time, Data3h, Config) StrikeDeltaT = derive.StrikeDeltaT(StrikeTime) # Convert observation units as required Temp = observation.Units(Temp, Config['Units']['Temp']) MaxTemp = observation.Units(MaxTemp, Config['Units']['Temp']) MinTemp = observation.Units(MinTemp, Config['Units']['Temp']) DewPoint = observation.Units(DewPoint, Config['Units']['Temp']) FeelsLike = observation.Units(FeelsLike, Config['Units']['Temp']) SLP = observation.Units(SLP, Config['Units']['Pressure']) MaxPres = observation.Units(MaxPres, Config['Units']['Pressure']) MinPres = observation.Units(MinPres, Config['Units']['Pressure']) PresTrend = observation.Units(PresTrend, Config['Units']['Pressure']) StrikeDist = observation.Units(StrikeDist, Config['Units']['Distance']) # Store derived outdoor AIR observations in dictionary derivedObs = {} derivedObs['outTemp'] = observation.Format(Temp, 'Temp') derivedObs['outTempMax'] = observation.Format(MaxTemp, 'Temp') derivedObs['outTempMin'] = observation.Format(MinTemp, 'Temp') derivedObs['DewPoint'] = observation.Format(DewPoint, 'Temp') derivedObs['FeelsLike'] = observation.Format(FeelsLike, 'Temp') derivedObs['Pres'] = observation.Format(SLP, 'Pressure') derivedObs['MaxPres'] = observation.Format(MaxPres, 'Pressure') derivedObs['MinPres'] = observation.Format(MinPres, 'Pressure') derivedObs['PresTrend'] = observation.Format(PresTrend, 'Pressure') derivedObs['StrikeDeltaT'] = observation.Format(StrikeDeltaT, 'TimeDelta') derivedObs['StrikeDist'] = observation.Format(StrikeDist, 'StrikeDistance') derivedObs['StrikeFreq'] = observation.Format(StrikeFreq, 'StrikeFrequency') derivedObs['Strikes3hr'] = observation.Format(Strikes3hr, 'StrikeCount') derivedObs['StrikesToday'] = observation.Format(StrikeCount['Today'], 'StrikeCount') derivedObs['StrikesMonth'] = observation.Format(StrikeCount['Month'], 'StrikeCount') derivedObs['StrikesYear'] = observation.Format(StrikeCount['Year'], 'StrikeCount') derivedObs['Humidity'] = observation.Format(Humidity, 'Humidity') # Update wfpiconsole display with derived outdoor AIR observations updateDisplay(derivedObs, wfpiconsole, 'outdoorAir') # Set flags for required API calls wfpiconsole.flagAPI[2] = 0 # Return wfpiconsole object return wfpiconsole
def Tempest(Msg, wfpiconsole): """ Handles Websocket messages received from TEMPEST module INPUTS: Msg Websocket messages received from TEMPEST module wfpiconsole wfpiconsole object """ # Replace missing observations from latest TEMPEST Websocket JSON with NaN Ob = [x if x != None else NaN for x in Msg['obs'][0]] # Discard duplicate TEMPEST Websocket messages if 'TempestMsg' in wfpiconsole.Obs: if wfpiconsole.Obs['TempestMsg']['obs'][0] == Ob[0]: print('Discarding duplicate TEMPEST Websocket message') return # Extract TEMPEST device ID, API flag, and station configuration object Device = wfpiconsole.config['Station']['TempestID'] flagAPI = wfpiconsole.flagAPI[0] Config = wfpiconsole.config # Extract required observations from latest TEMPEST Websocket JSON Time = [Ob[0], 's'] WindSpd = [Ob[2], 'mps'] WindGust = [Ob[3], 'mps'] WindDir = [Ob[4], 'degrees'] Pres = [Ob[6], 'mb'] Temp = [Ob[7], 'c'] Humidity = [Ob[8], '%'] UV = [Ob[10], 'index'] Radiation = [Ob[11], 'Wm2'] Rain = [Ob[12], 'mm'] Strikes = [Ob[15], 'count'] # Extract lightning strike data from the latest AIR Websocket JSON "Summary" # object StrikeTime = [ Msg['summary']['strike_last_epoch'] if 'strike_last_epoch' in Msg['summary'] else NaN, 's' ] StrikeDist = [ Msg['summary']['strike_last_dist'] if 'strike_last_dist' in Msg['summary'] else NaN, 'km' ] Strikes3hr = [ Msg['summary']['strike_count_3h'] if 'strike_count_3h' in Msg['summary'] else NaN, 'count' ] # Store latest TEMPEST Websocket message wfpiconsole.Obs['TempestMsg'] = Msg # Extract required derived observations minPres = wfpiconsole.Obs['MinPres'] maxPres = wfpiconsole.Obs['MaxPres'] minTemp = wfpiconsole.Obs['outTempMin'] maxTemp = wfpiconsole.Obs['outTempMax'] StrikeCount = { 'Today': wfpiconsole.Obs['StrikesToday'], 'Month': wfpiconsole.Obs['StrikesMonth'], 'Year': wfpiconsole.Obs['StrikesYear'] } rainAccum = { 'Today': wfpiconsole.Obs['TodayRain'], 'Yesterday': wfpiconsole.Obs['YesterdayRain'], 'Month': wfpiconsole.Obs['MonthRain'], 'Year': wfpiconsole.Obs['YearRain'] } peakSun = wfpiconsole.Obs['peakSun'] avgWind = wfpiconsole.Obs['AvgWind'] maxGust = wfpiconsole.Obs['MaxGust'] # Request TEMPEST data from the previous three hours Data3h = requestAPI.weatherflow.Last3h(Device, Time[0], Config) # Calculate derived variables from TEMPEST observations DewPoint = derive.DewPoint(Temp, Humidity) SLP = derive.SLP(Pres, Config) PresTrend = derive.SLPTrend(Pres, Time, Data3h, Config) FeelsLike = derive.FeelsLike(Temp, Humidity, WindSpd, Config) MaxTemp, MinTemp = derive.TempMaxMin(Time, Temp, maxTemp, minTemp, Device, Config, flagAPI) MaxPres, MinPres = derive.SLPMaxMin(Time, Pres, maxPres, minPres, Device, Config, flagAPI) StrikeCount = derive.StrikeCount(Strikes, StrikeCount, Device, Config, flagAPI) StrikeFreq = derive.StrikeFrequency(Time, Data3h, Config) StrikeDeltaT = derive.StrikeDeltaT(StrikeTime) FeelsLike = derive.FeelsLike(Temp, Humidity, WindSpd, Config) RainRate = derive.RainRate(Rain) rainAccum = derive.RainAccumulation(Rain, rainAccum, Device, Config, flagAPI) AvgWind = derive.MeanWindSpeed(WindSpd, avgWind, Device, Config, flagAPI) MaxGust = derive.MaxWindGust(WindGust, maxGust, Device, Config, flagAPI) WindSpd = derive.BeaufortScale(WindSpd) WindDir = derive.CardinalWindDirection(WindDir, WindSpd) peakSun = derive.peakSunHours(Radiation, peakSun, wfpiconsole.Astro, Device, Config, flagAPI) UVIndex = derive.UVIndex(UV) # Convert observation units as required Temp = observation.Units(Temp, Config['Units']['Temp']) MaxTemp = observation.Units(MaxTemp, Config['Units']['Temp']) MinTemp = observation.Units(MinTemp, Config['Units']['Temp']) DewPoint = observation.Units(DewPoint, Config['Units']['Temp']) FeelsLike = observation.Units(FeelsLike, Config['Units']['Temp']) SLP = observation.Units(SLP, Config['Units']['Pressure']) MaxPres = observation.Units(MaxPres, Config['Units']['Pressure']) MinPres = observation.Units(MinPres, Config['Units']['Pressure']) PresTrend = observation.Units(PresTrend, Config['Units']['Pressure']) StrikeDist = observation.Units(StrikeDist, Config['Units']['Distance']) RainRate = observation.Units(RainRate, Config['Units']['Precip']) TodayRain = observation.Units(rainAccum['Today'], Config['Units']['Precip']) YesterdayRain = observation.Units(rainAccum['Yesterday'], Config['Units']['Precip']) MonthRain = observation.Units(rainAccum['Month'], Config['Units']['Precip']) YearRain = observation.Units(rainAccum['Year'], Config['Units']['Precip']) WindSpd = observation.Units(WindSpd, Config['Units']['Wind']) WindDir = observation.Units(WindDir, Config['Units']['Direction']) WindGust = observation.Units(WindGust, Config['Units']['Wind']) AvgWind = observation.Units(AvgWind, Config['Units']['Wind']) MaxGust = observation.Units(MaxGust, Config['Units']['Wind']) FeelsLike = observation.Units(FeelsLike, Config['Units']['Temp']) # Store derived TEMPEST observations in dictionary derivedObs = {} derivedObs['outTemp'] = observation.Format(Temp, 'Temp') derivedObs['outTempMax'] = observation.Format(MaxTemp, 'Temp') derivedObs['outTempMin'] = observation.Format(MinTemp, 'Temp') derivedObs['DewPoint'] = observation.Format(DewPoint, 'Temp') derivedObs['FeelsLike'] = observation.Format(FeelsLike, 'Temp') derivedObs['Pres'] = observation.Format(SLP, 'Pressure') derivedObs['MaxPres'] = observation.Format(MaxPres, 'Pressure') derivedObs['MinPres'] = observation.Format(MinPres, 'Pressure') derivedObs['PresTrend'] = observation.Format(PresTrend, 'Pressure') derivedObs['StrikeDeltaT'] = observation.Format(StrikeDeltaT, 'TimeDelta') derivedObs['StrikeDist'] = observation.Format(StrikeDist, 'StrikeDistance') derivedObs['StrikeFreq'] = observation.Format(StrikeFreq, 'StrikeFrequency') derivedObs['Strikes3hr'] = observation.Format(Strikes3hr, 'StrikeCount') derivedObs['StrikesToday'] = observation.Format(StrikeCount['Today'], 'StrikeCount') derivedObs['StrikesMonth'] = observation.Format(StrikeCount['Month'], 'StrikeCount') derivedObs['StrikesYear'] = observation.Format(StrikeCount['Year'], 'StrikeCount') derivedObs['Humidity'] = observation.Format(Humidity, 'Humidity') derivedObs['FeelsLike'] = observation.Format(FeelsLike, 'Temp') derivedObs['RainRate'] = observation.Format(RainRate, 'Precip') derivedObs['TodayRain'] = observation.Format(TodayRain, 'Precip') derivedObs['YesterdayRain'] = observation.Format(YesterdayRain, 'Precip') derivedObs['MonthRain'] = observation.Format(MonthRain, 'Precip') derivedObs['YearRain'] = observation.Format(YearRain, 'Precip') derivedObs['WindSpd'] = observation.Format(WindSpd, 'Wind') derivedObs['WindGust'] = observation.Format(WindGust, 'Wind') derivedObs['AvgWind'] = observation.Format(AvgWind, 'Wind') derivedObs['MaxGust'] = observation.Format(MaxGust, 'Wind') derivedObs['WindDir'] = observation.Format(WindDir, 'Direction') derivedObs['Radiation'] = observation.Format(Radiation, 'Radiation') derivedObs['peakSun'] = observation.Format(peakSun, 'peakSun') derivedObs['UVIndex'] = observation.Format(UVIndex, 'UV') # Update wfpiconsole display with derived TEMPEST observations updateDisplay(derivedObs, wfpiconsole, 'Tempest') # Set flags for required API calls wfpiconsole.flagAPI[0] = 0 # Return wfpiconsole object return wfpiconsole
def Sky(Msg, wfpiconsole): """ Handles Websocket messages received from SKY module INPUTS: Msg Websocket messages received from SKY module wfpiconsole wfpiconsole object """ # Replace missing observations from latest SKY Websocket JSON with NaN Ob = [x if x != None else NaN for x in Msg['obs'][0]] # Discard duplicate SKY Websocket messages if 'SkyMsg' in wfpiconsole.Obs: if wfpiconsole.Obs['SkyMsg']['obs'][0] == Ob[0]: print('Discarding duplicate SKY Websocket message') return # Extract SKY device ID and API flag, and station configuration object Device = wfpiconsole.config['Station']['SkyID'] flagAPI = wfpiconsole.flagAPI[1] Config = wfpiconsole.config # Extract required observations from latest SKY Websocket JSON Time = [Ob[0], 's'] UV = [Ob[2], 'index'] Rain = [Ob[3], 'mm'] WindSpd = [Ob[5], 'mps'] WindGust = [Ob[6], 'mps'] WindDir = [Ob[7], 'degrees'] Radiation = [Ob[10], 'Wm2'] # Store latest SKY Websocket message wfpiconsole.Obs['SkyMsg'] = Msg # Extract required observations from latest AIR Websocket observations while not 'outAirMsg' in wfpiconsole.Obs: time.sleep(0.01) Ob = [ x if x != None else NaN for x in wfpiconsole.Obs['outAirMsg']['obs'][0] ] Temp = [Ob[2], 'c'] Humidity = [Ob[3], '%'] # Set wind direction to None if wind speed is zero if WindSpd[0] == 0: WindDir = [None, 'degrees'] # Extract required derived observations rainAccum = { 'Today': wfpiconsole.Obs['TodayRain'], 'Yesterday': wfpiconsole.Obs['YesterdayRain'], 'Month': wfpiconsole.Obs['MonthRain'], 'Year': wfpiconsole.Obs['YearRain'] } peakSun = wfpiconsole.Obs['peakSun'] avgWind = wfpiconsole.Obs['AvgWind'] maxGust = wfpiconsole.Obs['MaxGust'] # Calculate derived variables from SKY observations FeelsLike = derive.FeelsLike(Temp, Humidity, WindSpd, Config) RainRate = derive.RainRate(Rain) rainAccum = derive.RainAccumulation(Rain, rainAccum, Device, Config, flagAPI) AvgWind = derive.MeanWindSpeed(WindSpd, avgWind, Device, Config, flagAPI) MaxGust = derive.MaxWindGust(WindGust, maxGust, Device, Config, flagAPI) WindSpd = derive.BeaufortScale(WindSpd) WindDir = derive.CardinalWindDirection(WindDir, WindSpd) peakSun = derive.peakSunHours(Radiation, peakSun, wfpiconsole.Astro, Device, Config, flagAPI) UVIndex = derive.UVIndex(UV) # Convert observation units as required RainRate = observation.Units(RainRate, Config['Units']['Precip']) TodayRain = observation.Units(rainAccum['Today'], Config['Units']['Precip']) YesterdayRain = observation.Units(rainAccum['Yesterday'], Config['Units']['Precip']) MonthRain = observation.Units(rainAccum['Month'], Config['Units']['Precip']) YearRain = observation.Units(rainAccum['Year'], Config['Units']['Precip']) WindSpd = observation.Units(WindSpd, Config['Units']['Wind']) WindDir = observation.Units(WindDir, Config['Units']['Direction']) WindGust = observation.Units(WindGust, Config['Units']['Wind']) AvgWind = observation.Units(AvgWind, Config['Units']['Wind']) MaxGust = observation.Units(MaxGust, Config['Units']['Wind']) FeelsLike = observation.Units(FeelsLike, Config['Units']['Temp']) # Store derived SKY observations in dictionary derivedObs = {} derivedObs['FeelsLike'] = observation.Format(FeelsLike, 'Temp') derivedObs['RainRate'] = observation.Format(RainRate, 'Precip') derivedObs['TodayRain'] = observation.Format(TodayRain, 'Precip') derivedObs['YesterdayRain'] = observation.Format(YesterdayRain, 'Precip') derivedObs['MonthRain'] = observation.Format(MonthRain, 'Precip') derivedObs['YearRain'] = observation.Format(YearRain, 'Precip') derivedObs['WindSpd'] = observation.Format(WindSpd, 'Wind') derivedObs['WindGust'] = observation.Format(WindGust, 'Wind') derivedObs['AvgWind'] = observation.Format(AvgWind, 'Wind') derivedObs['MaxGust'] = observation.Format(MaxGust, 'Wind') derivedObs['WindDir'] = observation.Format(WindDir, 'Direction') derivedObs['Radiation'] = observation.Format(Radiation, 'Radiation') derivedObs['peakSun'] = observation.Format(peakSun, 'peakSun') derivedObs['UVIndex'] = observation.Format(UVIndex, 'UV') # Update wfpiconsole display with derived SKY observations updateDisplay(derivedObs, wfpiconsole, 'Sky') # Set flags for required API calls wfpiconsole.flagAPI[1] = 0 # Return wfpiconsole object return wfpiconsole