Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## WeatherFlow PiConsole: Raspberry Pi Python console for WeatherFlow Tempest
- ## and Smart Home Weather stations.
- ## Copyright (C) 2018-2021 Peter Davis
- ## This program is free software: you can redistribute it and/or modify it under
- ## the terms of the GNU General Public License as published by the Free Software
- ## Foundation, either version 3 of the License, or (at your option) any later
- ## version.
- ## This program is distributed in the hope that it will be useful, but WITHOUT
- ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- ## FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- ## details.
- ## You should have received a copy of the GNU General Public License along with
- ## this program. If not, see <http://www.gnu.org/licenses/>.
- ## Import required modules
- #:import NoTransition kivy.uix.screenmanager.NoTransition
- #:import Factory kivy.factory.Factory
- #:import utils kivy.utils
- ## Include required kv lang files
- #:include kvlang/displayElements.kv
- #:include kvlang/displayFields.kv
- #:include kvlang/panelLayout.kv
- ## =============================================================================
- ## SCREEN MANAGER
- ## =============================================================================
- ScreenManager:
- transition: NoTransition()
- CurrentConditions:
- id: CurrentConditions
- name: 'CurrentConditions'
- ## =============================================================================
- ## CURRRENT CONDITIONS SCREEN
- ## =============================================================================
- <CurrentConditions>:
- name: 'CurrentConditions'
- orientation: 'vertical'
- canvas.before:
- Color:
- rgba: utils.rgba('000000ff')
- Rectangle:
- pos: self.pos
- size: self.size
- BoxLayout:
- padding: ['2dp', '2dp', '2dp', '0dp']
- spacing: '3dp'
- orientation: 'vertical'
- BoxLayout:
- spacing: '4dp'
- orientation: 'vertical'
- BoxLayout:
- spacing: '5dp'
- BoxLayout:
- id: PanelOne
- BoxLayout:
- id: PanelTwo
- BoxLayout:
- id: PanelThree
- BoxLayout:
- spacing: '5dp'
- BoxLayout:
- id: PanelFour
- BoxLayout:
- id: PanelFive
- BoxLayout:
- id: PanelSix
- BoxLayout:
- spacing: '4dp'
- size_hint: (1,31/444)
- BoxLayout:
- id: ButtonOne
- BoxLayout:
- id: ButtonTwo
- BoxLayout:
- id: ButtonThree
- BoxLayout:
- id: ButtonFour
- BoxLayout:
- id: ButtonFive
- BoxLayout:
- id: ButtonSix
- BoxLayout:
- id: GraphsButton
- BoxLayout:
- PanelButton:
- id: 'mainPanelButton'
- text: 'Menu'
- on_release: Factory.mainMenu().open()
- ## =============================================================================
- ## WEATHERFLOW FORECAST PANEL AND BUTTON
- ## =============================================================================
- <ForecastPanel>:
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Forecast'
- ## Forecast Conditions
- TitleField:
- text: 'Conditions'
- pos_hint: {'x': 18/262, 'y': 166/202}
- size_hint_x: 77/262
- Image:
- source: 'icons/weather/' + app.MetData['Icon'] + app.scaleSuffix + '.png'
- pos_hint: {'x': 18/262, 'y': 83/202}
- size_hint: (77/262, 80/202)
- keep_ratio: 0
- allow_stretch: 1
- SmallMultilineField:
- text: app.MetData['Conditions']
- pos_hint: {'x': 110/262, 'y': 80/202}
- size_hint: (132/262, 62/202)
- halign: 'left'
- line_height: 1.2
- ## Forecast status
- BoldMultilineField:
- text: app.MetData['Status']
- pos_hint: {'x': 0/262, 'y': 97/202}
- size_hint: (262/262, 35/202)
- ## Forecast windspeed
- TitleField:
- text: 'Wind Speed'
- pos_hint: {'x': 132/262, 'y': 166/202}
- size_hint_x: 110/262
- MediumField:
- text: app.MetData['WindSpd'][0] + ' ' + app.MetData['WindSpd'][1] + ' ' + app.MetData['WindDir'][0]
- pos_hint: {'x': 132/262, 'y': 145/202}
- size_hint_x: (110/262)
- ## Forecast temperature
- TitleField:
- text: 'Temperature'
- pos_hint: {'x': 5/262, 'y': 65/202}
- size_hint_x: (125/262)
- MediumField:
- text: app.MetData['Temp'][0] + app.MetData['Temp'][1]
- pos_hint: {'x': 5/262, 'y': 43/202}
- size_hint_x: (125/262)
- SmallField:
- pos_hint: {'x': 5/262, 'y': 25/202}
- size_hint_x: (125/262)
- text:
- '[color=00a4b4ff][font=fonts/Inter-Bold.ttf]L: [/font]' + app.MetData['lowTemp'][0] + app.MetData['lowTemp'][1] + '[/color]' + ' ' + \
- '[color=f05e40ff]' + '[font=fonts/Inter-Bold.ttf]H: [/font]' + app.MetData['highTemp'][0] + app.MetData['highTemp'][1] + '[/color]'
- ## Forecast rain/snowfall
- TitleField:
- text: app.MetData['PrecipType'].title() + 'fall'
- pos_hint: {'x': 152/262, 'y': 65/202}
- size_hint_x: (100/262)
- MediumField:
- text: app.MetData['PrecipPercnt'][0] + app.MetData['PrecipPercnt'][1]
- pos_hint: {'x': 152/262, 'y': 43/202}
- size_hint_x: (100/262)
- SmallField:
- text: '[color=ffffffff]Daily[/color]: ' + app.MetData['PrecipDay'][0] + app.MetData['PrecipDay'][1]
- pos_hint: {'x': 152/262, 'y': 25/202}
- size_hint_x: (100/262)
- ## Forecast valid time
- SmallField:
- text: 'Forecast for ' + app.MetData['Valid']
- pos_hint: {'x': 5/262, 'y': 2/202}
- size_hint: (252/262, 17/202)
- text_size: self.size
- halign: 'right'
- <ForecastButton>:
- PanelButton:
- id: 'ForecastButton'
- text: 'Forecast'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## SAGER FORECAST PANEL AND BUTTON
- ## =============================================================================
- <SagerPanel>:
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Sager Forecast'
- ## Sager Weathercaster forecast
- MediumMultilineField:
- text: app.Sager['Forecast']
- pos_hint: {'x': 5/262, 'y': 21/202}
- size_hint: (252/262, 157/202)
- ## Forecast issue time
- SmallField:
- text: 'Forecast issued: ' + app.Sager['Issued']
- pos_hint: {'x': 5/262, 'y': 2/202}
- size_hint: (252/262, 17/202)
- text_size: self.size
- halign: 'right'
- <SagerButton>:
- PanelButton:
- id: 'SagerButton'
- text: 'Sager'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## TEMPERATURE WIDGET
- ## =============================================================================
- <TemperaturePanel>:
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Temperature'
- ## Indoor temperature
- TitleField:
- text: 'Indoor'
- pos_hint: {'x': 0/262, 'y': 166/202}
- size_hint_x: (131/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- LargeField:
- text: app.Obs['inTemp'][0] + app.Obs['inTemp'][1]
- pos_hint: {'x': 0/262, 'y': 132/202}
- size_hint_x: (131/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- ## Indoor temperature minimum
- MediumField:
- text: '[size=' + str(int(self.font_size*0.88)) + '][color=00a4b4ff]' + app.Obs['inTempMin'][0] + '[size=' + str(int(self.font_size*0.83)) + ']' + app.Obs['inTempMin'][1] + '[/color][/size][/size]'
- pos_hint: {'x': 0/262, 'y': 106/202}
- size_hint_x: (65.5/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- SmallField:
- text: app.Obs['inTempMin'][2]
- pos_hint: {'x': 0/262, 'y': 86/202}
- size_hint_x: (65.5/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- ## Indoor temperature maximum
- MediumField:
- text: '[size=' + str(int(self.font_size*0.88)) + '][color=f05e40ff]' + app.Obs['inTempMax'][0] + '[size=' + str(int(self.font_size*0.83)) + ']' + app.Obs['inTempMax'][1] + '[/color][/size][/size]'
- pos_hint: {'x': 65.5/262, 'y': 106/202}
- size_hint_x: (65.5/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- SmallField:
- text: app.Obs['inTempMax'][2]
- pos_hint: {'x': 65.5/262, 'y': 86/202}
- size_hint_x: (65.5/262)
- opacity: 1 if app.IndoorTemp == '1' else 0
- ## Outdoor temperature
- TitleField:
- text: 'Outdoor'
- pos_hint: {'x': 131/262 if app.IndoorTemp == '1' else 0/262, 'y': 166/202}
- size_hint_x: (131/262 if app.IndoorTemp == '1' else 262/262)
- LargeField:
- text: app.Obs['outTemp'][0] + app.Obs['outTemp'][1]
- pos_hint: {'x': 131/262 if app.IndoorTemp == '1' else 65.5/262, 'y': 132/202}
- size_hint_x: (131/262)
- ## Outdoor temperature minimum
- MediumField:
- text: '[size=' + str(int(self.font_size*0.88)) + '][color=00a4b4ff]' + app.Obs['outTempMin'][0] + '[size=' + str(int(self.font_size*0.83)) + ']' + app.Obs['outTempMin'][1] + '[/color][/size][/size]'
- pos_hint: {'x': 131/262 if app.IndoorTemp == '1' else 65.5/262, 'y': 106/202}
- size_hint_x: (65.5/262)
- SmallField:
- text: app.Obs['outTempMin'][2]
- pos_hint: {'x': 131/262 if app.IndoorTemp == '1' else 65.5/262, 'y': 86/202}
- size_hint_x: (65.5/262)
- ## Outdoor temperature maximum
- MediumField:
- text: '[size=' + str(int(self.font_size*0.88)) + '][color=f05e40ff]' + app.Obs['outTempMax'][0] + '[size=' + str(int(self.font_size*0.83)) + ']' + app.Obs['outTempMax'][1] + '[/color][/size][/size]'
- pos_hint: {'x': 196.5/262 if app.IndoorTemp == '1' else 131/262, 'y': 106/202}
- size_hint_x: (65.5/262)
- SmallField:
- text: app.Obs['outTempMax'][2]
- pos_hint: {'x': 196.5/262 if app.IndoorTemp == '1' else 131/262, 'y': 86/202}
- size_hint_x: (65.5/262)
- ## 'Feels like' temperature
- TitleField:
- text: 'Feels Like'
- pos_hint: {'x': 0/262, 'y': 65/202}
- size_hint_x: (87.330/262)
- MediumField:
- text: app.Obs['FeelsLike'][0] + app.Obs['FeelsLike'][1]
- pos_hint: {'x': 0/262, 'y': 43/202}
- size_hint_x: (87.330/262)
- ## Outdoor humidity
- TitleField:
- text: 'Humidity'
- pos_hint: {'x': 87.330/262, 'y': 65/202}
- size_hint_x: (87.330/262)
- MediumField:
- text: app.Obs['Humidity'][0] + app.Obs['Humidity'][1]
- pos_hint: {'x': 87.330/262, 'y': 43/202}
- size_hint_x: (87.330/262)
- ## Dew point
- TitleField:
- text: 'Dew Point'
- pos_hint: {'x': 174.660/262, 'y': 65/202}
- size_hint_x: (87.330/262)
- MediumField:
- text: app.Obs['DewPoint'][0] + app.Obs['DewPoint'][1]
- pos_hint: {'x': 174.660/262, 'y': 43/202}
- size_hint_x: (87.330/262)
- ## 'Feels like' icon and text
- Image:
- source: 'atlas://atlas/feelsLike/' + root.feelsLikeIcon + app.scaleSuffix
- pos_hint: {'x': 7/262, 'y': 7/202}
- size_hint: (36/262, 31/202)
- keep_ratio: 0
- allow_stretch: 1
- SmallField:
- text: app.Obs['FeelsLike'][2]
- pos_hint: {'x': 49/262, 'y': 10/202}
- size_hint: (200/262, 17/202)
- text_size: self.size
- halign: 'left'
- <TemperatureButton>:
- PanelButton:
- id: 'TemperatureButton'
- text: 'Temperature'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## WIND SPEED AND DIRECTION WIDGET
- ## =============================================================================
- <WindSpeedPanel>:
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Wind Speed [size=' + str(int(self.ids.Title.font_size*0.8)) + ']|[/size] Direction'
- ## Rapid Wind wind speed and direction
- windRose:
- Image:
- source: 'icons/windrose/icons' + app.scaleSuffix + '/' + str(round(root.rapidWindDir)) + '.png'
- pos_hint: {'x': 0, 'y': 0}
- size_hint: (1, 1)
- keep_ratio: 0
- allow_stretch: 1
- ## Current average wind speed
- LargeField:
- text: app.Obs['WindSpd'][0]
- pos_hint: {'x': 3/262, 'y': 95/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['WindSpd'][1]
- pos_hint: {'x': 3/262, 'y': 78/202}
- size_hint_x: (60/262)
- ## Daily averaged wind speed
- SmallField:
- text: 'Avg [color=ff8837ff]' + app.Obs['AvgWind'][0] + '[/color] ' + app.Obs['AvgWind'][1]
- pos_hint: {'x': 3/262, 'y': 164/202}
- size_hint_x: (101/262)
- SmallField:
- text: 'Wind'
- pos_hint: {'x': 3/262, 'y': 147/202}
- size_hint_x: (101/262)
- ## Current wind gust
- LargeField:
- text: app.Obs['WindGust'][0]
- pos_hint: {'x': 201/262, 'y': 95/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['WindGust'][1]
- pos_hint: {'x': 201/262, 'y': 78/202}
- size_hint_x: (60/262)
- ## Maximum wind gust
- SmallField:
- text: 'Max [color=ff8837ff]' + app.Obs['MaxGust'][0] + '[/color] ' + app.Obs['MaxGust'][1]
- pos_hint: {'x': 159/262, 'y': 164/202}
- size_hint_x: (101/262)
- SmallField:
- text: 'Gust'
- pos_hint: {'x': 159/262, 'y': 147/202}
- size_hint_x: (101/262)
- ## Current Beaufort scale text and icon
- Image:
- source: 'atlas://atlas/windSpd/' + root.windSpdIcon + app.scaleSuffix
- pos_hint: {'x': 18/262, 'y': 28/202}
- size_hint: (30/262, 30/202)
- keep_ratio: 0
- allow_stretch: 1
- SmallField:
- text: app.Obs['WindSpd'][4]
- pos_hint: {'x': 6/262, 'y': 6/202}
- size_hint: (126/262, 17/202)
- text_size: self.size
- halign: 'left'
- ## Current average wind direction
- Image:
- source: 'atlas://atlas/windDir/' + root.windDirIcon + app.scaleSuffix
- pos_hint: {'x': 216/262, 'y': 28/202}
- size_hint: (30/262, 30/202)
- keep_ratio: 0
- allow_stretch: 1
- SmallField:
- text: 'Direction: [color=9aba2fff]' + app.Obs['WindDir'][0] + app.Obs['WindDir'][1] + '[/color]'
- pos_hint: {'x': 119/262, 'y': 6/202}
- size_hint: (135/262, 17/202)
- text_size: self.size
- halign: 'right'
- ## Rapid wind direction in degrees
- MediumField:
- text: app.Obs['rapidDir'][0] + app.Obs['rapidDir'][1]
- pos_hint: {'x': 102/262, 'y': 116/202}
- size_hint_x: (60/262)
- ## Rapid wind speed
- MediumField:
- text: app.Obs['rapidSpd'][0] + ' [size=' + str(int(self.font_size*0.8)) + ']' + app.Obs['rapidSpd'][1] + '[/size]'
- pos_hint: {'x': 92/262, 'y': 89/202}
- size_hint_x: (80/262)
- ## Rapid wind direction text
- SmallField:
- text: app.Obs['rapidDir'][3]
- pos_hint: {'x': 92/262, 'y': 65.5/202}
- size_hint_x: (80/262)
- <WindSpeedButton>:
- PanelButton:
- id: 'WindSpeedButton'
- text: 'Wind Speed'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## SUNRISE/SUNSET WIDGET
- ## =============================================================================
- <SunriseSunsetPanel>:
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Solar [size=' + str(int(self.ids.Title.font_size*0.8)) + ']|[/size] UV Index'
- ## Night bar
- BoxLayout:
- pos_hint: {'x': 13/262, 'y': 96/202}
- size_hint: [236/262, 10/202]
- canvas.after:
- Color:
- rgba: [100/255,100/255,100/255,1]
- Rectangle:
- pos: self.pos
- size: self.size
- ## Dawn/Dusk bar
- BoxLayout:
- pos_hint: {'x': (13+app.Astro['Dawn'][2]*236)/262, 'y': 96/202}
- size_hint: [(app.Astro['Dusk'][2]*236)/262, 10/202]
- canvas.after:
- Color:
- rgba: [29/255,74/255,87/255,1]
- Rectangle:
- pos: self.pos
- size: self.size
- ## Sunrise/sunset bar
- BoxLayout:
- pos_hint: {'x': (13+app.Astro['Sunrise'][2]*236)/262, 'y': 96/202}
- size_hint: [(app.Astro['Sunset'][2]*236)/262, 10/202]
- canvas.after:
- Color:
- rgba: [0/255,113/255,123/255,1]
- Rectangle:
- pos: self.pos
- size: self.size
- ## Sun bar and icon position
- BoxLayout:
- pos_hint: {'x': 13/262, 'y': 94/202}
- size_hint: [236/262, 14/202]
- canvas.after:
- Color:
- rgba: [230/255,75/255,36/255,app.Astro['sunIcon'][1]]
- Line:
- width: 1.2 * app.scaleFactor
- rectangle: [self.x + app.Astro['sunIcon'][2]*self.width, self.y, 1, self.height]
- Image:
- source: 'atlas://atlas/sunIcon/' + app.Astro['sunIcon'][0] + app.scaleSuffix
- pos_hint: {'x': (4+app.Astro['sunIcon'][2]*236)/262, 'y': 92/202}
- size_hint: (18/262, 18/202)
- keep_ratio: 0
- allow_stretch: 1
- ## Solar radiation
- TitleField:
- text: 'Radiation'
- pos_hint: {'x': 3/262, 'y': 166/202}
- size_hint_x: (105/262)
- MediumField:
- text: app.Obs['Radiation'][0] + app.Obs['Radiation'][1]
- pos_hint: {'x': 3/262, 'y': 138/202}
- size_hint_x: (105/262)
- ## UV Index
- TitleField:
- text: 'UV Index'
- pos_hint: {'x': 125/262, 'y': 166/202}
- size_hint_x: (120/262)
- MediumField:
- text: app.Obs['UVIndex'][0]
- pos_hint: {'x': 125/262, 'y': 138/202}
- size_hint_x: (40/262)
- TitleField:
- text: app.Obs['UVIndex'][2]
- pos_hint: {'x': 170/262, 'y': 140/202}
- size_hint_x: (75/262)
- color: utils.rgba('#000000ff')
- canvas.before:
- Color:
- rgba: utils.rgba(root.uvBackground) if root.uvBackground != '-' else utils.rgba('000000ff')
- RoundedRectangle:
- pos: [self.pos[0],self.pos[1]-4*app.scaleFactor]
- size: (self.width,self.height+8*app.scaleFactor)
- radius: [5,]
- ## Sunrise time
- TitleField:
- text: 'Sunrise'
- pos_hint: {'x': 13/262, 'y': 113/202}
- size_hint: (55/262, 17/202)
- text_size: self.size
- halign: 'left'
- SmallField:
- text: app.Astro['Sunrise'][1]
- pos_hint: {'x': 13/262, 'y': 73/202}
- size_hint: (80/262, 17/202)
- text_size: self.size
- halign: 'left'
- ## Sunset time
- TitleField:
- text: 'Sunset'
- pos_hint: {'x': 194/262, 'y': 113/202}
- size_hint: (55/262, 17/202)
- text_size: self.size
- halign: 'right'
- SmallField:
- text: app.Astro['Sunset'][1]
- pos_hint: {'x': 169/262, 'y': 73/202}
- size_hint: (80/262, 17/202)
- text_size: self.size
- halign: 'right'
- ## Time remaining until sunrise or sunset
- TitleField:
- text: app.Astro['sunEvent'][3]
- pos_hint: {'x': 24/262, 'y': 50/202}
- size_hint_x: (80/262)
- MediumField:
- text: app.Astro['sunEvent'][1]
- pos_hint: {'x': 10/262, 'y': 27/202}
- size_hint_x: (30/262)
- TitleField:
- text: 'hrs'
- font_size: dp(10.9*app.scaleFactor)
- pos_hint: {'x': 40/262, 'y': 25/202}
- size_hint_x: (20/262)
- color: utils.rgba('ffffffff')
- MediumField:
- text: app.Astro['sunEvent'][2]
- pos_hint: {'x': 60/262, 'y': 27/202}
- size_hint_x: (30/262)
- TitleField:
- text: 'mins'
- font_size: dp(10.9*app.scaleFactor)
- pos_hint: {'x': 90/262, 'y': 25/202}
- size_hint_x: (28/262)
- color: utils.rgba('ffffffff')
- SmallField:
- text: 'Till ' + app.Astro['sunEvent'][0]
- pos_hint: {'x': 24/262, 'y': 5/202}
- size_hint_x: (80/262)
- ## Peak Sun Hours
- TitleField:
- text: 'Peak Sun Hours'
- pos_hint: {'x': 132/262, 'y': 50/202}
- size_hint_x: (120/262)
- MediumField:
- text: app.Obs['peakSun'][0]
- pos_hint: {'x': 152/262, 'y': 26/202}
- size_hint_x: (80/262)
- SmallField:
- text: 'Solar: ' + app.Obs['peakSun'][4]
- pos_hint: {'x': 132/262, 'y': 5/202}
- size_hint_x: (120/262)
- <SunriseSunsetButton>:
- PanelButton:
- id: 'SunriseButton'
- text: 'Solar'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## MOON PHASE WIDGET
- ## =============================================================================
- <MoonPhasePanel>
- ## Panel background, title, and MoonRose
- PanelBackground:
- _panelTitle: 'Moon Phase'
- moonRose:
- ## Moonrise time
- TitleField:
- text: 'Moonrise'
- pos_hint: {'x': 5/262, 'y': 23/202}
- size_hint_x: (80/262)
- SmallField:
- text: app.Astro['Moonrise'][1]
- pos_hint: {'x': 5/262, 'y': 5/202}
- size_hint_x: (80/262)
- ## Moonset time
- TitleField:
- text: 'Moonset'
- pos_hint: {'x': 177/262, 'y': 23/202}
- size_hint_x: (80/262)
- SmallField:
- text: app.Astro['Moonset'][1]
- pos_hint: {'x': 177/262, 'y': 5/202}
- size_hint_x: (80/262)
- ## Next new moon
- TitleField:
- text: 'Next'
- pos_hint: {'x': 6/262, 'y': 170/202}
- size_hint_x: (70/262)
- TitleField:
- text: '[color=00a4b4ff]New[/color] Moon'
- pos_hint: {'x': 6/262, 'y': 156/202}
- size_hint_x: (70/262)
- SmallField:
- text: app.Astro['NewMoon'][0]
- pos_hint: {'x': 6/262, 'y': 138/202}
- size_hint_x: (70/262)
- ## Next full moon
- TitleField:
- text: 'Next'
- pos_hint: {'x': 186/262, 'y': 170/202}
- size_hint_x: (70/262)
- TitleField:
- text: '[color=f05e40ff]Full[/color] Moon'
- pos_hint: {'x': 186/262, 'y': 156/202}
- size_hint_x: (70/262)
- SmallField:
- text: app.Astro['FullMoon'][0]
- pos_hint: {'x': 186/262, 'y': 138/202}
- size_hint_x: (70/262)
- ## Moon phase icon
- Image:
- source: 'atlas://atlas/moonIcon' + app.scaleSuffix + '/' + app.Astro['Phase'][0]
- pos_hint: {'x': 108/262, 'y': 93/202}
- size_hint: (46/262, 46/202)
- keep_ratio: 0
- allow_stretch: 1
- ## Moon phase text
- SmallField:
- text: app.Astro['Phase'][1]
- pos_hint: {'x': 75/262, 'y': 72/202}
- size_hint_x: (112/262)
- ## Moon illuminance text
- SmallField:
- text: app.Astro['Phase'][2] + '% Illumin.'
- pos_hint: {'x': 86/262, 'y': 52/202}
- size_hint_x: (90/262)
- <MoonPhaseButton>:
- PanelButton:
- id: 'MoonPhaseButton'
- text: 'Moon'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## RAINFALL WIDGET
- ## =============================================================================
- <RainfallPanel>
- ## Panel background, title, and RainGauge
- RainfallBackground:
- _panelTitle: 'Rainfall'
- RainGauge:
- ## Current rain rate and text
- SmallField:
- text: app.Obs['RainRate'][2]
- pos_hint: {'x': 1/262, 'y': 57/202}
- size_hint_x: (176/262)
- SmallField:
- text: app.Obs['RainRate'][0] + app.Obs['RainRate'][1]
- pos_hint: {'x': 175/262, 'y': 57/202}
- size_hint_x: (86/262)
- ## Rain rate animation
- StencilView:
- pos_hint: {'x': 202/262, 'y': 81/202}
- size_hint: (33/262, 108/202)
- FloatLayout:
- width: self.parent.height*(264/108)
- height: self.parent.height
- pos: self.parent.pos
- Image:
- source: 'atlas://atlas/rainGauge/rainGauge' + app.scaleSuffix
- keep_ratio: 0
- allow_stretch: 1
- size_hint: (1,1)
- pos_hint: {'x': root.rainRatePosX, 'y': root.rainRatePosY}
- ## Total daily rainfall
- TitleField:
- text: 'Today'
- pos_hint: {'x': 1/262, 'y': 166/202}
- size_hint_x: (88/262)
- MediumField:
- text: app.Obs['TodayRain'][0] + '[size=' + str(int(self.font_size*0.85)) + ']' + app.Obs['TodayRain'][1] + '[/size]'
- pos_hint: {'x': 1/262, 'y': 138/202}
- size_hint_x: (88/262)
- ## Total yesterday rainfall
- TitleField:
- text: 'Yesterday'
- pos_hint: {'x': 89/262, 'y': 166/202}
- size_hint_x: (88/262)
- MediumField:
- text: app.Obs['YesterdayRain'][0] + '[size=' + str(int(self.font_size*0.85)) + ']' + app.Obs['YesterdayRain'][1] + '[/size]'
- pos_hint: {'x': 89/262, 'y': 138/202}
- size_hint_x: (88/262)
- ## Total monthly rainfall
- TitleField:
- text: 'Month'
- pos_hint: {'x': 1/262, 'y': 111/202}
- size_hint_x: (88/262)
- MediumField:
- text: app.Obs['MonthRain'][0] + '[size=' + str(int(self.font_size*0.85)) + ']' + app.Obs['MonthRain'][1] + '[/size]'
- pos_hint: {'x': 1/262, 'y': 83/202}
- size_hint_x: (88/262)
- ## Total yearly rainfall
- TitleField:
- text: 'Year'
- pos_hint: {'x': 89/262, 'y': 111/202}
- size_hint_x: (88/262)
- MediumField:
- text: app.Obs['YearRain'][0] + '[size=' + str(int(self.font_size*0.85)) + ']' + app.Obs['YearRain'][1] + '[/size]'
- pos_hint: {'x': 89/262, 'y': 83/202}
- size_hint_x: (88/262)
- ## Time and date
- TimeDateField:
- text: app.System['Date']
- pos_hint: {'x': 0/262, 'y': 24/202}
- size_hint_x: (262/262)
- TimeDateField:
- text: app.System['Time']
- pos_hint: {'x': 0/262, 'y': 3/202}
- size_hint_x: (262/262)
- <RainfallButton>:
- PanelButton:
- id: 'RainfallButton'
- text: 'Rainfall'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## LIGHTNING WIDGET
- ## =============================================================================
- <LightningPanel>
- ## Panel background and title
- PanelBackground:
- _panelTitle: 'Lightning'
- ## Last strike time
- TitleField:
- text:
- 'Last Strike' if app.Obs['StrikeDeltaT'][4] == '-' else \
- 'Strike Detected!' if app.Obs['StrikeDeltaT'][4] < 360 else \
- 'Last Strike'
- pos_hint: {'x': 83/262, 'y': 168/202}
- size_hint_x: (176/262)
- LargeField:
- text: app.Obs['StrikeDeltaT'][0]
- pos_hint: {'x': 83/262, 'y': 139/202}
- size_hint_x: (80/262 if app.Obs['StrikeDeltaT'][2] == '-' else 40/262)
- TitleField:
- text: app.Obs['StrikeDeltaT'][1]
- font_size: dp(13*app.scaleFactor)
- pos_hint: {'x': 83/262, 'y': 123/202}
- size_hint_x: (80/262 if app.Obs['StrikeDeltaT'][2] == '-' else 40/262)
- LargeField:
- text: app.Obs['StrikeDeltaT'][2]
- opacity: 0 if app.Obs['StrikeDeltaT'][2] == '-' else 1
- pos_hint: {'x': 123/262, 'y': 139/202}
- size_hint_x: (40/262)
- TitleField:
- text: app.Obs['StrikeDeltaT'][3]
- font_size: dp(13*app.scaleFactor)
- opacity: 0 if app.Obs['StrikeDeltaT'][2] == '-' else 1
- pos_hint: {'x': 123/262, 'y': 123/202}
- size_hint_x: (40/262)
- SmallField:
- text: '[color=f05e40ff]ago[/color]'
- pos_hint: {'x': 83/262, 'y': 108/202}
- size_hint_x: (80/262)
- ## Last strike distance
- LargeField:
- text: app.Obs['StrikeDist'][0]
- pos_hint: {'x': 169/262, 'y': 139/202}
- size_hint_x: (90/262)
- TitleField:
- text: app.Obs['StrikeDist'][1]
- font_size: dp(13*app.scaleFactor)
- pos_hint: {'x': 169/262, 'y': 123/202}
- size_hint_x: (90/262)
- SmallField:
- text: '[color=f05e40ff]away[/color]'
- pos_hint: {'x': 169/262, 'y': 108/202}
- size_hint_x: (90/262)
- ## Last three hour lightning strikes
- TitleField:
- text: 'Strike Count'
- pos_hint: {'x': 6/262, 'y': 88/202}
- size_hint_x: (132/262)
- TitleField:
- text: '3 hours'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 6/262, 'y': 70/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['Strikes3hr'][0]
- pos_hint: {'x': 6/262, 'y': 49/202}
- size_hint_x: (60/262)
- ## Total daily lightning strikes
- TitleField:
- text: 'Today'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 78/262, 'y': 70/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['StrikesToday'][0]
- pos_hint: {'x': 78/262, 'y': 49/202}
- size_hint_x: (60/262)
- ## Total monthly lightning strikes
- TitleField:
- text: 'Month'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 6/262, 'y': 28/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['StrikesMonth'][0]
- pos_hint: {'x': 6/262, 'y': 7/202}
- size_hint_x: (60/262)
- ## Total yearly lightning strikes
- TitleField:
- text: 'Year'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 78/262, 'y': 28/202}
- size_hint_x: (60/262)
- MediumField:
- text: app.Obs['StrikesYear'][0]
- pos_hint: {'x': 78/262, 'y': 7/202}
- size_hint_x: (60/262)
- ## Strike frequency last ten minutes
- TitleField:
- text: 'Strike Frequency'
- pos_hint: {'x': 143/262, 'y': 88/202}
- size_hint_x: (114/262)
- TitleField:
- text: '10 Minutes'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 143/262, 'y': 70/202}
- size_hint_x: (114/262)
- MediumField:
- text: app.Obs['StrikeFreq'][0] + app.Obs['StrikeFreq'][1]
- pos_hint: {'x': 143/262, 'y': 49/202}
- size_hint_x: (114/262)
- ## Strike frequency last three hours
- TitleField:
- text: '3 hours'
- color: utils.rgba('ffffffff')
- pos_hint: {'x': 143/262, 'y': 28/202}
- size_hint_x: (114/262)
- MediumField:
- text: app.Obs['StrikeFreq'][2] + app.Obs['StrikeFreq'][3]
- pos_hint: {'x': 143/262, 'y': 7/202}
- size_hint_x: (114/262)
- ## Lightning bolt icon
- Image:
- canvas.before:
- PushMatrix
- Translate:
- x: root.lightningBoltPosX
- canvas.after:
- PopMatrix
- source: 'atlas://atlas/lightningBolt/' + root.lightningBoltIcon + app.scaleSuffix
- keep_ratio: 0
- allow_stretch: 1
- pos_hint: {'x': 9/262, 'y': 120/202}
- size_hint: (65/262, 68/202)
- <LightningButton>:
- PanelButton:
- id: 'LightningButton'
- text: 'Lightning'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## BAROMETER WIDGET
- ## =============================================================================
- <BarometerPanel>:
- ## Panel background, title, and Barometer dial
- PanelBackground:
- _panelTitle: 'Barometer'
- barometerDial:
- ## Current pressure arrow
- Image:
- source: 'icons/barometer/icons' + app.scaleSuffix + '/' + root.barometerArrow + '.png'
- keep_ratio: 0
- allow_stretch: 1
- pos_hint: {'x': 46/262, 'y': 18/202}
- size_hint: (168/262, 84/202)
- ## Maximum and minimum pressure on pressure dial
- TitleField:
- text: app.BarometerMin
- pos_hint: {'x': 29/262, 'y': 4/202}
- size_hint_x: (40/262)
- TitleField:
- text: app.BarometerMax
- pos_hint: {'x': 191/262, 'y': 4/202}
- size_hint_x: (40/262)
- ## Current pressure
- TitleField:
- text: 'SLP'
- pos_hint: {'x': 80/262, 'y': 64/202}
- size_hint_x: (100/262)
- LargeField:
- text: app.Obs['Pres'][0]
- pos_hint: {'x': 80/262, 'y': 35/202}
- size_hint_x: (100/262)
- SmallField:
- text: app.Obs['Pres'][1]
- pos_hint: {'x': 80/262, 'y': 17/202}
- size_hint_x: (100/262)
- ## Current pressure trend
- TitleField:
- text: 'Trend'
- pos_hint: {'x': 155/262, 'y': 166/202}
- size_hint_x: (96/262)
- SmallField:
- text: app.Obs['PresTrend'][2]
- pos_hint: {'x': 155/262, 'y': 148/202}
- size_hint_x: (96/262)
- SmallField:
- text: app.Obs['PresTrend'][0] + app.Obs['PresTrend'][1]
- pos_hint: {'x': 155/262, 'y': 129/202}
- size_hint_x: (96/262)
- ## 24 Hour pressure low
- TitleField:
- text: 'Low'
- pos_hint: {'x': 3/262, 'y': 166/202}
- size_hint_x: (70/262)
- SmallField:
- text: '[color=00a4b4ff]' + app.Obs['MinPres'][0] + '[/color]'
- pos_hint: {'x': 3/262, 'y': 148/202}
- size_hint_x: (70/262)
- SmallField:
- text: app.Obs['MinPres'][2]
- pos_hint: {'x': 3/262, 'y': 129/202}
- size_hint_x: (70/262)
- ## 24 Hour pressure high
- TitleField:
- text: 'High'
- pos_hint: {'x': 73/262, 'y': 166/202}
- size_hint_x: (70/262)
- SmallField:
- text: '[color=f05e40ff]' + app.Obs['MaxPres'][0] + '[/color]'
- pos_hint: {'x': 73/262, 'y': 148/202}
- size_hint_x: (70/262)
- SmallField:
- text: app.Obs['MaxPres'][2]
- pos_hint: {'x': 73/262, 'y': 129/202}
- size_hint_x: (70/262)
- ## Weather tendency
- SmallField:
- text: app.Obs['PresTrend'][3]
- pos_hint: {'x': 21/262, 'y': 109/202}
- size_hint_x: (220/262)
- <BarometerButton>:
- PanelButton:
- id: 'BarometerButton'
- text: 'Pressure'
- on_release: app.CurrentConditions.SwitchPanel(self)
- ## =============================================================================
- ## UPDATE NOTIFICATION
- ## =============================================================================
- <updateNotif>:
- size_hint: (None, 76/480)
- pos_hint: {'x': app.CurrentConditions.ids.PanelSix.x/app.window.width, 'y': 2/app.window.height}
- width: app.CurrentConditions.ids.PanelSix.size[0]
- UpdateNotifBackground:
- _panelTitle: 'Update Available'
- RelativeLayout:
- BoldField:
- text: 'Current version:'
- pos_hint: {'x': 0.03, 'y': 0.5}
- size_hint: (0.47, 14/76)
- text_size: self.size
- halign: 'left'
- BoldField:
- text: app.config['System']['Version']
- pos_hint: {'x': 0.5, 'y': 0.52}
- size_hint: (0.3, 14/76)
- BoldField:
- text: 'Latest version:'
- pos_hint: {'x': 0.03, 'y': 0.28}
- size_hint: (0.47, 14/76)
- text_size: self.size
- halign: 'left'
- BoldField:
- text: '[color=9aba2fff]' + app.Version['Latest'] + '[/color]'
- pos_hint: {'x': 0.5, 'y': 0.30}
- size_hint: (0.3, 14/76)
- BoldField:
- text: 'Run: [font=fonts/Inter-BoldItalic.ttf][color=00a4b4ff]wfpiconsole update[/color][/font]'
- pos_hint: {'x': 0, 'y': 0.08}
- size_hint: (1, 14/76)
- ## =============================================================================
- ## MAIN MENU
- ## =============================================================================
- <mainMenu>:
- statusPanel: statusPanel.__self__
- size_hint: (.8, .8)
- canvas:
- Color:
- rgba: 0,0,0,1
- Rectangle:
- pos: self.pos
- size: self.size
- GridLayout:
- padding: '5dp'
- cols: 1
- size_hint: None, None
- pos: root.pos
- size: root.size
- TabbedPanel:
- background_color: (0, 0, 0,0)
- do_default_tab: False
- tab_pos: 'bottom_left'
- tab_height: 40*app.scaleFactor
- tab_width: 100*app.scaleFactor
- MainMenuTab:
- text: 'System'
- MainMenuLayout:
- id: statusPanel
- BoxLayout:
- orientation: 'vertical'
- padding: [dp(0),dp(0),dp(0),dp(10)]
- size_hint: (1,.22)
- MenuField:
- font_size: dp(16*app.scaleFactor)
- text: app.config['Station']['Name']
- MenuField:
- text: 'Station status: ' + app.Station.Device['stationStatus']
- GridLayout:
- cols: 2
- orientation: 'vertical'
- padding: [dp(0),dp(0),dp(0),dp(10)]
- size_hint: (1,.28)
- MenuField:
- text: 'Station time: ' + app.System['Time']
- MenuField:
- text: 'Station elevation: ' + '{:.2f}'.format(float(app.config['Station']['Elevation'])) + ' m'
- MenuField:
- text: 'Station latitude: ' + '{:.4f}'.format(float(app.config['Station']['Latitude'])) + '\u00B0'
- MenuField:
- text: 'Station Longitude: ' + '{:.4f}'.format(float(app.config['Station']['Longitude'])) + '\u00B0'
- MenuField:
- text: 'Hub firmware: ' + app.Station.Device['hubFirmware']
- MenuField:
- text: 'Console version: [color=00a4b4ff]' + app.config['System']['Version'] + '[/color]'
- BoxLayout:
- orientation: 'horizontal'
- size_hint: (1,.1)
- StatusColumn:
- size_hint: (.15,1)
- text: 'Device'
- StatusColumn:
- size_hint: (.12,1)
- text: 'Status'
- StatusColumn:
- size_hint: (.22,1)
- text: 'Last Observation'
- StatusColumn:
- size_hint: (.20,1)
- text: 'Battery Voltage'
- StatusColumn:
- size_hint: (.31,1)
- text: '24 hr Observation Count'
- MainMenuTab:
- text: 'Credits'
- MainMenuLayout:
- CreditsMultilineField:
- text:
- 'Python Console for Weather Flow Tempest and Smart Home Weather Station \n' \
- 'Code written by Peter Davis. Copyright 2018-2020 \n' \
- 'GNU General Public License v3.0 \n\n' \
- 'Graphics inspired by Weather34 Home Weather Station \n' \
- 'Copyright 2015-2020 Brian Underdown \n' \
- 'CC Attribution-NonCommercial-NoDerivatives 4.0 International License \n' \
- 'www.weather34.com/homeweatherstation/ \n\n' \
- 'Weather forecast data provided by \n' \
- 'WeatherFlow BetterForecast API \n'
Advertisement
Add Comment
Please, Sign In to add comment