{"id":5250,"date":"2024-05-02T13:29:26","date_gmt":"2024-05-02T11:29:26","guid":{"rendered":"https:\/\/home.et.utwente.nl\/slootenvanf\/?p=5250"},"modified":"2025-09-12T14:00:23","modified_gmt":"2025-09-12T12:00:23","slug":"python-weather-station-app","status":"publish","type":"post","link":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/","title":{"rendered":"Learn Python:\u00a0weather station app with live data\u00a0"},"content":{"rendered":"\n<p>Through this tutorial you become familiar with developing a Python application with a graphical userinterface. We will create an App which can display weather data from various weather stations. Data will come from an online xml service providing weather data.<\/p>\n\n\n\n<p>We are going to create an application that can display the temperature of several weather stations in the Netherlands, as well as the average temperature of those weather stations.<\/p>\n\n\n\n<p>You are given a&nbsp;<em>WeatherStation<\/em>&nbsp;class for reading the data. This class can read data using an XML file. XML files are used on the internet to provide data in a structured way (in a specific format).&nbsp;<em>Buienradar<\/em>&nbsp;is a Dutch site that provides weather data from several weather stations in XML form.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tutorial steps<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Design and create the user interface<\/li>\n\n\n\n<li>Add the WeatherStation class to the project<\/li>\n\n\n\n<li>Realize displaying  the temperature &amp; station name<\/li>\n\n\n\n<li>Add multiple instances of the class to the user interface<\/li>\n\n\n\n<li>Calculate the average temperature and display it<\/li>\n<\/ol>\n\n\n\n<p>These steps are explained in detail below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Design and create the user interface<\/h2>\n\n\n\n<p>First, we create one of the four Panels for displaying the temperature with the name of the weather station. Then we use that Panel several times (copy) to display the data of several weather stations. Also, we create a separate part of the user interface in which the average temperature is displayed (at the bottom in the example).<\/p>\n\n\n\n<p>Start with a new folder for this project and name that \u201cWeatherStation\u201d.<\/p>\n\n\n\n<p>Setup a basic script with a bare-bones userinterface as <a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/02\/20\/python-hello-world\/\" target=\"_blank\" rel=\"noreferrer noopener\">learned in for instance this tutorial<\/a>, and save that into the folder. It might look like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"383\" height=\"211\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image.png\" alt=\"\" class=\"wp-image-5253\" style=\"width:223px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image.png 383w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-300x165.png 300w\" sizes=\"auto, (max-width: 383px) 100vw, 383px\" \/><\/a><\/figure>\n\n\n\n<p>Next, we will construct a <a href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\" target=\"_blank\" rel=\"noreferrer noopener\">class<\/a>, based on a Tkinter Frame (it <a href=\"https:\/\/www.w3schools.com\/python\/python_inheritance.asp\" target=\"_blank\" rel=\"noreferrer noopener\">inherites<\/a> from tk.Frame). This will be a panel that can display a temperature value of one station. <a href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\" target=\"_blank\" rel=\"noreferrer noopener\">Learn more about classes, objects and methods in Python here.<\/a><\/p>\n\n\n\n<p>This could look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class TemperaturePanel(tk.Frame):\n    w = \"\" # WeatherStation\n    temperature = \"20.0\"\n\n    def __init__(self, parent, id):\n        tk.Frame.__init__(self, parent)\n        self.configure(background=\"#ffffff\", borderwidth=5)\n\n        self.labelTemp = tk.Label(self, text=self.temperature, anchor=\"center\", font=(\"Arial\", 25))\n        self.labelTemp.pack(side=\"top\", fill=\"both\")<\/code><\/pre>\n\n\n\n<p>Make sure to add the code at the top of the script, after the last <em>import <\/em>line.<\/p>\n\n\n\n<p>Then, add another Frame, which we can use as a container for multiple panels. The Frame will take care of the layout of the panels. They will be organized in <a href=\"https:\/\/www.tutorialspoint.com\/python\/tk_grid.htm\" target=\"_blank\" rel=\"noreferrer noopener\">a grid with two columns<\/a>. The Frame can look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Frame(tk.Frame):\n    def __init__(self, parent):\n        tk.Frame.__init__(self, parent)\n\n        self.panel1 = TemperaturePanel(self, 6290)\n        \n        # add to grid:\n        self.panel1.grid(row=0, column=0, sticky=\"ew\")\n\n        # 2 equal sized columns:\n        self.grid_columnconfigure(0, weight=1)\n        self.grid_columnconfigure(1, weight=1)<\/code><\/pre>\n\n\n\n<p>Finally, add a line at the end, just before the main loop to add the frame to the userinterface;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Frame(root).place(x=0, y=0, relwidth=1, relheight=1)<\/code><\/pre>\n\n\n\n<p>If you run the script, it should look like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"290\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-1.png\" alt=\"\" class=\"wp-image-5254\" style=\"width:316px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-1.png 627w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-1-300x139.png 300w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/a><\/figure>\n\n\n\n<p>The &#8220;20.0&#8221; is a placeholder, and not related to any temperature reading (yet). Can you find it in the code?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Add the WeatherStation class to the project<\/h2>\n\n\n\n<p>Download the script <strong><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/div\/python\/WeatherStation.py\" target=\"_blank\" rel=\"noreferrer noopener\">WeatherStation.py<\/a><\/strong> and copy it into the project folder. At the top of your userinterface script, import it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from WeatherStation import WeatherStation<\/code><\/pre>\n\n\n\n<p>Open the file in your editor. It contains the class definition which has several methods (functions in the class) that you can use to get data from a given station. <a href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\" target=\"_blank\" rel=\"noreferrer noopener\">Learn more about classes, objects and methods in Python here.<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Realize displaying  the temperature &amp; station name<\/h2>\n\n\n\n<p>Now we will add code to the TemperaturePanel class so it can actually display the temperature from a station.<\/p>\n\n\n\n<p>Before the definition of labelTemp, add:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>self.w = WeatherStation(id)<\/code><\/pre>\n\n\n\n<p>This will assign class variable w with and object created from class WeatherStation, with the given id. That id is a parameter that was already present in the init method of the class (it came with the example code from the previous step).<\/p>\n\n\n\n<p>Next, add a line to assign class variable temperature with the temperature value we read from the WeatherStation:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>self.temperature = self.w.readTemperature()<\/code><\/pre>\n\n\n\n<p>Run the script. It should give a real value of a station:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"290\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-2.png\" alt=\"\" class=\"wp-image-5256\" style=\"width:346px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-2.png 627w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-2-300x139.png 300w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/a><\/figure>\n\n\n\n<p>Do you know from which station? (Hint: check output in the Shell or Terminal).<\/p>\n\n\n\n<p>Now, in your editor, open the script <strong>WeatherStation.py<\/strong>. Look for the first class variable named &#8216;xml&#8217; in that class. It has the source of the data (de URL of the XML file). Open that URL in your browser and have a look. Find a weather station different from the one that is already used in the app (the one with id 6290). Find the id of that new station and assign it to panel1 in your userinterface script:<\/p>\n\n\n\n<p>Change this number into an id from a different station:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-3.png\"><img loading=\"lazy\" decoding=\"async\" width=\"532\" height=\"72\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-3.png\" alt=\"\" class=\"wp-image-5257\" style=\"width:355px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-3.png 532w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-3-300x41.png 300w\" sizes=\"auto, (max-width: 532px) 100vw, 532px\" \/><\/a><\/figure>\n\n\n\n<p>Run the script and check if the station and its temperature are different now.<\/p>\n\n\n\n<p>Now we would like to see the station name in the userinterface also. Duplicate the labelTemp in the class TemperaturePanel and name that copy &#8220;lblStationName&#8221;. Remove the parameter for the font, font=(&#8220;Arial&#8221;, 25) or resize it, as we want the stationname to be displayed smaller.<\/p>\n\n\n\n<p>For lblStationName, in the parameter list, replace the assignment of the text:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>text=self.w.readTemperature()<\/code><\/pre>\n\n\n\n<p>with a call to the function of the class WeatherStation that provides the station name. You should be able to find that function in WeatherStation.py.<\/p>\n\n\n\n<p>Now, the station name should be there:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"290\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-4.png\" alt=\"\" class=\"wp-image-5258\" style=\"width:370px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-4.png 627w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-4-300x139.png 300w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Add multiple instances of the class to the user interface<\/h2>\n\n\n\n<p>Find the definition of panel1 in class Frame. Duplicate it 3 times so you have 4 instances. Name them panel1&#8230;panel4. Assign different station id&#8217;s to all of them.<\/p>\n\n\n\n<p>Assign them to the grid also, so duplicate the line <strong>self.panel1.grid(&#8230;<\/strong> also and assign them to the proper rows and columns in the grid:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"193\" height=\"100\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-6.png\" alt=\"\" class=\"wp-image-5261\" style=\"width:135px;height:auto\"\/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Calculate the average temperature and display it<\/h2>\n\n\n\n<p>To be able to calculate the average, we must first have the temperature of a panel as a floating point number. Currently, the temperature is a string, and cannot be extracted from the TemperaturePanel.<\/p>\n\n\n\n<p>So we will add a method to the class TemperaturePanel which:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Reads the temperature (as a string) from the WeatherStation<\/li>\n\n\n\n<li>Converts that to a float<\/li>\n\n\n\n<li>Returns the value (this will be the result of the method)<\/li>\n<\/ul>\n\n\n\n<p>This could be the skeleton of this method, with comments in pseudo code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def readTemperature(self):\n    # read temperature from the WeatherStation:\n    temperature_str = ...\n    # convert temperature to a float:\n    temperature_value = ...\n    return temperature_value<\/code><\/pre>\n\n\n\n<p>Use this to complete the method yourself (put the proper code on the parts indicated with &#8230;).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Hints:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>How to read the temperature can be seen in the parameter &#8220;text=&#8221; when the labelTemp is created, in the __init__ function of the TemperaturePanel.<\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3schools.com\/python\/python_numbers.asp\" target=\"_blank\" rel=\"noreferrer noopener\">Read more about type conversion here.<\/a><\/li>\n<\/ul>\n\n\n\n<p>After that method is finished, we can proceed with the calculation of the average. This can be done at the end of the __init__ function of the class Frame. Here, you can do (in pseudo code):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>average = (sum_of_temperatures_of_all_panels)\/4<\/code><\/pre>\n\n\n\n<p>The sum of temperatures can be a simple addition (using &#8216;+&#8217; <a href=\"https:\/\/www.w3schools.com\/python\/python_operators.asp\" target=\"_blank\" rel=\"noreferrer noopener\">operators<\/a>) of the 4 temperatures that you can read by calling the method readTemperature() that we just created for each panel. So for the first panel, this would look like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>self.panel1.readTemperature()<\/code><\/pre>\n\n\n\n<p>This should give you sufficient information to construct the line of code that calculates the average yourself.<\/p>\n\n\n\n<p>Test if it works by printing the result in the shell:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>print(\"average:\", average)<\/code><\/pre>\n\n\n\n<p>Then run the app. Does it show the proper value of the average in the shell?<\/p>\n\n\n\n<p>Now, all that remains is showing that in the userinterface.  Add a label for that:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>self.label = tk.Label(self, text=average, anchor=\"center\")\nself.label.grid(row=2, column=0, columnspan=2, sticky=\"ew\")<\/code><\/pre>\n\n\n\n<p>The last line will properly place it in the grid, spanning two columns.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Formatting the output number<\/h4>\n\n\n\n<p>You might notice that now it only shows the number, and also might have a lot of decimals (for instance 25.599999999999998). So you must properly round the number and format the result shown, including text that clarifies what it is.<\/p>\n\n\n\n<p>There are <a href=\"https:\/\/www.geeksforgeeks.org\/python-output-formatting\/\" target=\"_blank\" rel=\"noreferrer noopener\">many ways of formatting output<\/a> of numbers. Here, an example using formatted string literals:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>f'xxxxxxx-message-xxxxxxx {average:.1f}'<\/code><\/pre>\n\n\n\n<p>Which will get the results with 1 decimal point.<\/p>\n\n\n\n<p>Use this to properly visualize the resulting average, as shown in the userinterface below. <\/p>\n\n\n\n<p>The final result should look similar to this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-45.png\"><img loading=\"lazy\" decoding=\"async\" width=\"502\" height=\"282\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-45.png\" alt=\"\" class=\"wp-image-6378\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-45.png 502w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-45-300x169.png 300w\" sizes=\"auto, (max-width: 502px) 100vw, 502px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Finalize the application: add comments<\/h2>\n\n\n\n<p>Make sure to add more comments to the parts of the code that you added\/modified. Use multi line comments or single line comments. Use the comments to explain how the code works. It must be clear for us, when we review your code, that you understood its purpose.<\/p>\n\n\n\n<p>Some examples of comments:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"\"\"\nExample of a multi line comment.\nThis is the second line of the comment.\n\"\"\"\n\n# Example of a line of code with comment at the end of the line:\nprint(\"Start of temperature measurement\"); # display text at the shell<\/code><\/pre>\n\n\n\n<p>At the top of the main script, add multi line comments with a general description of the script and add your name.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>With this tutorial you have written Python code and learned how to apply variables in expressions to perform calculations.<\/p>\n\n\n\n<p>You have also learned the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a user interface.<\/li>\n\n\n\n<li>Using expressions to perform calculations.<\/li>\n\n\n\n<li>Calling and determining the right methods from existing classes.<\/li>\n\n\n\n<li>Using variables as parameters for methods.<\/li>\n\n\n\n<li>Coming up with and creating new methods.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Learn more<\/h2>\n\n\n\n<p>Some tutorial sites to learn more:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.w3schools.com\/python\/python_classes.asp\" target=\"_blank\" rel=\"noreferrer noopener\">Python basics: classes, objects &amp; methods<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.w3schools.com\/python\/python_inheritance.asp\" target=\"_blank\" rel=\"noreferrer noopener\">Python basics: inheritance<\/a><\/li>\n\n\n\n<li>Tkinter: <a href=\"https:\/\/www.tutorialspoint.com\/python\/tk_grid.htm\" target=\"_blank\" rel=\"noreferrer noopener\">using grids<\/a><\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/tag\/python\/\" target=\"_blank\" rel=\"noreferrer noopener\">Also, check out other Python tutorials on this site!<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Extra practice<\/h3>\n\n\n\n<p>It would be nice to display for instance the humidity in the TemperaturePanel. Add a label for that, and use method&nbsp;<em>readValue()<\/em>&nbsp;of the WeatherStation class to get the humidity like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>self.w.readValue('luchtvochtigheid')<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-9.png\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"352\" src=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-9.png\" alt=\"\" class=\"wp-image-5280\" style=\"width:310px;height:auto\" srcset=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-9.png 627w, https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/image-9-300x168.png 300w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/a><\/figure>\n\n\n\n<p>It would also be nice if the application could refresh the data once every 5 minutes or so&#8230; that&#8217;s something we leave open as an extra challenge.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Get code<\/h2>\n\n\n\n<p>If you want to explore the final solution, <a href=\"https:\/\/github.com\/vanslooten\/python\/tree\/main\/WeatherStation\" target=\"_blank\" rel=\"noreferrer noopener\">check out the code<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Through this tutorial you become familiar with developing a Python application with a graphical userinterface. We will create an App which can display weather data from various weather stations. Data will come from an online xml service providing weather data. We are going to create an application that can display the temperature of several weather [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6377,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","footnotes":""},"categories":[3],"tags":[108,246,531,95,526,527,515,566],"class_list":["post-5250","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-education","tag-app","tag-appdev","tag-drawing","tag-programming","tag-python","tag-tkinter","tag-userinterface","tag-weather"],"blocksy_meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com<\/title>\n<meta name=\"description\" content=\"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com\" \/>\n<meta property=\"og:description\" content=\"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data\" \/>\n<meta property=\"og:url\" content=\"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/\" \/>\n<meta property=\"og:site_name\" content=\"vanslooten.com\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-02T11:29:26+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-12T12:00:23+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png\" \/>\n\t<meta property=\"og:image:width\" content=\"502\" \/>\n\t<meta property=\"og:image:height\" content=\"282\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Fjodor van Slooten\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@fjodorvs\" \/>\n<meta name=\"twitter:site\" content=\"@fjodorvs\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fjodor van Slooten\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/\"},\"author\":{\"name\":\"Fjodor van Slooten\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#\\\/schema\\\/person\\\/e62ff2d6beaa937dc9345a023eeb05dd\"},\"headline\":\"Learn Python:\u00a0weather station app with live data\u00a0\",\"datePublished\":\"2024-05-02T11:29:26+00:00\",\"dateModified\":\"2025-09-12T12:00:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/\"},\"wordCount\":1489,\"publisher\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#\\\/schema\\\/person\\\/e62ff2d6beaa937dc9345a023eeb05dd\"},\"image\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/Screenshot.png\",\"keywords\":[\"app\",\"appdev\",\"drawing\",\"programming\",\"python\",\"tkinter\",\"userinterface\",\"weather\"],\"articleSection\":[\"Education\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/\",\"url\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/\",\"name\":\"Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/Screenshot.png\",\"datePublished\":\"2024-05-02T11:29:26+00:00\",\"dateModified\":\"2025-09-12T12:00:23+00:00\",\"description\":\"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#primaryimage\",\"url\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/Screenshot.png\",\"contentUrl\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/Screenshot.png\",\"width\":502,\"height\":282},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/2024\\\/05\\\/02\\\/python-weather-station-app\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Learn Python:\u00a0weather station app with live data\u00a0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#website\",\"url\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/\",\"name\":\"vanslooten.com\",\"description\":\"Personal website of Fjodor van Slooten\",\"publisher\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#\\\/schema\\\/person\\\/e62ff2d6beaa937dc9345a023eeb05dd\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/#\\\/schema\\\/person\\\/e62ff2d6beaa937dc9345a023eeb05dd\",\"name\":\"Fjodor van Slooten\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/2018-08-24-13.33.38_small.jpg\",\"url\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/2018-08-24-13.33.38_small.jpg\",\"contentUrl\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/2018-08-24-13.33.38_small.jpg\",\"width\":300,\"height\":214,\"caption\":\"Fjodor van Slooten\"},\"logo\":{\"@id\":\"https:\\\/\\\/home.et.utwente.nl\\\/slootenvanf\\\/wp-content\\\/uploads\\\/2019\\\/06\\\/2018-08-24-13.33.38_small.jpg\"},\"sameAs\":[\"http:\\\/\\\/vanslooten.com\",\"https:\\\/\\\/x.com\\\/fjodorvs\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com","description":"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/","og_locale":"en_US","og_type":"article","og_title":"Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com","og_description":"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data","og_url":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/","og_site_name":"vanslooten.com","article_published_time":"2024-05-02T11:29:26+00:00","article_modified_time":"2025-09-12T12:00:23+00:00","og_image":[{"width":502,"height":282,"url":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png","type":"image\/png"}],"author":"Fjodor van Slooten","twitter_card":"summary_large_image","twitter_creator":"@fjodorvs","twitter_site":"@fjodorvs","twitter_misc":{"Written by":"Fjodor van Slooten","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#article","isPartOf":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/"},"author":{"name":"Fjodor van Slooten","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#\/schema\/person\/e62ff2d6beaa937dc9345a023eeb05dd"},"headline":"Learn Python:\u00a0weather station app with live data\u00a0","datePublished":"2024-05-02T11:29:26+00:00","dateModified":"2025-09-12T12:00:23+00:00","mainEntityOfPage":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/"},"wordCount":1489,"publisher":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#\/schema\/person\/e62ff2d6beaa937dc9345a023eeb05dd"},"image":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#primaryimage"},"thumbnailUrl":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png","keywords":["app","appdev","drawing","programming","python","tkinter","userinterface","weather"],"articleSection":["Education"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/","url":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/","name":"Learn Python:\u00a0weather station app with live data\u00a0 - vanslooten.com","isPartOf":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#website"},"primaryImageOfPage":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#primaryimage"},"image":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#primaryimage"},"thumbnailUrl":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png","datePublished":"2024-05-02T11:29:26+00:00","dateModified":"2025-09-12T12:00:23+00:00","description":"Learn Python:\u00a0weather station app with live data\u00a0 Learn Python:\u00a0create a weather station app with live data","breadcrumb":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#primaryimage","url":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png","contentUrl":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2024\/05\/Screenshot.png","width":502,"height":282},{"@type":"BreadcrumbList","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/2024\/05\/02\/python-weather-station-app\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/home.et.utwente.nl\/slootenvanf\/"},{"@type":"ListItem","position":2,"name":"Learn Python:\u00a0weather station app with live data\u00a0"}]},{"@type":"WebSite","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#website","url":"https:\/\/home.et.utwente.nl\/slootenvanf\/","name":"vanslooten.com","description":"Personal website of Fjodor van Slooten","publisher":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#\/schema\/person\/e62ff2d6beaa937dc9345a023eeb05dd"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/home.et.utwente.nl\/slootenvanf\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/#\/schema\/person\/e62ff2d6beaa937dc9345a023eeb05dd","name":"Fjodor van Slooten","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2019\/06\/2018-08-24-13.33.38_small.jpg","url":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2019\/06\/2018-08-24-13.33.38_small.jpg","contentUrl":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2019\/06\/2018-08-24-13.33.38_small.jpg","width":300,"height":214,"caption":"Fjodor van Slooten"},"logo":{"@id":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-content\/uploads\/2019\/06\/2018-08-24-13.33.38_small.jpg"},"sameAs":["http:\/\/vanslooten.com","https:\/\/x.com\/fjodorvs"]}]}},"_links":{"self":[{"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/posts\/5250","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/comments?post=5250"}],"version-history":[{"count":33,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/posts\/5250\/revisions"}],"predecessor-version":[{"id":6380,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/posts\/5250\/revisions\/6380"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/media\/6377"}],"wp:attachment":[{"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/media?parent=5250"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/categories?post=5250"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/home.et.utwente.nl\/slootenvanf\/wp-json\/wp\/v2\/tags?post=5250"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}