{"componentChunkName":"component---src-templates-blog-post-js","path":"/solar-calculator/","result":{"data":{"site":{"siteMetadata":{"title":"Justin is a Maker","author":"Justin Smith"}},"mdx":{"id":"e5215f13-dd0a-5d95-b2de-4ba79ce12851","frontmatter":{"title":"Solar Calculator","date":"June 30, 2017","externalLink":null,"teaser":"Using a Raspberry Pi to let homeowners see exactly how much solar potential their house has."},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Solar Calculator\",\n  \"date\": \"2017-06-30T00:00:00-0500\",\n  \"teaser\": \"Using a Raspberry Pi to let homeowners see exactly how much solar potential their house has.\",\n  \"featuredImage\": \"solar.jpg\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"The first thing we did when I was hired to start the creative technology practice at Fjord Chicago was sit down and establish a few goals. The foremost goal of the entire practice was to get ideas off of a screen and into the real world. When we got a request to revamp the solar installation experience for a major energy provider, we knew that it would be a great opportunity to blend physical and digital experiences to wow their customers.\"), mdx(\"p\", null, \"Our client was located in a state that people thought couldn\\u2019t generate enough solar power for it to be worth the effort, but the area actually had a lot of potential for photovoltaic generation. The bulk of the project involved mapping out the entire solar interconnect process and making recommendations about where they could improve their services to be more human-centered, but we also had the opportunity to do extensive research on how their current customers were thinking about solar. We found that customers were often using complicated solar calculators as their first touchpoint in their journey to solar installation, and the current experience left much to be desired.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/6b43bcebe9ba2729b93b457079ffec5d/a2510/solar-2.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"70.66666666666667%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAQCAwX/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAGaGuuFUNhX/8QAGhAAAwEAAwAAAAAAAAAAAAAAAQIDABITIv/aAAgBAQABBQKp65q5LcN5OMEWm//EABURAQEAAAAAAAAAAAAAAAAAABBB/9oACAEDAQE/Aaf/xAAWEQADAAAAAAAAAAAAAAAAAAABEDH/2gAIAQIBAT8BEX//xAAaEAABBQEAAAAAAAAAAAAAAAABAAIQESIh/9oACAEBAAY/As8QBjQsK2x//8QAGxAAAwACAwAAAAAAAAAAAAAAAAERIVExQWH/2gAIAQEAAT8hXFNFCcDrmh5kw+eOdIuE+mQ//9oADAMBAAIAAwAAABC8D//EABcRAAMBAAAAAAAAAAAAAAAAAAABESH/2gAIAQMBAT8QacQw/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAR/9oACAECAQE/EEC22//EABoQAQADAQEBAAAAAAAAAAAAAAEAESFBMfH/2gAIAQEAAT8QdgJmKpZQ/kl1XyaKuDA3R9mPe6z0smvZ/9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The finished prototype\",\n    \"title\": \"The finished prototype\",\n    \"src\": \"/static/6b43bcebe9ba2729b93b457079ffec5d/a2510/solar-2.jpg\",\n    \"srcSet\": [\"/static/6b43bcebe9ba2729b93b457079ffec5d/f93b5/solar-2.jpg 300w\", \"/static/6b43bcebe9ba2729b93b457079ffec5d/b4294/solar-2.jpg 600w\", \"/static/6b43bcebe9ba2729b93b457079ffec5d/a2510/solar-2.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The finished prototype\")), mdx(\"p\", null, \"If you go to an online solar calculator right now, you\\u2019ll be asked for all sorts of information like your current monthly energy usage in kilowatt hours, the pitch of your roof, the average duration of sunlight on your property, and all sorts of other questions that the average consumer won\\u2019t readily know. In addition to that, calculations can vary wildly based on who is doing the math. We found that some very popular calculators were overly optimistic, while others tried to push the customer to purchase more equipment than they could actually use. With all of the data that this energy provider had about their customers, we knew that we had a chance to make this process a lot more user-friendly.\"), mdx(\"p\", null, \"We wanted our calculator to be a useful tool for getting accurate information about what a solar installation could do for a residential customer, but we also wanted to use it to get folks excited about the solar potential of their home. We came up with the idea of taking the calculator out of the digital space and into the physical world. What better way to excite people than to actually show them a panel at work?\"), mdx(\"p\", null, \"The prototype needed to be able to collect energy data from an actual panel, then feed that data back into a computer to analyze the data. The first step in that process was to actually get our hands on a few panels and see how they functioned.\"), mdx(\"div\", {\n    className: \"paragraph-with-picture\"\n  }, mdx(\"p\", null, \"We decided to go with an iPad-sized six watt panel from Voltaic. The panel was designed for rugged use, and came with a connector that we could easily modify to feed into our prototype. We learned our first lesson by testing how long the panel took to charge the USB battery pack that came with the panel. I was on my bike that day, so I decided to strap the unit to my backpack and see if we could charge the battery at all on my ride home.\"), mdx(\"div\", {\n    \"className\": \"image-container small-image\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"500px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/7d2e56d559627aa4343e81aebff17e8c/41099/solar-backpack-1.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"133.33333333333331%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQCAwUG/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAF3GtUzehMMoSvgkgD/xAAeEAACAQQDAQAAAAAAAAAAAAABAgMABBEhEBIiMv/aAAgBAQABBQK5lUAPuLyk+TLna3DIs7djWKHyOP/EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQMBAT8BH//EABQRAQAAAAAAAAAAAAAAAAAAACD/2gAIAQIBAT8BH//EAB4QAAEDBAMAAAAAAAAAAAAAAAEAAiEQESIxIGFx/9oACAEBAAY/ArDe1kI6WJdbxEuO6BrTCjl//8QAHBAAAgMAAwEAAAAAAAAAAAAAAAERITEQQYFx/9oACAEBAAE/IVtzvSDXovsMkqVtCEtBL8MZggLm6cKiNPTXnH//2gAMAwEAAgADAAAAEAzFz//EABcRAQEBAQAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8Q1ORdn//EABgRAAMBAQAAAAAAAAAAAAAAAAABIRAR/9oACAECAQE/EI6US5n/xAAfEAEAAwACAgMBAAAAAAAAAAABABEhMVFBYXGhscH/2gAIAQEAAT8QQbZoRRvMC5SqmPtHl9ILY75iSVXLoK+fX7Dqujmg61ldE4Lxe0eoVZxSpzLXtYAC3RBd/j+JjPSWz//Z')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The Voltaic strapped to my bag\",\n    \"title\": \"The Voltaic strapped to my bag\",\n    \"src\": \"/static/7d2e56d559627aa4343e81aebff17e8c/41099/solar-backpack-1.jpg\",\n    \"srcSet\": [\"/static/7d2e56d559627aa4343e81aebff17e8c/f93b5/solar-backpack-1.jpg 300w\", \"/static/7d2e56d559627aa4343e81aebff17e8c/41099/solar-backpack-1.jpg 500w\"],\n    \"sizes\": \"(max-width: 500px) 100vw, 500px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The Voltaic strapped to my bag\"), \"\\n  \")), mdx(\"div\", {\n    className: \"paragraph-with-picture\"\n  }, mdx(\"p\", null, \"I got home and saw zero charge. I left the panel out in the backyard for two more hours, but still barely got any charge on the battery. The key lesson there was that solar can be extremely slow. We would need to visualize the data in real-time in order to keep a customer engaged.\"), mdx(\"div\", {\n    \"className\": \"image-container small-image\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/c3463889d1484f8180554ef63d705f69/a2510/voltaic-test.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"75%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAMEAv/EABcBAAMBAAAAAAAAAAAAAAAAAAABAgP/2gAMAwEAAhADEAAAAYWbqzqYaD//xAAbEAACAgMBAAAAAAAAAAAAAAABAgADERIhIv/aAAgBAQABBQJnyU9Q1iJVxVUBhrP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAWEQADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8BoX//xAAaEAACAgMAAAAAAAAAAAAAAAAAIQExAhEi/9oACAEBAAY/AljoYpOmSrLP/8QAGxABAAMAAwEAAAAAAAAAAAAAAQARITFRYUH/2gAIAQEAAT8hLBtzGXzj1EPATArwdQVQ/HkuGNLn/9oADAMBAAIAAwAAABC8H//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAG3Q3/xAAWEQEBAQAAAAAAAAAAAAAAAAABABH/2gAIAQIBAT8QcMhb/8QAHRABAQACAQUAAAAAAAAAAAAAAREAITFBUWFx4f/aAAgBAQABPxCRIKiuvEwiKS0aTqZUp2g+4PJwSunvLHwLCceMUUCS2zP/2Q==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Testing the panel from Voltaic\",\n    \"title\": \"Testing the panel from Voltaic\",\n    \"src\": \"/static/c3463889d1484f8180554ef63d705f69/a2510/voltaic-test.jpg\",\n    \"srcSet\": [\"/static/c3463889d1484f8180554ef63d705f69/f93b5/voltaic-test.jpg 300w\", \"/static/c3463889d1484f8180554ef63d705f69/b4294/voltaic-test.jpg 600w\", \"/static/c3463889d1484f8180554ef63d705f69/a2510/voltaic-test.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Testing the panel from Voltaic\"), \"\\n  \")), mdx(\"p\", null, \"I decided to use a Raspberry Pi as the brain for the unit due to its size, cost, and availability. The cable that ran from the solar panel was converted to discharge into a voltage sensor, which was then sent to a database on the Pi. That voltage data was great to see coming through, but we were still missing a part of the puzzle\\u2013we needed to know what the sun was doing while we were getting those particular voltage readings. To account for that, I added a TSL2591 luminosity sensor to the project. This sensor lets us measure the amount of visible and infrared light, which helps us get a feel for the external conditions that the prototype was being tested in. After a rough assembly of all of these parts, I went out on a nice summer day to field test the components.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/20568ea1b9fbe8d9bb471c7ce2473ab3/a2510/field-testing-1.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"75%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABUBAQEAAAAAAAAAAAAAAAAAAAID/9oADAMBAAIQAxAAAAGTreVImwK//8QAGRAAAgMBAAAAAAAAAAAAAAAAAQIAAxET/9oACAEBAAEFAg4wMHblKa8grVWyf//EABURAQEAAAAAAAAAAAAAAAAAAAAS/9oACAEDAQE/AYS//8QAFREBAQAAAAAAAAAAAAAAAAAAABL/2gAIAQIBAT8BtT//xAAcEAABAwUAAAAAAAAAAAAAAAAAAhEhARAxQZH/2gAIAQEABj8ClPRlUkwOPu3/xAAbEAACAwEBAQAAAAAAAAAAAAABEQAhMYFBsf/aAAgBAQABPyFTYTYX5NquLyEng9gAF2bTyJEHqFjP/9oADAMBAAIAAwAAABB/3//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPxCUy//EABYRAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAgEBPxBA5bv/xAAeEAACAwABBQAAAAAAAAAAAAABEQAhQTFRYXGxwf/aAAgBAQABPxA+x1IntMhoCKEgoB7PENYta4+RngAUNbhPYNDC5wT18wBG6W9p/9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Field testing the sensors\",\n    \"title\": \"Field testing the sensors\",\n    \"src\": \"/static/20568ea1b9fbe8d9bb471c7ce2473ab3/a2510/field-testing-1.jpg\",\n    \"srcSet\": [\"/static/20568ea1b9fbe8d9bb471c7ce2473ab3/f93b5/field-testing-1.jpg 300w\", \"/static/20568ea1b9fbe8d9bb471c7ce2473ab3/b4294/field-testing-1.jpg 600w\", \"/static/20568ea1b9fbe8d9bb471c7ce2473ab3/a2510/field-testing-1.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Field testing the sensors\")), mdx(\"p\", null, \"The field test went well, and I was able to verify that the voltage being sent to the database was accurate with a multimeter. The next step in our process was to start collecting enough data to explore. I took the prototype home and set it outside for two days to start collecting data. The first day I leaned the panel up against a window on the front of my house, which allowed it to get a good stretch of direct sunlight. When noon hit, I realized that I would need to move the unit to simulate a roof-based panel since the sun was now moving over the house. It wasn\\u2019t an ideal testing environment, but I went ahead and moved the panel to the backyard for the afternoon.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/c41c580c0fce2b453752b943d0e80308/a2510/house-test-1.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"75%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIDAQT/xAAWAQEBAQAAAAAAAAAAAAAAAAACAAH/2gAMAwEAAhADEAAAAU2NcSHMR//EABoQAQEAAwEBAAAAAAAAAAAAAAECABESAxP/2gAIAQEAAQUCmugNVrPK+M+qlND/AP/EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/Aaf/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAgEBPwFX/8QAGhAAAgIDAAAAAAAAAAAAAAAAABEBIQIQQf/aAAgBAQAGPwJjnJ6RMl9s/8QAGRABAAMBAQAAAAAAAAAAAAAAAQARITFR/9oACAEBAAE/Ib59WXGjM9RjgqOvZT1FPk0S2H//2gAMAwEAAgADAAAAEPPf/8QAFhEBAQEAAAAAAAAAAAAAAAAAAREA/9oACAEDAQE/EJEuu//EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oACAECAQE/EKp//8QAHxABAQACAQQDAAAAAAAAAAAAAREAMSFBUWFxkcHh/9oACAEBAAE/EHRWtX0YlVdaInzltFrbX7zcPyHYF3LlQiegO+JPG8vBLyHu/mf/2Q==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Testing the unit on the front of my house\",\n    \"title\": \"Testing the unit on the front of my house\",\n    \"src\": \"/static/c41c580c0fce2b453752b943d0e80308/a2510/house-test-1.jpg\",\n    \"srcSet\": [\"/static/c41c580c0fce2b453752b943d0e80308/f93b5/house-test-1.jpg 300w\", \"/static/c41c580c0fce2b453752b943d0e80308/b4294/house-test-1.jpg 600w\", \"/static/c41c580c0fce2b453752b943d0e80308/a2510/house-test-1.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Testing the unit on the front of my house\")), mdx(\"p\", null, \"The second day of testing was a little more complicated, but it helped us prove a valuable data point. We had a nice sunny morning that quickly turned into an overcast drizzly day. I was a little bummed as I didn\\u2019t think we would get good readings, but the data proved me wrong. It doesn\\u2019t matter to the panel if it\\u2019s actually clear and sunny outside\\u2013it\\u2019s looking for infrared light, and there\\u2019s still plenty of that on a cloudy day. We were able to show that the panel continued production throughout the rain, which helped us push the point about solar viability in the state that the power company was located in.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/2eda81af1755fd724fa318a0f79ebff3/a2510/house-test-2.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"55.99999999999999%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIDBP/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAF5UWXGKSf/xAAaEAACAwEBAAAAAAAAAAAAAAACAwABIhES/9oACAEBAAEFAliPhw1U7F3huhn/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAACAwEAAAAAAAAAAAAAAAAAAQIQIRH/2gAIAQEABj8CjmsVRF2v/8QAHhAAAgEDBQAAAAAAAAAAAAAAAAERITGBUWFxscH/2gAIAQEAAT8hYc5XHG5NohEOcjMC7NU18LWP/9oADAMBAAIAAwAAABAAH//EABcRAAMBAAAAAAAAAAAAAAAAAAABESH/2gAIAQMBAT8QS0p//8QAFhEBAQEAAAAAAAAAAAAAAAAAABFB/9oACAECAQE/EMR//8QAGxABAAIDAQEAAAAAAAAAAAAAAQARITFBYaH/2gAIAQEAAT8QEqS8hcgibhhK4o7+wfKPopACODnLePG4GyUAeE//2Q==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Testing the unit in the drizzle\",\n    \"title\": \"Testing the unit in the drizzle\",\n    \"src\": \"/static/2eda81af1755fd724fa318a0f79ebff3/a2510/house-test-2.jpg\",\n    \"srcSet\": [\"/static/2eda81af1755fd724fa318a0f79ebff3/f93b5/house-test-2.jpg 300w\", \"/static/2eda81af1755fd724fa318a0f79ebff3/b4294/house-test-2.jpg 600w\", \"/static/2eda81af1755fd724fa318a0f79ebff3/a2510/house-test-2.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Testing the unit in the drizzle\")), mdx(\"p\", null, \"Now that we had data, we could start designing the interface that the customer would use to see their data. We knew that the productized unit wouldn\\u2019t ship with a display on it, but I went ahead and added a Raspberry Pi touchscreen for the sake of the demo. This screen needed to show how the panel was performing, what our luminosity readings were, and how all of that stacked up against the customer\\u2019s usage data.\"), mdx(\"div\", {\n    className: \"paragraph-with-picture\"\n  }, mdx(\"p\", null, \"The first version of the data dashboard was the bare minimum to make sure that we were getting our readings in. None of the data was normalized, the timestamps were still unformatted, and we didn't have usage data yet.\"), mdx(\"div\", {\n    \"className\": \"image-container small-image\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/5c380da6ff90df978a61cc1fa4ed09cd/a2510/dash-1.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"56.333333333333336%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAMCBAX/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABuySuXGECf//EAB4QAAAEBwAAAAAAAAAAAAAAAAABAwQCERITISMy/9oACAEBAAEFAm87KnOQ3PStEdBD/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHBAAAQMFAAAAAAAAAAAAAAAAAAECERAyUXGh/9oACAEBAAY/AmwLOC/o0dqn/8QAHhABAAEDBQEAAAAAAAAAAAAAAQAhMUERUWFxobH/2gAIAQEAAT8hdME57mGCqC7e0Q0Hf7Lwylk//9oADAMBAAIAAwAAABAL3//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABYRAQEBAAAAAAAAAAAAAAAAABEQIf/aAAgBAgEBPxBcn//EABsQAQACAwEBAAAAAAAAAAAAAAEAESExUXHR/9oACAEBAAE/EKHVG30jc9CFaMblg4bgEIH0h+sNHIkXs//Z')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The rough draft of the dashboard\",\n    \"title\": \"The rough draft of the dashboard\",\n    \"src\": \"/static/5c380da6ff90df978a61cc1fa4ed09cd/a2510/dash-1.jpg\",\n    \"srcSet\": [\"/static/5c380da6ff90df978a61cc1fa4ed09cd/f93b5/dash-1.jpg 300w\", \"/static/5c380da6ff90df978a61cc1fa4ed09cd/b4294/dash-1.jpg 600w\", \"/static/5c380da6ff90df978a61cc1fa4ed09cd/a2510/dash-1.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The rough draft of the dashboard\"), \"\\n  \")), mdx(\"p\", null, \"The full dashboard evolved into something much easier to interact with. The first screen shows the averaged voltage every minute in orange, and the total power generated in red. The second screen shows our luminosity readings from the day\\u2013this particular screen is showing the rainy day readings. If you cross reference the luminosity readings with the power readings, you\\u2019ll see that our power didn\\u2019t dip when we bumped into cloudy conditions.\"), mdx(\"p\", null, \"The last screen shows what happens when we take that generation data and extrapolate it out to a full installation size. I figured out how many of our test panels that we could fit on my roof, then multiplied our power generation numbers to reflect that. In addition to that upsizing, I ran a model that calculated how the performance of the panel would change based on average sunlight duration throughout the rest of the year. That data was then graphed against a real customer\\u2019s monthly usage data that we were getting from the power company\\u2019s API. The solar prediction is shown in orange, and the monthly usage is shown in red.\"), mdx(\"p\", null, \"Lastly, you\\u2019ll notice that we added some explainers on the bottom of the screen to help people contextualize this information. The majority of the calculators we researched spit out info in terms that the average customer wouldn\\u2019t be familiar with or care about, so we wanted to make sure to make our information relatable.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/0079fc525ecac2f3f34bb80be2b76760/a2510/energy-screenshot.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"57.00000000000001%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQBAgMF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB6q70DU0E/8QAFhABAQEAAAAAAAAAAAAAAAAAAhAB/9oACAEBAAEFAkDCAsv/xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAwEBPwGn/8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQIBAT8Bh//EABwQAAEDBQAAAAAAAAAAAAAAAAIAAZERICEzkv/aAAgBAQAGPwLADC1jyquDRZ//xAAdEAACAQQDAAAAAAAAAAAAAAAAAREhMVFhcYHw/9oACAEBAAE/IUHV9BrHvwIMnstEIVj/2gAMAwEAAgADAAAAEDcP/8QAFxEBAAMAAAAAAAAAAAAAAAAAARARQf/aAAgBAwEBPxArhH//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/EB//xAAcEAEBAQACAwEAAAAAAAAAAAABEQAhMUFhcdH/2gAIAQEAAT8QcyAsfyypSHus4LFGB19OsCr5zJJuMHW//9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Energy generation screen\",\n    \"title\": \"Energy generation screen\",\n    \"src\": \"/static/0079fc525ecac2f3f34bb80be2b76760/a2510/energy-screenshot.jpg\",\n    \"srcSet\": [\"/static/0079fc525ecac2f3f34bb80be2b76760/f93b5/energy-screenshot.jpg 300w\", \"/static/0079fc525ecac2f3f34bb80be2b76760/b4294/energy-screenshot.jpg 600w\", \"/static/0079fc525ecac2f3f34bb80be2b76760/a2510/energy-screenshot.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Energy generation screen\")), mdx(\"br\", null), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/ba643779a68683be9a03832ec428c60c/a2510/luminosity-screenshot.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"57.00000000000001%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAECBAX/xAAVAQEBAAAAAAAAAAAAAAAAAAAAAf/aAAwDAQACEAMQAAAB6s6FCLK//8QAGRABAAIDAAAAAAAAAAAAAAAAAgERABIg/9oACAEBAAEFAqG1GMgBcf/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EAB4QAAAEBwAAAAAAAAAAAAAAAAABAhESEyAzYZGi/9oACAEBAAY/Amlci2lsEHgLVH//xAAbEAEBAAEFAAAAAAAAAAAAAAABABEhMWFxof/aAAgBAQABPyFHRPMWZW7MF66lgja//9oADAMBAAIAAwAAABA8D//EABYRAQEBAAAAAAAAAAAAAAAAAAEQYf/aAAgBAwEBPxAcn//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAECAQE/EIf/xAAcEAEAAwADAQEAAAAAAAAAAAABABEhMUFRcbH/2gAIAQEAAT8QzBXWFfnEWKjRQue88gVeGQ59ICr3GpKmaHE//9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Luminosity measurement screen\",\n    \"title\": \"Luminosity measurement screen\",\n    \"src\": \"/static/ba643779a68683be9a03832ec428c60c/a2510/luminosity-screenshot.jpg\",\n    \"srcSet\": [\"/static/ba643779a68683be9a03832ec428c60c/f93b5/luminosity-screenshot.jpg 300w\", \"/static/ba643779a68683be9a03832ec428c60c/b4294/luminosity-screenshot.jpg 600w\", \"/static/ba643779a68683be9a03832ec428c60c/a2510/luminosity-screenshot.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Luminosity measurement screen\")), mdx(\"br\", null), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/9ba81fcf8abfc17376a0c15235242fd3/a2510/usage-screenshot.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"57.00000000000001%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAECBAX/xAAUAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHSVpCEhP/EABgQAQEBAQEAAAAAAAAAAAAAAAECABIg/9oACAEBAAEFArJwDuIfH//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/Aaf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAdEAAABQUAAAAAAAAAAAAAAAAAAQIDkREgMjOS/9oACAEBAAY/AqE2XI1pgYJiz//EABoQAQEAAgMAAAAAAAAAAAAAAAEAETFRcZH/2gAIAQEAAT8hEvaQ7i3nGDC+CSwRq//aAAwDAQACAAMAAAAQeA//xAAWEQEBAQAAAAAAAAAAAAAAAAAREDH/2gAIAQMBAT8QwE//xAAVEQEBAAAAAAAAAAAAAAAAAAAQEf/aAAgBAgEBPxCH/8QAHBABAAMAAgMAAAAAAAAAAAAAAQARITFBkaHB/9oACAEBAAE/ELCszl8ZAgHTW71ERWg1vkBV7jUlTNCf/9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Usage and solar potential screen\",\n    \"title\": \"Usage and solar potential screen\",\n    \"src\": \"/static/9ba81fcf8abfc17376a0c15235242fd3/a2510/usage-screenshot.jpg\",\n    \"srcSet\": [\"/static/9ba81fcf8abfc17376a0c15235242fd3/f93b5/usage-screenshot.jpg 300w\", \"/static/9ba81fcf8abfc17376a0c15235242fd3/b4294/usage-screenshot.jpg 600w\", \"/static/9ba81fcf8abfc17376a0c15235242fd3/a2510/usage-screenshot.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Usage and solar potential screen\")), mdx(\"br\", null), mdx(\"p\", null, \"The client absolutely loved the finished product, and it\\u2019s been one of our most active showcase pieces at the Chicago studio. The upper leadership connected with the product because it was something tangible that they could walk around and show people, and it clearly communicated some key findings from our research. That excitement is what keeps me excited about the work as we continue to see how we can get digital tools off of a screen and into the real world.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1000px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/2c1ad5b7ab41b2020f859483aa5efc9f/a2510/solar-3.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"66.66666666666666%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAIFAwT/xAAVAQEBAAAAAAAAAAAAAAAAAAACAf/aAAwDAQACEAMQAAABxZeguSUw3//EABwQAAEDBQAAAAAAAAAAAAAAAAIAASEDEBESE//aAAgBAQABBQIYKqAsPO20YX//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEv/aAAgBAwEBPwGUv//EABYRAQEBAAAAAAAAAAAAAAAAAAABEv/aAAgBAgEBPwG1p//EABwQAAEDBQAAAAAAAAAAAAAAAAECEBEAEiExcf/aAAgBAQAGPwJNx3jlGFAl4gBv/8QAGhABAAMBAQEAAAAAAAAAAAAAAQARITFBYf/aAAgBAQABPyG1ML68hytpx2KXkS8iMvsJSf/aAAwDAQACAAMAAAAQZA//xAAXEQEAAwAAAAAAAAAAAAAAAAAAESFB/9oACAEDAQE/ELag/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARMf/aAAgBAgEBPxAh5bv/xAAYEAEBAQEBAAAAAAAAAAAAAAABESEAUf/aAAgBAQABPxDOMITj66dSPoDVWOC8gVKt4CoMwpZznnARi8QM7//Z')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The finished prototype\",\n    \"title\": \"The finished prototype\",\n    \"src\": \"/static/2c1ad5b7ab41b2020f859483aa5efc9f/a2510/solar-3.jpg\",\n    \"srcSet\": [\"/static/2c1ad5b7ab41b2020f859483aa5efc9f/f93b5/solar-3.jpg 300w\", \"/static/2c1ad5b7ab41b2020f859483aa5efc9f/b4294/solar-3.jpg 600w\", \"/static/2c1ad5b7ab41b2020f859483aa5efc9f/a2510/solar-3.jpg 1000w\"],\n    \"sizes\": \"(max-width: 1000px) 100vw, 1000px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The finished prototype\")), mdx(\"br\", null));\n}\n;\nMDXContent.isMDXComponent = true;"}},"pageContext":{"slug":"/solar-calculator/","previous":{"id":"e15c7deb-13da-5f76-abdc-43cd48241b5e","fields":{"slug":"/ansible-pi/"},"frontmatter":{"title":"Headless Raspberry Pi Startup with Ansible"},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Headless Raspberry Pi Startup with Ansible\",\n  \"date\": \"2017-04-12T00:00:00-0500\",\n  \"teaser\": \"Get your Pi up and ready to go with a few short commands and an Ansible playbook.\",\n  \"featuredImage\": \"ansible-pi.jpg\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Getting started on a Raspberry Pi can be a little daunting if you\\u2019re brand new to working with the board. The easiest route is to get a monitor and a spare mouse and keyboard to get everything set up, but there are plenty of times when you aren\\u2019t going to have access to all of those components. If you\\u2019re sitting there with a Pi and wondering how to get set up, this post will help you get the ball rolling. This kind of setup refers to running the Pi \\u201Cheadless\\u201D, which is just a fancy way to say running it without a monitor.\"), mdx(\"p\", null, \"We\\u2019ll walk through the basic steps to get SSH set up, and then we\\u2019ll move on to the fun stuff\\u2013configuring your Pi via Ansible.\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"640px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/05ffe39d722e55651f106f8bb88e2027/c08c5/ansible-pi.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"75%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAIBBf/EABUBAQEAAAAAAAAAAAAAAAAAAAEA/9oADAMBAAIQAxAAAAHnToSkf//EABgQAQEBAQEAAAAAAAAAAAAAAAEAIRIi/9oACAEBAAEFAvMHSOWiF//EABcRAAMBAAAAAAAAAAAAAAAAAAEQEUH/2gAIAQMBAT8BMxf/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAZEAACAwEAAAAAAAAAAAAAAAABEQAQIQL/2gAIAQEABj8C1xci8Kr/xAAaEAADAQEBAQAAAAAAAAAAAAAAARExIWFx/9oACAEBAAE/IUmkVewdqJS1Ed+m5zeHHWf/2gAMAwEAAgADAAAAEOTv/8QAFxEAAwEAAAAAAAAAAAAAAAAAARARIf/aAAgBAwEBPxAJFav/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPxAJ/8QAHRABAQACAwADAAAAAAAAAAAAAREAITFBYXGxwf/aAAgBAQABPxCwTW4489xRQFu8B+9fLj7kr2mSmB6wopo1zjf3hS7FV33n/9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"Raspberry Pi & Ansible\",\n    \"title\": \"Raspberry Pi & Ansible\",\n    \"src\": \"/static/05ffe39d722e55651f106f8bb88e2027/c08c5/ansible-pi.jpg\",\n    \"srcSet\": [\"/static/05ffe39d722e55651f106f8bb88e2027/f93b5/ansible-pi.jpg 300w\", \"/static/05ffe39d722e55651f106f8bb88e2027/b4294/ansible-pi.jpg 600w\", \"/static/05ffe39d722e55651f106f8bb88e2027/c08c5/ansible-pi.jpg 640w\"],\n    \"sizes\": \"(max-width: 640px) 100vw, 640px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"Raspberry Pi & Ansible\")), mdx(\"h3\", null, \"Getting your Pi ready\"), mdx(\"p\", null, \"Let\\u2019s start by discussing how to get the Raspbian image on the SD card. We\\u2019ll be using the Raspbian Jessie with Pixel distro for this project. Head over to \", mdx(\"a\", {\n    href: \"https://www.raspberrypi.org/downloads/noobs/\",\n    target: \"_new\"\n  }, \"raspberrypi.org\"), \" to grab the latest Raspbian download. At the time of this post, the latest version is 4.4, but this should work for pretty much any version. If you can download torrents on your network, the torrent option for downloading the Raspbian distro is trusted and significantly faster than downloading the ZIP file.\"), mdx(\"p\", null, \"I\\u2019ll be using a Mac for this tutorial, and a few of the tools we\\u2019ll use to make this work are only available for Mac, to my knowledge. While you\\u2019re waiting for Raspbian to download, head over and download two additional programs that we\\u2019ll need to flash the card. The first is \", mdx(\"a\", {\n    href: \"https://www.sdcard.org/downloads/formatter_4/\",\n    target: \"_blank\"\n  }, \"SD Card Formatter\"), \" from the SD Association. We\\u2019ll use this to prep our card for imaging. The second is \", mdx(\"a\", {\n    href: \"https://www.tweaking4all.com/software/macosx-software/macosx-apple-pi-baker/\",\n    target: \"_new\"\n  }, \"Apple Pi Baker\"), \", a tool that makes managing your Pi disk images as easy as\\u2026pi. Sorry.\"), mdx(\"p\", null, \"Let\\u2019s format our SD card first. Open SD Formatter and choose the \\u201CQuick Format\\u201D option. Make sure you have the right card selected\\u2013unless you have any other external media plugged in, the only option should be the micro SD that you\\u2019ll use for your Pi. Click format and you should be good to go.\"), mdx(\"p\", null, \"When your Raspbian download has finished, you need to unzip it get access to the .img file. If you double-click the file and use Mac\\u2019s native Archive Utility, the ZIP file will unpack to a .cpgz file, which we don\\u2019t want. Instead of using Archive Utility, you need to use something like \", mdx(\"a\", {\n    href: \"http://unarchiver.c3.cx/unarchiver\",\n    target: \"_new\"\n  }, \"The Unarchiver\"), \" to extract the .img file from the ZIP. Once you have the .img file, we\\u2019re ready to make a few edits to the image that will help us with our setup.\"), mdx(\"p\", null, \"Double-click the Raspbian .img file to boot the drive. We\\u2019ll get into this new drive to edit and create a few files. When you see the booted drive on your Mac (likely called boot), open a new terminal window. We need to tell the terminal what we\\u2019d like to edit, and the easiest way to do this is to type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"cd\"), \"\\u201D for \\u201Cchange directory\\u201D, and then drag the boot disk onto the terminal window\\u2013this will autofill the path for us. Hit enter to change the directory, and then type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ls -a\"), \"\\u201D to show all the files in the directory.\"), mdx(\"h3\", null, \"Enabling SSH on the boot disk\"), mdx(\"p\", null, \"Due to a security problem a few months back, \", mdx(\"a\", {\n    href: \"https://www.raspberrypi.org/blog/a-security-update-for-raspbian-pixel/\",\n    target: \"_new\"\n  }, \"the Raspberry Pi Foundation made the decision to not enable SSH by default on new Raspbian images\"), \". This is an incredibly smart move as you don\\u2019t want SSH enabled with the default username and password\\u2013people who don\\u2019t change it were leaving their Pi\\u2019s open to a world of hurt. We\\u2019re going to re-enable it with the knowledge that we\\u2019ll be changing our password from the default as soon as we boot up. To enable SSH, you\\u2019ll need to create a blank file in the boot disk called \\u201CSSH\\u201D. To do this, run \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo touch ssh\"), \"\\u201D in your terminal window that\\u2019s pointed at the boot disk.\"), mdx(\"h3\", null, \"Configuring wi-fi on the boot disk\"), mdx(\"p\", null, \"SSH isn\\u2019t much good to us without a network connection. To make sure that we\\u2019re able to connect to wi-fi, we need to add a wpa_supplicant.conf file to our boot disk. Run \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo nano wpa_supplicant.conf\"), \"\\u201D in your terminal. This will open a nano editor that will let you write code in the terminal. For our power users out there, feel free to use whatever editor you\\u2019d like (looking at you, Vim/Emacs folks). We need to add the following code to this file to connect to a network. You\\u2019ll need to replace the \\u201CYOUR_NETWORK_NAME\\u201D and \\u201CYOUR_NETWORK_PASSWORD\\u201D with the appropriate credentials for your network. Once you\\u2019re done editing the file in nano, hit \\u201Cctrl+x\\u201D to exit, and then \\u201CY\\u201D to save.\"), mdx(\"div\", {\n    \"className\": \"gatsby-highlight\",\n    \"data-language\": \"javascript\"\n  }, mdx(\"pre\", {\n    parentName: \"div\",\n    \"style\": {\n      \"counterReset\": \"linenumber NaN\"\n    },\n    \"className\": \"language-javascript line-numbers\"\n  }, mdx(\"code\", {\n    parentName: \"pre\",\n    \"className\": \"language-javascript\"\n  }, \"network\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"{\"), \"\\n  ssid\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"YOUR_NETWORK_NAME\\\"\"), \"\\n  psk\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token string\"\n  }, \"\\\"YOUR_NETWORK_PASSWORD\\\"\"), \"\\n  key_mgmt\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"=\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"WPA\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token operator\"\n  }, \"-\"), mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token constant\"\n  }, \"PSK\"), \"\\n\", mdx(\"span\", {\n    parentName: \"code\",\n    \"className\": \"token punctuation\"\n  }, \"}\")), mdx(\"span\", {\n    parentName: \"pre\",\n    \"aria-hidden\": \"true\",\n    \"className\": \"line-numbers-rows\",\n    \"style\": {\n      \"whiteSpace\": \"normal\",\n      \"width\": \"auto\",\n      \"left\": \"0\"\n    }\n  }, mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  }), mdx(\"span\", {\n    parentName: \"span\"\n  })))), mdx(\"h3\", null, \"Writing the image\"), mdx(\"p\", null, \"We\\u2019ve got our two pieces of the boot disk that needed editing ready, so now we can move on to actually writing the image to the card.\"), mdx(\"p\", null, \"You can start by ejecting the \\u201Cboot\\u201D disk image\\u2013we won\\u2019t need that anymore. Next, open Pi Baker and select the SD card that you just formatted. We\\u2019re going to use the \\u201Crestore backup\\u201D function to write the .img file to the card. Locate the raspbian-jessie.img file that you downloaded, and select it in the \\u201Crestore backup\\u201D section of Pi Baker. After you have the selected, click \\u201CRestore Backup\\u201D. This process took around eight minutes to complete, but your mileage will vary based on your computer and the size of your SD card.\"), mdx(\"h3\", null, \"Firing up your Pi\"), mdx(\"p\", null, \"Now that the card is ready to go with the Raspbian image, we can go ahead and power it on! Plug your Pi in, then open a new terminal window on your Mac. We\\u2019ll try one command to SSH in first, and we\\u2019ll have a backup for anyone who that doesn\\u2019t work for. Depending on your network, you may be able to address the Pi as \\u201Craspberrypi.local\\u201D. To give this a shot, type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ssh raspberrypi.local -l pi\"), \"\\u201D into your terminal and hit enter. If it asks you about wanting to add the fingerprint, congrats, it worked\\u2013type \\u201Cyes\\u201D and then hit enter to accept. After that, enter the default password of \\u201Craspberry\\u201D. If you get something along the lines of \\u201CCould not resolve hostname raspberrypi.local\\u201D, that probably means that your network isn\\u2019t going to let us address the Pi with the shortname, provided you got the rest of the steps right. We have a few options to figure out the IP address of the Pi so we can SSH in, the easiest of which is accessing the network router for your wi-fi. Log in to your router\\u2019s control panel, look for connected devices, and make a note of the IP address associated with the hostname \\u201Craspberry\\u201D. If you don\\u2019t have access to your router, you can follow \", mdx(\"a\", {\n    href: \"https://www.raspberrypi.org/documentation/remote-access/ip-address.md\",\n    target: \"_new\"\n  }, \"these instructions from raspberrypi.org\"), \" to find your IP using other methods. Once you have your Pi\\u2019s IP address, type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ssh YOUR_PI_IP_ADDRESS -l pi\"), \"\\u201D and follow the previous instruction to log in with the default credentials.\"), mdx(\"h3\", null, \"Changing your password\"), mdx(\"p\", null, \"The absolute first thing that we need to do is change the default password. The easiest way to change the password is through \\u201Craspi-config\\u201D, which you can access by typing \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sudo raspi-config\"), \"\\u201D in your SSH terminal. Hit enter to select \\u201CChange User Password\\u201D, then enter your password. Back at the raspi-config window, hit tab twice to select \\u201CFinish\\u201D, then hit enter. The username \\u201Cpi\\u201D is now associated with whatever password you just set.\"), mdx(\"h3\", null, \"On to Ansible\"), mdx(\"p\", null, \"Ansible is an automation tool that lets us easily script a series of actions that we\\u2019d like to take place on our Pi. It\\u2019s big in the devops world, and it\\u2019s easy to see why\\u2013Ansible is relatively easy to get up and running compared to its alternatives. Its ease-of-use makes it a perfect candidate to set up a Pi.\"), mdx(\"p\", null, \"I created an Ansible Playbook to group all of our actions\\u2013you can \", mdx(\"a\", {\n    href: \"https://github.com/justinisamaker/ansible-pi\",\n    target: \"_new\"\n  }, \"clone it from my Github.\"), \" A playbook, in Ansible parlance, is just a collection of actions and the things that they need in order to run. Start by cloning the repo to your main computer. Once you have the repo cloned, open up the \\u201Chosts\\u201D file in your code editor. You\\u2019ll need to replace the \\u201CYOUR_PI_IP_HERE\\u201D and \\u201Cansible_user\\u201D/\\u201Cansible_password\\u201D sections with, you guessed it, your Pi\\u2019s IP and your username and password. If you forgot your IP from earlier, or if you didn\\u2019t have to get it because \\u201Craspberrypi.local\\u201D worked, you can just type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ifconfig\"), \"\\u201D in your SSH window and find the IP address listed under WLAN0 if you\\u2019re connected to the wifi. Enter your Pi\\u2019s IP and login information in the hosts file, then save.\"), mdx(\"h3\", null, \"Breaking down the Ansible tasks\"), mdx(\"p\", null, \"The actions that we\\u2019ll be taking on our Pi are all located in the \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/roles/common/files\"), \"\\u201D section of the Ansible-Pi repo you just cloned. These are fairly opinionated to what I use the Pi for, but the beauty of open source is that they\\u2019re all editable, so you can adjust them to your liking. Let\\u2019s walk through what each .sh file does:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"anti-raspbian-bloat: Removes packages that I don\\u2019t want on every installation, removes unused folders in /home/pi\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"configure-locale: Changes the locale from en_GB to en_US\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"set-keyboard-layout: Changes the keyboard layout from GB to US\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"set-timezone: Sets the timezone to \\u201CAmerica/Chicago\\u201D\")), mdx(\"p\", null, \"You can edit any of these files to better reflect your locale. If you\\u2019re comfortable with using English for the Pi and you\\u2019re located in the United States, all you should have to update is the timezone file.\"), mdx(\"p\", null, \"The next piece that we\\u2019ll look at is the actual list of tasks, which you can find in \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/roles/commons/tasks/main.yml\"), \"\\u201D. Let\\u2019s break that routine down:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Transfer init scripts: Moves everything from \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"/roles/common/files\"), \"\\u201D into your Pi\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Thin out Raspbian: Deletes unnecessary files/directories\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Upgrade apt cache: Makes sure we have the latest packages\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Upgrade dist: Step two of making sure our packages are up-to-date\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Configure locale\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Set timezone\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Set keyboard layout\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Install packages: Use this to install any packages you want to that you would usuall install with \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"li\"\n  }, \"apt-get-install\"), \"\\u201D. Right now I just have it set up to install TightVNC.\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"Reboot: restart the Pi to make sure our changes are applied\")), mdx(\"p\", null, \"Before we run this, you\\u2019ll need to install Ansible on your Mac. You can do this through \", mdx(\"a\", {\n    href: \"https://brew.sh/\",\n    target: \"_new\"\n  }, \"Homebrew\"), \" by running \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"brew install ansible\"), \"\\u201C.\"), mdx(\"p\", null, \"Now we\\u2019re on to the good stuff\\u2013actually running our playbook! On your Mac\\u2019s terminal, navigate to the folder that you cloned ansible-pi to, then run \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ansible-playbook -s -i hosts ansible-pi.yml\"), \"\\u201D. This tells Ansible to run our root playbook with sudo access using the hosts file from the repo. You should see the task names start to read out to your terminal. For a brand new Pi, each task should say the task name, and then a status message that should read \\u201Cchanged: YOUR_PI_IP_ADDRESS\\u201D. The only task that should fail is the final reboot task\\u2013the Pi will already be rebooting, so it can\\u2019t report back that the task finished successfully.\"), mdx(\"h3\", null, \"Making sure it worked\"), mdx(\"p\", null, \"After you\\u2019ve run the ansible playbook, SSH back into your Pi. If you type \", \"\\u201C\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ls\"), \"\\u201D in the home directory, you should only see the init folder that we transferred over. That means that your configuration worked, and you should be good to start using your Pi!\"));\n}\n;\nMDXContent.isMDXComponent = true;"},"next":{"id":"a3f7e8fa-53ac-5164-b4ed-ec9fb1efa7e6","fields":{"slug":"/put-to-light/"},"frontmatter":{"title":"A.C. Moore Put to Light"},"body":"var _excluded = [\"components\"];\n\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsxRuntime classic */\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"A.C. Moore Put to Light\",\n  \"date\": \"2018-07-10T00:00:00-0500\",\n  \"teaser\": \"A custom-built Put to Light system for A.C. Moore's warehouses to increase order processing speed and accuracy.\",\n  \"featuredImage\": \"ptl-walls.jpg\"\n};\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, _excluded);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Retailers have their work cut out for them if they\\u2019re going to keep up with Amazon. The scale and speed at which they operate has completely transformed consumer expectations\\u2013two-day shipping has become the de facto standard for delivered goods. A.C. Moore, a major arts and crafts retailer for the eastern part of the United States, realized that they would have a major problem on their hands if they didn\\u2019t adapt to meet that shipping speed. There\\u2019s only so much control that they have over an order when it leaves their warehouse, but they can control how quickly they process orders inside their operation.\"), mdx(\"p\", null, \"One of the pieces of their order fulfillment puzzle was a strategy called \\u201CPut to Light.\\u201D Whenever an order comes into their warehouse it is split into three major phases\\u2013picking, sorting, and packing. During the picking phase, items are retrieved from the warehouse floor and sent along conveyors in a series of \\u201Cpick waves.\\u201D When a pick wave is ready to be sorted, it gets diverted to a put wall. That\\u2019s where I come in! A.C. Moore knew that they wanted put walls, but they weren\\u2019t happy with the existing options, and they wanted one that would integrate perfectly with their custom-built warehouse management system. They asked if I could build them nine custom put walls, and before I knew it, I was knee deep in warehouse logistics!\"), mdx(\"div\", {\n    \"className\": \"image-container large-image\"\n  }, \"\\n  \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1200px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/64d95373b0eb3bf4163bfb0cb4075088/89513/ptl-walls.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"66.33333333333333%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAQBAgMF/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAVZbsc83I//EABwQAAIABwAAAAAAAAAAAAAAAAABAgMQERIhMf/aAAgBAQABBQJy9wqw6PmKP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABYQAAMAAAAAAAAAAAAAAAAAABAgMf/aAAgBAQAGPwIRP//EABkQAAMBAQEAAAAAAAAAAAAAAAABESExYf/aAAgBAQABPyGERz0bprPEJXVQt6Jo7Yf/2gAMAwEAAgADAAAAEOjf/8QAFREBAQAAAAAAAAAAAAAAAAAAEBH/2gAIAQMBAT8Qh//EABYRAQEBAAAAAAAAAAAAAAAAABEAAf/aAAgBAgEBPxBwm//EABsQAQEAAgMBAAAAAAAAAAAAAAERACExQVHw/9oACAEBAAE/ENWKrttDnBRUfa4dUXu40CjXhlAIUlnGDtdvUz//2Q==')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The completed put walls\",\n    \"title\": \"The completed put walls\",\n    \"src\": \"/static/64d95373b0eb3bf4163bfb0cb4075088/e5166/ptl-walls.jpg\",\n    \"srcSet\": [\"/static/64d95373b0eb3bf4163bfb0cb4075088/f93b5/ptl-walls.jpg 300w\", \"/static/64d95373b0eb3bf4163bfb0cb4075088/b4294/ptl-walls.jpg 600w\", \"/static/64d95373b0eb3bf4163bfb0cb4075088/e5166/ptl-walls.jpg 1200w\", \"/static/64d95373b0eb3bf4163bfb0cb4075088/d9c39/ptl-walls.jpg 1800w\", \"/static/64d95373b0eb3bf4163bfb0cb4075088/df51d/ptl-walls.jpg 2400w\", \"/static/64d95373b0eb3bf4163bfb0cb4075088/89513/ptl-walls.jpg 4288w\"],\n    \"sizes\": \"(max-width: 1200px) 100vw, 1200px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n  \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The completed put walls\")), mdx(\"p\", null, \"At its core a put wall is a fairly simple technology. We needed to be able to light up a specific location under a bin on a shelf where an item would be placed, and then listen for a button click to confirm that the picker put the item in the bin. While simple from a hardware perspective, there is a lot that needs to happen on the software side of things, and it gets increasingly complex as you try to scale it. Whatever solution I came up with needed to be able to communicate to the endpoints of their warehouse management system (WMS). It also needed to be able to do it for roughly 500 bins at a time, with absolutely no errors, as fast as it possibly could.\"), mdx(\"div\", {\n    className: \"paragraph-with-picture\"\n  }, mdx(\"p\", null, \"I decided to use a Raspberry Pi for the brain of each put wall. We needed to be able to perform some pretty complex handshakes with the WMS that would have been an absolute nightmare to attempt on an Arduino. While the Pi was better-suited for the networking side, it does not ship with the kind of inputs and outputs that we needed. Each put wall needed to listen to 52 buttons and run approximately six thousand WS2812B LEDs.\", mdx(\"br\", null), mdx(\"br\", null), \"The first thing to account for were the buttons. We needed twice as many inputs as were available on the Pi, which meant that I\\u2019d have to find an external way to expand the I/O capabilities. I sourced an excellent stackable HAT from ModMyPi that gave us access to two MCP23017 port expander chips. By stacking two of these HATs on the Pi we could move all of the inputs from the buttons off of the main GPIO pins. That left enough room for us to drive the extremely long LED strips and account for all the buttons.\"), mdx(\"div\", {\n    \"className\": \"image-container small-image\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"div\",\n    \"className\": \"gatsby-resp-image-wrapper\",\n    \"style\": {\n      \"position\": \"relative\",\n      \"display\": \"block\",\n      \"marginLeft\": \"auto\",\n      \"marginRight\": \"auto\",\n      \"maxWidth\": \"1200px\"\n    }\n  }, \"\\n      \", mdx(\"a\", {\n    parentName: \"span\",\n    \"className\": \"gatsby-resp-image-link\",\n    \"href\": \"/static/c7c17638e588ddb37456820b250c05dc/9568a/gpio-config.jpg\",\n    \"style\": {\n      \"display\": \"block\"\n    },\n    \"target\": \"_blank\",\n    \"rel\": \"noopener\"\n  }, \"\\n    \", mdx(\"span\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-background-image\",\n    \"style\": {\n      \"paddingBottom\": \"133.33333333333331%\",\n      \"position\": \"relative\",\n      \"bottom\": \"0\",\n      \"left\": \"0\",\n      \"backgroundImage\": \"url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAbABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEAgH/xAAWAQEBAQAAAAAAAAAAAAAAAAACAwH/2gAMAwEAAhADEAAAAV7xAKVDRyUp4VwhNX//xAAbEAABBAMAAAAAAAAAAAAAAAABAAIRIQMSMv/aAAgBAQABBQLYElzYeLyAQKVrI2tFIBPLuF//xAAYEQEBAAMAAAAAAAAAAAAAAAAAARESQf/aAAgBAwEBPwHixlvX/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAEREP/aAAgBAgEBPwGCyH//xAAbEAACAgMBAAAAAAAAAAAAAAAAASExEBEggf/aAAgBAQAGPwIsobhCIa9N4lrj/8QAGxABAAMAAwEAAAAAAAAAAAAAAQARITFBUWH/2gAIAQEAAT8hULeeiVVGJS+kw3wPfsFkkV6AYZr5JariwGrKuAjGZzP/2gAMAwEAAgADAAAAELvqfP/EABcRAQEBAQAAAAAAAAAAAAAAAAEAETH/2gAIAQMBAT8QMQ5At1kR/8QAGBEBAQADAAAAAAAAAAAAAAAAAAEhMXH/2gAIAQIBAT8Q6VhNLD//xAAeEAEAAwACAgMAAAAAAAAAAAABABEhMUFRcYGh8f/aAAgBAQABPxCp0OWle4sLuFeXiOtFKfbE4jhu2uk998ZxHR2m7cLiHKgBb+QElhSdwBBVWtY0RoFsADr5hi1teY6nC6zkrqs//9k=')\",\n      \"backgroundSize\": \"cover\",\n      \"display\": \"block\"\n    }\n  }), \"\\n  \", mdx(\"img\", {\n    parentName: \"a\",\n    \"className\": \"gatsby-resp-image-image\",\n    \"alt\": \"The MCP23017 HAT with everything plugged in\",\n    \"title\": \"The MCP23017 HAT with everything plugged in\",\n    \"src\": \"/static/c7c17638e588ddb37456820b250c05dc/e5166/gpio-config.jpg\",\n    \"srcSet\": [\"/static/c7c17638e588ddb37456820b250c05dc/f93b5/gpio-config.jpg 300w\", \"/static/c7c17638e588ddb37456820b250c05dc/b4294/gpio-config.jpg 600w\", \"/static/c7c17638e588ddb37456820b250c05dc/e5166/gpio-config.jpg 1200w\", \"/static/c7c17638e588ddb37456820b250c05dc/d9c39/gpio-config.jpg 1800w\", \"/static/c7c17638e588ddb37456820b250c05dc/df51d/gpio-config.jpg 2400w\", \"/static/c7c17638e588ddb37456820b250c05dc/9568a/gpio-config.jpg 3024w\"],\n    \"sizes\": \"(max-width: 1200px) 100vw, 1200px\",\n    \"style\": {\n      \"width\": \"100%\",\n      \"height\": \"100%\",\n      \"margin\": \"0\",\n      \"verticalAlign\": \"middle\",\n      \"position\": \"absolute\",\n      \"top\": \"0\",\n      \"left\": \"0\"\n    },\n    \"loading\": \"lazy\"\n  }), \"\\n  \"), \"\\n    \"), \"\\n    \", mdx(\"a\", {\n    parentName: \"div\",\n    \"className\": \"image-caption\"\n  }, \"The MCP23017 HAT with everything plugged in\"), \"\\n  \")), mdx(\"p\", null, \"The LEDs were split into two long zig-zag strips\\u2013one for the putting side on the front, and one for the packing side on the back. The general idea is that when an item is scanned, the bin that it goes in will light up blue on the front of the wall. When a picker places the item in that bin, they hit the button, and then the system checks if anything else needs to go into the bin to complete the order. If the order is ready to ship, then the LEDs on the other side of the wall light up green to let the shipping department know that the bin is ready to be pulled from the wall and packed for shipping. At 3,000 pixels long we were definitely stretching the boundaries of what our Neopixels were capable of. We were, however, able to get great performance out of them thanks to a beefy power supply that was introduced at multiple parts of the circuit and no need for animation along the strips. Ultimately each wall would only have 30 or 40 LEDs turned on at a time in most cases, so we were able to run both strips from two pins on the Pi. We wanted to go with a full RGB LED rather than a solid-colored strip in order to communicate different phases of a pick wave. For instance, if a picker realized that something was wrong after they confirmed an item\\u2019s placement, they could flag the location for a QA check from the tablet computer attached to the wall. This would then light up the front and back of the location with orange lights to let both sides know not to proceed with that bin.\"), mdx(\"p\", null, \"After I squared away the physical production side of mounting all the buttons and running all the LEDs, we needed to determine the most efficient way for the Pi to communicate with the WMS. I decided to build a custom API that communicated with the WMS via a MQTT server. MQTT has been around since 1999, but has become increasingly popular because of its usefulness in IoT projects. As its core, MQTT is a super lightweight pub/sub communicator that lets you rapidly send or receive small bits of information. This was perfect for our use case\\u2013the wall would subscribe to lighting messages coming from the WMS, and then publish button presses back to the WMS. In addition to the speed of MQTT, you can also set a quality of service. This means that you can say if you want a message to continue trying to send until it receives a confirmation that the message was received. Having the system be able to confirm a message like that was a huge help in making sure that there were zero errors during processing.\"), mdx(\"p\", null, \"We had the luxury of setting up a brand new warehouse for A.C. Moore in Chicago at the start of this project, so we began by only running three of the nine put walls on the new system to make sure that everything worked. There was a fair amount of wear and tear on the shelves since everyone is the warehouse is moving so quickly, but I designed the system to be as modular as possible and to be simple enough for any of the warehouse managers to repair. After a few tweaks to the physical design of the system, we rolled out the other six walls right before Black Friday, where they ran for almost two days solid. Since then A.C. Moore has also installed five of the walls in their main warehouses in Berlin, New Jersey.\"), mdx(\"p\", null, \"The whole process can be a lot to wrap your head around if you aren\\u2019t familiar with warehouse logistics. Check out the video below to see what a full pick wave looked like when I was testing it with an A.C. Moore employee.\"), mdx(\"video\", {\n    src: \"/41af92184c63a761f93160b0ff68ccf8/blitsy-pick-wave.mp4\",\n    controls: true,\n    muted: true,\n    autoPlay: true,\n    loop: true\n  }), mdx(\"br\", null), mdx(\"br\", null));\n}\n;\nMDXContent.isMDXComponent = true;"}}},"staticQueryHashes":["3128451518"]}