{"id":741,"date":"2017-11-01T13:00:49","date_gmt":"2017-11-01T13:00:49","guid":{"rendered":"http:\/\/chewett.co.uk\/blog\/?p=741"},"modified":"2017-10-31T22:09:54","modified_gmt":"2017-10-31T22:09:54","slug":"raspberry-pi-cluster-node-01-logging-liveness","status":"publish","type":"post","link":"https:\/\/chewett.co.uk\/blog\/741\/raspberry-pi-cluster-node-01-logging-liveness\/","title":{"rendered":"Raspberry Pi Cluster Node &#8211; 01 Logging Liveness"},"content":{"rendered":"<p>This post describes how to make a simple python script that logs the node is alive every 10 seconds.<\/p>\n<p><!--more--><\/p>\n<h2>Why we are going to log each node is alive<\/h2>\n<p><a href=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" data-attachment-id=\"662\" data-permalink=\"https:\/\/chewett.co.uk\/blog\/658\/distributed-computing-raspberry-pi-cluster\/single_master_many_slave\/\" data-orig-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?fit=410%2C381&amp;ssl=1\" data-orig-size=\"410,381\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"single_master_many_slave\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?fit=300%2C279&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?fit=410%2C381&amp;ssl=1\" class=\"alignleft size-full wp-image-662\" src=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?resize=410%2C381\" alt=\"\" width=\"410\" height=\"381\" srcset=\"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?w=410&amp;ssl=1 410w, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?resize=300%2C279&amp;ssl=1 300w, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/09\/single_master_many_slave.png?resize=50%2C46&amp;ssl=1 50w\" sizes=\"auto, (max-width: 410px) 100vw, 410px\" \/><\/a>As discussed in the previous post on <a href=\"\/blog\/658\/distributed-computing-raspberry-pi-cluster\/\">Distributed Computing on the Raspberry Pi Cluster<\/a> there will be many slaves and a single master in the first stage.<\/p>\n<p>The image reproduced opposite shows the process each slave will go through. They will repeatedly ask for work, then perform the action given to them.<\/p>\n<p>If there is no work then they will idle for a period of time and then ask the master again for work.<\/p>\n<p>This cycle will form the basis of running distributed work on the cluster. Any live node will be able to come online and request work. Once the work is done it will report back to the master with the result.<\/p>\n<p>Then the loop will continue again requesting more work.<\/p>\n<h2>\u00a0What we are going to use<\/h2>\n<p>This first script will create the event loop to check if there is work to do and add logging to keep track of what the node is doing.<\/p>\n<p>I am going to use the standard python logger to keep track of the work the node is doing. I will be configuring this to log data to both the console and a file. This will mean that I can view what the process is doing by observing the running console and ensure this data is saved to a file.<\/p>\n<p>Another really useful feature that the python logger has is that it is inherently thread safe. For the moment we are only using a single thread so this won&#8217;t matter. However in the future I plan to move towards making this applicable multi-threaded and having logging that handles this will be very useful.<\/p>\n<h2>Setting up the python logger<\/h2>\n<p>The python logging module can be simply imported using\u00a0<code>import logging<\/code>.\u00a0Once we have imported this we have access to all the logging features needed for our Raspberry Pi Cluster.<\/p>\n<p>To start with I am going to set up a formatter\u00a0for the logs.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">logFormatter = logging.Formatter(\r\n    &quot;%(asctime)s &#x5B;%(threadName)-12.12s] &#x5B;%(levelname)-5.5s]  %(message)s&quot;)<\/pre>\n<p>This formatter will be used to define the format of the logs produced. This includes all the important information including the time, thread, level and the message logged. As discussed above while the current program is not multi-threaded this will be in the future so it will be helpful to keep track of which thread is writing to the log.<\/p>\n<p>Now that I have a formatter\u00a0I can start to get the base logger object. This can be obtained using the below code.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">logger = logging.getLogger()\r\nlogger.setLevel(logging.DEBUG)<\/pre>\n<p>Here I am getting the base logger and setting the level of messages that will be logged. By setting it to <code>DEBUG<\/code>\u00a0I ensure that all messages will be logged. This base level set is inherited by all child loggers and output handlers.<\/p>\n<p>To actually save print out or save the log I need to attach handlers to the log. The most basic type of handler is the console handler. This works by printing all the information out to the console. I create one using the following code.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">consoleHandler = logging.StreamHandler()\r\nconsoleHandler.setFormatter(logFormatter)\r\nconsoleHandler.setLevel(logging.INFO)\r\nlogger.addHandler(consoleHandler)<\/pre>\n<p>Once the handler has been created with <code>logging.StreamHandler()<\/code>\u00a0I attach the formatter I created earlier. For the console output I have also set the logging level to <code>INFO<\/code>. This means only messages of <code>INFO<\/code> and higher will be printed to the console. The final but most important line attaches the handler to the logger we created earlier. This will receive the messages sent to the logger and will print them to the console.<\/p>\n<p>In addition to logging to the console I want to keep a store of all messages in case I need to review what has been occurring. I am able to do this with the following code by creating a file handler.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">fileHandler = logging.FileHandler(&quot;mainlogger.log&quot;)\r\nfileHandler.setFormatter(logFormatter)\r\nlogger.addHandler(fileHandler)<\/pre>\n<p>Here as I am creating a logger to save to a file I supply a filename <code>mainlogger.log<\/code>. This will be the file that is written to each time the logger runs. By default each time this code runs the file will have log data appended to it. This means if the script is stopped and rerun old log data won&#8217;t be lost. Again like above we use our custom log formatter to format our logs in a specific way.<\/p>\n<p>Now we have created our logger and various handlers to display the data we are ready to use it.<\/p>\n<h2>Using the Python Logger<\/h2>\n<p>The logger object has a number of methods to allow us to log a message and data. The basic log function is<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">logger.log(level, message, args)<\/pre>\n<p>Here you log a specific message at a specific error level. This error level is an integer representing the severity of the message. The message along with any additional arguments will be used by your formatter to display and store the message. With log you have to specify a specific error level, the basic logging levels, as taken from the <a href=\"https:\/\/docs.python.org\/2\/library\/logging.html#levels\" target=\"_blank\" rel=\"noopener\">python site<\/a> are:<\/p>\n<table class=\"docutils\" border=\"1\">\n<thead valign=\"bottom\">\n<tr class=\"row-odd\">\n<th class=\"head\">Level<\/th>\n<th class=\"head\">Numeric value<\/th>\n<\/tr>\n<\/thead>\n<tbody valign=\"top\">\n<tr class=\"row-even\">\n<td><code class=\"docutils literal\"><span class=\"pre\">CRITICAL<\/span><\/code><\/td>\n<td>50<\/td>\n<\/tr>\n<tr class=\"row-odd\">\n<td><code class=\"docutils literal\"><span class=\"pre\">ERROR<\/span><\/code><\/td>\n<td>40<\/td>\n<\/tr>\n<tr class=\"row-even\">\n<td><code class=\"docutils literal\"><span class=\"pre\">WARNING<\/span><\/code><\/td>\n<td>30<\/td>\n<\/tr>\n<tr class=\"row-odd\">\n<td><code class=\"docutils literal\"><span class=\"pre\">INFO<\/span><\/code><\/td>\n<td>20<\/td>\n<\/tr>\n<tr class=\"row-even\">\n<td><code class=\"docutils literal\"><span class=\"pre\">DEBUG<\/span><\/code><\/td>\n<td>10<\/td>\n<\/tr>\n<tr class=\"row-odd\">\n<td><code class=\"docutils literal\"><span class=\"pre\">NOTSET<\/span><\/code><\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>This means that a logger set to a default level of <code>DEBUG<\/code>\u00a0will log any messages set at level 10 and above. So that you don&#8217;t have to remember these values you can use the helper methods<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">logger.debug(message, args)\r\nlogger.info(message, args)\r\nlogger.warning(message, args)\r\nlogger.error(message, args)\r\nlogger.critical(message, args)<\/pre>\n<p>These work identically to <code>logger.log()<\/code>\u00a0except they have preset the log level to the respective integer (based on the above table). For ease of use I will be using the\u00a0specific logger functions defined above.<\/p>\n<h2>Creating the basis of a Raspberry Pi Cluster worker<\/h2>\n<p>Now I have the logger set up I can create a really basic Raspberry Pi Cluster worker. For this example it won&#8217;t perform any jobs but this structure will be used in the future.<\/p>\n<p>I will define a function that will eventually be used to find work to perform. In this case I will just use my logger to log that there is no work to be done.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">def find_work_to_do():\r\n    logger.info(&quot;Node slave still alive&quot;)\r\n    logger.info(&quot;Looking for work to run&quot;)\r\n    return None<\/pre>\n<p>This function also returns <code>None<\/code>\u00a0so that the calling function knows that there is nothing to do. The next and most crucial piece of code is the worker loop.<\/p>\n<pre class=\"brush: python; title: ; notranslate\" title=\"\">while True:\r\n    work = find_work_to_do()\r\n    if work is None:\r\n        logger.info(&quot;Found no jobs to perform, going to sleep again&quot;)\r\n        time.sleep(10)\r\n    else:\r\n        pass # we will do work in the future but not at the moment<\/pre>\n<p>Here we run forever checking to see if there is any work. If there is no work found, as determined by getting <code>None<\/code>\u00a0back from the <code>find_work_to_do<\/code>\u00a0function then it will log this and sleep for 10 seconds.<\/p>\n<p>For the moment we will ignore the case that work has been found as this is just to set up a basic work loop.<\/p>\n<h2>Summary of work towards the Raspberry Pi Cluster<\/h2>\n<p>Today I have gone over the basics of the python logger and set up the initial code for our cluster project. In addition, I have created the template function that will be used to get work for our nodes. The next lessons will focus on creating a basic system to talk to a master node and send messages.<\/p>\n<p>The full code for this first example is available on the <a href=\"https:\/\/github.com\/chewett\/RaspberryPiCluster\" target=\"_blank\" rel=\"noopener\">Github Repository<\/a> for this project.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post describes how to make a simple python script that logs the node is alive every 10 seconds.<\/p>\n","protected":false},"author":1,"featured_media":810,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[122],"tags":[39,183,184,37,101],"class_list":["post-741","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-cluster","tag-linux","tag-logging","tag-python","tag-raspberry-pi","tag-raspberry-pi-cluster"],"wppr_data":{"cwp_meta_box_check":"No"},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/rpi_cluster_01_logging_liveness.jpg?fit=800%2C800&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/p2toWX-bX","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":738,"url":"https:\/\/chewett.co.uk\/blog\/738\/raspberry-pi-cluster-github-repository\/","url_meta":{"origin":741,"position":0},"title":"Raspberry Pi Cluster Github Repository","author":"Chewett","date":"October 14, 2017","format":false,"excerpt":"This post is a summary of the plan for the Raspberry Pi Cluster project. Progress so far So far I have been creating a variety of scripts to see what you I can easily do with the cluster project. At the moment these scripts are spread across the nodes and\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/10\/github_raspberry_pi_start.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1054,"url":"https:\/\/chewett.co.uk\/blog\/1054\/raspberry-pi-tutorial-website-online-now\/","url_meta":{"origin":741,"position":1},"title":"Raspberry Pi Tutorial Website online now!","author":"Chewett","date":"March 10, 2018","format":false,"excerpt":"This post talks about the new page on my website with linking to all my Raspberry Pi Cluster tutorials. Raspberry Pi Cluster Tutorial Webpage Now I have a couple Raspberry Pi Cluster tutorials I decided to link to all of them on my website. This will form the basis of\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/03\/rpi_tutorial_website_online.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2780,"url":"https:\/\/chewett.co.uk\/blog\/2780\/raspberry-pi-cluster-node-18-raspberry-pi-temperature-monitoring\/","url_meta":{"origin":741,"position":2},"title":"Raspberry Pi Cluster Node \u2013 18 Raspberry Pi Temperature Monitoring","author":"Chewett","date":"February 20, 2021","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by starting to log temperature with the RaspberryPiVcgencmd Python module. Installing RaspberryPiVcgencmd RaspberryPiVcgencmd is a small python module aimed to control vcgencmd and allow programmatic access to it. This can be installed with the following command. python3 -m pip\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=700%2C400 2x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2021\/02\/raspi_cluster_18_cputemperature_posticon_OUTPUT.png?fit=1200%2C628&ssl=1&resize=1050%2C600 3x"},"classes":[]},{"id":881,"url":"https:\/\/chewett.co.uk\/blog\/881\/raspberry-pi-cluster-node-02-packaging-common-functionality\/","url_meta":{"origin":741,"position":3},"title":"Raspberry Pi Cluster Node \u2013 02 Packaging common functionality","author":"Chewett","date":"November 29, 2017","format":false,"excerpt":"This post builds on the first step to create a Raspberry Pi Cluster node to package the common functionality that will be shared between master and clients. Packaging common functionality With the Raspberry Pi Cluster project there will be a number of things all nodes will do. This can lead\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/11\/rpi_cluster_02_packaging.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/11\/rpi_cluster_02_packaging.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/11\/rpi_cluster_02_packaging.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2017\/11\/rpi_cluster_02_packaging.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":2127,"url":"https:\/\/chewett.co.uk\/blog\/2127\/raspberry-pi-cluster-node-14-a-simple-webserver\/","url_meta":{"origin":741,"position":4},"title":"Raspberry Pi Cluster Node \u2013 14 A simple webserver","author":"Chewett","date":"April 17, 2019","format":false,"excerpt":"This tutorial focuses on creating a simple webserver that displays the status of the master using python Bottle. What will the webserver be used for? To interact with the cluster I am planning on making a small set of webpages. Initially these will just display information about the cluster but\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/04\/rpi_cluster_14_a_simple_webserver.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/04\/rpi_cluster_14_a_simple_webserver.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/04\/rpi_cluster_14_a_simple_webserver.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2019\/04\/rpi_cluster_14_a_simple_webserver.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1781,"url":"https:\/\/chewett.co.uk\/blog\/1781\/raspberry-pi-cluster-node-07-sending-data-to-the-slave\/","url_meta":{"origin":741,"position":5},"title":"Raspberry Pi Cluster Node \u2013 07 Sending data to the Slave","author":"Chewett","date":"December 5, 2018","format":false,"excerpt":"This post builds on\u00a0my previous posts in the Raspberry Pi Cluster series\u00a0by adding the ability to receive data from the master. In this\u00a0update, I will be adding a way\u00a0for the slave to request data and\u00a0have it returned by the master. Moving machine details into its own file The first thing\u2026","rel":"","context":"In &quot;Raspberry Pi Cluster&quot;","block_context":{"text":"Raspberry Pi Cluster","link":"https:\/\/chewett.co.uk\/blog\/category\/raspberry-pi-cluster\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_07_sending_to_slave.jpg?fit=800%2C800&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_07_sending_to_slave.jpg?fit=800%2C800&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_07_sending_to_slave.jpg?fit=800%2C800&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/chewett.co.uk\/blog\/wp-content\/uploads\/2018\/12\/rpi_cluster_07_sending_to_slave.jpg?fit=800%2C800&ssl=1&resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/741","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=741"}],"version-history":[{"count":9,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/741\/revisions"}],"predecessor-version":[{"id":819,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/posts\/741\/revisions\/819"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media\/810"}],"wp:attachment":[{"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chewett.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}