<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Devhour</title>
	<atom:link href="https://www.devhour.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.devhour.net</link>
	<description>Taking time to write about development</description>
	<lastBuildDate>Wed, 20 Mar 2024 08:42:41 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>

<image>
	<url>https://www.devhour.net/wp-content/uploads/2024/03/cropped-devhourlogo-32x32.png</url>
	<title>Devhour</title>
	<link>https://www.devhour.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Monitoring air quality with a Raspberry Pi &#038; PMS5003 Sensor</title>
		<link>https://www.devhour.net/monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor</link>
					<comments>https://www.devhour.net/monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Wed, 20 Mar 2024 07:05:52 +0000</pubDate>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[Air Quality]]></category>
		<category><![CDATA[BME680]]></category>
		<category><![CDATA[Humidity]]></category>
		<category><![CDATA[PM10]]></category>
		<category><![CDATA[PM2.5]]></category>
		<category><![CDATA[PMS5003]]></category>
		<category><![CDATA[Pressure]]></category>
		<category><![CDATA[Temperature]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=118</guid>

					<description><![CDATA[<p>Unfortunately my family and I live in a country that doesn&#8217;t have the greatest air quality. In order to see how bad it really is I have decided to pull out the Raspberry Pi yet again. Once attached to a Particle Matter sensor I&#8217;ll have my own basic Air Quality/Weather station. This somewhat flows on [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor/">Monitoring air quality with a Raspberry Pi & PMS5003 Sensor</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Unfortunately my family and I live in a country that doesn&#8217;t have the greatest air quality. In order to see how bad it really is I have decided to pull out the Raspberry Pi yet again. Once attached to a Particle Matter sensor I&#8217;ll have my own basic Air Quality/Weather station. This somewhat flows on from my previous series &#8211; <a href="https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/" title="Raspberry Pi and Motion (Weather App Pt 2) (Revised)">Raspberry Pi and Motion (Weather App Pt 2) (Revised)</a>.</p>



<h2 class="wp-block-heading">Particulate Matter and Air Quality Index</h2>



<p>Air Quality Index (AQI) serves as a crucial tool to convey the current level of air pollution. Health risks increase as the AQI rises. The common pollutants tracked by AQI include ground-level ozone, particulate matter, carbon monoxide, sulfur dioxide, and nitrogen dioxide.</p>



<p>Particulate matter (PM) refers to a mixture of solid particles and liquid droplets found in the air. Particulate matter can be categorized based on the size of the particles:</p>



<ul class="wp-block-list">
<li><strong>PM1.0</strong> refers to particles that are 1.0 micron or smaller in diameter. These particles are so small that they can penetrate the lungs and may even enter the bloodstream, posing significant health risks.</li>



<li><strong>PM2.5</strong>, also known as fine particulate matter, includes particles that are 2.5 microns or smaller in diameter. Because of their size, they can penetrate deep into the lung tissue and have been linked to a variety of health problems, from minor eye and throat irritation to more serious conditions such as heart attacks and decreased lung function.</li>



<li><strong>PM10</strong> includes particles that are 10 microns or smaller in diameter. These particles can cause health issues by irritating the eyes, nose, and throat, and can affect the heart and lungs, making pre-existing lung and heart conditions worse.</li>
</ul>



<h2 class="wp-block-heading">Components Required</h2>



<p>So, to get started, here is a short list of the key components you&#8217;ll need &#8211; at the very least &#8211; to get this small project up and running.</p>



<ul class="wp-block-list">
<li><a href="https://amzn.to/3To5eqb" target="_blank" rel="noopener" title="Raspberry Pi Zero 2 W">Raspberry Pi Zero 2 W</a> (also tested and working on the Raspberry Pi 4 Model B and original Model B)</li>



<li><a href="https://amzn.to/3VGDJej" target="_blank" rel="noopener" title="">PMS5003 Particulate Matter Sensor w/ Breakout Board</a>
<ul class="wp-block-list">
<li><a href="https://shop.pimoroni.com/products/pms5003-particulate-matter-sensor-with-cable?variant=29075640352851" target="_blank" rel="noopener" title="PMS5003 Particulate Matter Sensor">PMS5003 Particulate Matter Sensor</a> (I have also had success with this sensor and breakout from Pimoroni)</li>



<li><a href="https://shop.pimoroni.com/products/particulate-matter-sensor-breakout?variant=29493578301523" target="_blank" rel="noopener" title="Particulate Matter Sensor Breakout">Particulate Matter Sensor Breakout</a></li>
</ul>
</li>



<li><a href="https://amzn.to/3IFOSnI" target="_blank" rel="noopener" title="BME680 Sensor">BME680 Sensor</a> Temperature, Pressure, and Humidity Sensor (Not necessary but can also provide useful additional data)</li>



<li><a href="https://amzn.to/43qo0BB" target="_blank" rel="noopener" title="">Jumper Cables</a> &#8211; Extremely useful for connecting the sensors to the Raspberry Pi</li>
</ul>



<p>I went with the Raspberry Pi Zero because the end goal of this is to stick it outside in a weatherproof enclosure so space will be a limiting factor in the final revision. Key an eye out for future parts where I do that as well as try my hand at PCB design for the ultimate Weather HAT (Hardware Attached on Top).</p>



<h2 class="wp-block-heading">Raspberry Pi Wiring Guide</h2>



<p>Fortunately for us, the wiring for this project is super straight forward. No additional resistors will be required so it&#8217;s as simple as attaching the pins of the sensor to the corresponding pins on the Raspberry Pi.</p>



<p>The two tables below show the pin-out from the sensor boards and the pin that it will be plugged into on the Pi.</p>



<figure class="wp-block-table"><table><tbody><tr><td><strong>Raspberry Pi GPIO Pin</strong></td><td><strong>PMS5003 Breakout Board</strong></td></tr><tr><td>Pin #2 5v</td><td>Pin #1 5v</td></tr><tr><td>Pin #6 Ground</td><td>Pin #2 GND</td></tr><tr><td>Pin #8 GPIO 14 (TXD)</td><td>Pin #3 TX</td></tr><tr><td>Pin #10 GPIO 15 (RXD)</td><td>Pin #4 RX</td></tr><tr><td>Pin #11 GPIO 17</td><td>Pin #5 Reset</td></tr><tr><td>&#8211;</td><td>Pin #6 EN</td></tr></tbody></table><figcaption class="wp-element-caption">Mapping between Raspberry Pi and PMS5003 Sensor</figcaption></figure>



<p></p>



<figure class="wp-block-table"><table><tbody><tr><td>Raspberry Pi GPIO Pin</td><td>BME680 Breakout Board</td></tr><tr><td>Pin #1 3.3v</td><td>Pin #1 2-5v</td></tr><tr><td>Pin #3 GPIO 2 SDA</td><td>Pin #2 SDA</td></tr><tr><td>Pin #5 GPIO 3 SCL</td><td>Pin #3 SCL</td></tr><tr><td>&#8211;</td><td>Pin #4 N/A</td></tr><tr><td>Pin #9 Ground</td><td>Pin #5 GND</td></tr></tbody></table><figcaption class="wp-element-caption">Mapping between Raspberry Pi and BME680 Sensor</figcaption></figure>



<p>And here is a simple diagram for those who are more visually inclined!</p>


<div class="wp-block-image">
<figure class="aligncenter"><img fetchpriority="high" decoding="async" width="624" height="504" src="https://www.devhour.net/wp-content/uploads/2024/03/rpi.png" alt="Raspberry Pi Wiring Diagram" class="wp-image-152" srcset="https://www.devhour.net/wp-content/uploads/2024/03/rpi.png 624w, https://www.devhour.net/wp-content/uploads/2024/03/rpi-300x242.png 300w" sizes="(max-width: 624px) 100vw, 624px" /><figcaption class="wp-element-caption">Wiring Diagram of the Raspberry Pi and PMS5003/BME680 Sensors</figcaption></figure></div>


<h2 class="wp-block-heading">Software Installation</h2>



<h3 class="wp-block-heading">Raspberry Pi Setup</h3>



<p>Firstly, you will need to enable I2C and Serial Port Interfaces on the Pi. Do this by opening the configuration screen:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo raspi-config" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">raspi-config</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Choose &#8216;Interface Options&#8217; and do the following:</p>



<ol class="wp-block-list">
<li>Enable I2C</li>



<li>Serial Port &#8211; Disable Login Shell</li>



<li>Serial Port &#8211; Enable Serial Port Hardware</li>
</ol>



<p>Next, we need to manually adjust some of the other config settings of the Pi. </p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo nano /boot/config.txt" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">nano</span><span style="color: #575279"> </span><span style="color: #EA9D34">/boot/config.txt</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Add the following lines to the bottom in order to adjust the communication rate of the I2C interface, and switch the Bluetooth functionality of the Raspberry Pi to mini UART.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="dtparam=i2c_arm_baudrate=10000
enable_uart=1
dtoverlay=pi3-miniuart-bt" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #575279">dtparam=i2c_arm_baudrate=10000</span></span>
<span class="line"><span style="color: #575279">enable_uart=1</span></span>
<span class="line"><span style="color: #575279">dtoverlay=pi3-miniuart-bt</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Plaintext</span></div>



<p>Save the file (Ctrl+x) and reboot the device.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo reboot" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">reboot</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Once rebooted we can then install Python and a few essential pieces of software in order to communicate programmatically with the sensors.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo apt install build-essential git i2c-tools python3-dev python3-setuptools python3-venv python3-requests python3-smbus python3-serial python3-tz" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">apt</span><span style="color: #575279"> </span><span style="color: #EA9D34">install</span><span style="color: #575279"> </span><span style="color: #EA9D34">build-essential</span><span style="color: #575279"> </span><span style="color: #EA9D34">git</span><span style="color: #575279"> </span><span style="color: #EA9D34">i2c-tools</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-dev</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-setuptools</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-venv</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-requests</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-smbus</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-serial</span><span style="color: #575279"> </span><span style="color: #EA9D34">python3-tz</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>I always recommend creating a virtual environment for new projects because it keeps everything a little more segregated and reduces the risks of conflicts and other issues.</p>



<h3 class="wp-block-heading">Environment Setup</h3>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mkdir weather &amp;&amp; cd weather
python3 -m venv .venv
source .venv/bin/activate" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">mkdir</span><span style="color: #575279"> </span><span style="color: #EA9D34">weather</span><span style="color: #575279"> </span><span style="color: #797593">&amp;&amp;</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">cd</span><span style="color: #575279"> </span><span style="color: #EA9D34">weather</span></span>
<span class="line"><span style="color: #D7827E">python3</span><span style="color: #575279"> </span><span style="color: #286983">-m</span><span style="color: #575279"> </span><span style="color: #EA9D34">venv</span><span style="color: #575279"> </span><span style="color: #EA9D34">.venv</span></span>
<span class="line"><span style="color: #B4637A; font-style: italic">source</span><span style="color: #575279"> </span><span style="color: #EA9D34">.venv/bin/activate</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Now let&#8217;s install python libraries for the PMS5003 and BME680 sensors</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="pip install pms5003 adafruit-circuitpython-bme680 adafruit_extended_bus" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">pip</span><span style="color: #575279"> </span><span style="color: #EA9D34">install</span><span style="color: #575279"> </span><span style="color: #EA9D34">pms5003</span><span style="color: #575279"> </span><span style="color: #EA9D34">adafruit-circuitpython-bme680</span><span style="color: #575279"> </span><span style="color: #EA9D34">adafruit_extended_bus</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<h2 class="wp-block-heading">Testing</h2>



<p>Let&#8217;s create a couple of python files now in order to use these libraries to connect and read the data coming from the sensors:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="nano pmSensor.py" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">nano</span><span style="color: #575279"> </span><span style="color: #EA9D34">pmSensor.py</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="from pms5003 import PMS5003

pms5003 = PMS5003(device=&quot;/dev/ttyAMA0&quot;, baudrate=9600, pin_enable=&quot;GPIO22&quot;, pin_reset=&quot;GPIO27&quot;)

data = pms5003.read()
print(data)" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #286983">from</span><span style="color: #575279"> pms5003 </span><span style="color: #286983">import</span><span style="color: #575279"> </span><span style="color: #286983">PMS5003</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">pms5003 </span><span style="color: #286983">=</span><span style="color: #575279"> PMS5003</span><span style="color: #797593">(</span><span style="color: #907AA9; font-style: italic">device</span><span style="color: #286983">=</span><span style="color: #EA9D34">&quot;/dev/ttyAMA0&quot;</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">baudrate</span><span style="color: #286983">=</span><span style="color: #D7827E">9600</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">pin_enable</span><span style="color: #286983">=</span><span style="color: #EA9D34">&quot;GPIO22&quot;</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">pin_reset</span><span style="color: #286983">=</span><span style="color: #EA9D34">&quot;GPIO27&quot;</span><span style="color: #797593">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">data </span><span style="color: #286983">=</span><span style="color: #575279"> pms5003</span><span style="color: #797593">.</span><span style="color: #575279">read</span><span style="color: #797593">()</span></span>
<span class="line"><span style="color: #B4637A; font-style: italic">print</span><span style="color: #797593">(</span><span style="color: #575279">data</span><span style="color: #797593">)</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Python</span></div>



<p>Save the file and then run it.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="python3 pmSensor.py" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">python3</span><span style="color: #575279"> </span><span style="color: #EA9D34">pmSensor.py</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>And you should see the following output:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="PM1.0 ug/m3 (ultrafine particles):                             35
PM2.5 ug/m3 (combustion particles, organic compounds, metals): 53
PM10 ug/m3  (dust, pollen, mould spores):                      55
PM1.0 ug/m3 (atmos env):                                       28
PM2.5 ug/m3 (atmos env):                                       43
PM10 ug/m3 (atmos env):                                        51
&gt;0.3um in 0.1L air:                                            5892
&gt;0.5um in 0.1L air:                                            1656
&gt;1.0um in 0.1L air:                                            324
&gt;2.5um in 0.1L air:                                            25
&gt;5.0um in 0.1L air:                                            1
&gt;10um in 0.1L air:                                             0" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #575279">PM1.0 ug/m3 (ultrafine particles):                             35</span></span>
<span class="line"><span style="color: #575279">PM2.5 ug/m3 (combustion particles, organic compounds, metals): 53</span></span>
<span class="line"><span style="color: #575279">PM10 ug/m3  (dust, pollen, mould spores):                      55</span></span>
<span class="line"><span style="color: #575279">PM1.0 ug/m3 (atmos env):                                       28</span></span>
<span class="line"><span style="color: #575279">PM2.5 ug/m3 (atmos env):                                       43</span></span>
<span class="line"><span style="color: #575279">PM10 ug/m3 (atmos env):                                        51</span></span>
<span class="line"><span style="color: #575279">&gt;0.3um in 0.1L air:                                            5892</span></span>
<span class="line"><span style="color: #575279">&gt;0.5um in 0.1L air:                                            1656</span></span>
<span class="line"><span style="color: #575279">&gt;1.0um in 0.1L air:                                            324</span></span>
<span class="line"><span style="color: #575279">&gt;2.5um in 0.1L air:                                            25</span></span>
<span class="line"><span style="color: #575279">&gt;5.0um in 0.1L air:                                            1</span></span>
<span class="line"><span style="color: #575279">&gt;10um in 0.1L air:                                             0</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Plaintext</span></div>



<p>Next, for the BME680 sensor</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="nano bme680.py" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">nano</span><span style="color: #575279"> </span><span style="color: #EA9D34">bme680.py</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="import adafruit_bme680
import time
import board

from adafruit_extended_bus import ExtendedI2C as I2C

i2c = I2C(1)

bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c)

# Change this to the pressure at sea level in your location
bme680.sea_level_pressure = 1002.25

temp = &quot;%0.1f&quot; % bme680.temperature
humidity = &quot;%0.1f&quot; % bme680.relative_humidity
pressure = &quot;%0.3f&quot; % bme680.pressure
altitude = &quot;%0.2f&quot; % bme680.altitude
                
data = {
  'Temperature': temp,
  'Pressure': pressure,
  'Humidity': humidity,
  'Altitude': altitude
}

print(data)" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #286983">import</span><span style="color: #575279"> adafruit_bme680</span></span>
<span class="line"><span style="color: #286983">import</span><span style="color: #575279"> time</span></span>
<span class="line"><span style="color: #286983">import</span><span style="color: #575279"> board</span></span>
<span class="line"></span>
<span class="line"><span style="color: #286983">from</span><span style="color: #575279"> adafruit_extended_bus </span><span style="color: #286983">import</span><span style="color: #575279"> ExtendedI2C </span><span style="color: #286983">as</span><span style="color: #575279"> </span><span style="color: #286983">I2C</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">i2c </span><span style="color: #286983">=</span><span style="color: #575279"> I2C</span><span style="color: #797593">(</span><span style="color: #D7827E">1</span><span style="color: #797593">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">bme680 </span><span style="color: #286983">=</span><span style="color: #575279"> adafruit_bme680</span><span style="color: #797593">.</span><span style="color: #575279">Adafruit_BME680_I2C</span><span style="color: #797593">(</span><span style="color: #575279">i2c</span><span style="color: #797593">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #797593; font-style: italic">#</span><span style="color: #9893A5; font-style: italic"> Change this to the pressure at sea level in your location</span></span>
<span class="line"><span style="color: #575279">bme680</span><span style="color: #797593">.</span><span style="color: #575279">sea_level_pressure </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #D7827E">1002.25</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">temp </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;</span><span style="color: #286983">%0.1f</span><span style="color: #EA9D34">&quot;</span><span style="color: #575279"> </span><span style="color: #286983">%</span><span style="color: #575279"> bme680</span><span style="color: #797593">.</span><span style="color: #575279">temperature</span></span>
<span class="line"><span style="color: #575279">humidity </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;</span><span style="color: #286983">%0.1f</span><span style="color: #EA9D34">&quot;</span><span style="color: #575279"> </span><span style="color: #286983">%</span><span style="color: #575279"> bme680</span><span style="color: #797593">.</span><span style="color: #575279">relative_humidity</span></span>
<span class="line"><span style="color: #575279">pressure </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;</span><span style="color: #286983">%0.3f</span><span style="color: #EA9D34">&quot;</span><span style="color: #575279"> </span><span style="color: #286983">%</span><span style="color: #575279"> bme680</span><span style="color: #797593">.</span><span style="color: #575279">pressure</span></span>
<span class="line"><span style="color: #575279">altitude </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;</span><span style="color: #286983">%0.2f</span><span style="color: #EA9D34">&quot;</span><span style="color: #575279"> </span><span style="color: #286983">%</span><span style="color: #575279"> bme680</span><span style="color: #797593">.</span><span style="color: #575279">altitude</span></span>
<span class="line"><span style="color: #575279">                </span></span>
<span class="line"><span style="color: #575279">data </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #EA9D34">&#39;Temperature&#39;</span><span style="color: #797593">:</span><span style="color: #575279"> temp</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #EA9D34">&#39;Pressure&#39;</span><span style="color: #797593">:</span><span style="color: #575279"> pressure</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #EA9D34">&#39;Humidity&#39;</span><span style="color: #797593">:</span><span style="color: #575279"> humidity</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #EA9D34">&#39;Altitude&#39;</span><span style="color: #797593">:</span><span style="color: #575279"> altitude</span></span>
<span class="line"><span style="color: #797593">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #B4637A; font-style: italic">print</span><span style="color: #797593">(</span><span style="color: #575279">data</span><span style="color: #797593">)</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Python</span></div>



<p>Save it and run it:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="python3 bme680.py" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">python3</span><span style="color: #575279"> </span><span style="color: #EA9D34">bme680.py</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>And the output will appear as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="{'Temperature': '34.0', 'Pressure': '681.287', 'Humidity': '100.0', 'Altitude': '19.72'}" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #575279">{&#39;Temperature&#39;: &#39;34.0&#39;, &#39;Pressure&#39;: &#39;681.287&#39;, &#39;Humidity&#39;: &#39;100.0&#39;, &#39;Altitude&#39;: &#39;19.72&#39;}</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Plaintext</span></div>



<p>I have found that I have to run the BME680 sensor script 3-4 times before it gives me consistent (and I assume) accurate readings.</p>



<h2 class="wp-block-heading">AirQualityPi Project</h2>



<p>As discussed earlier, this is part of a bigger project which I&#8217;ve dubbed AirQualityPi. The idea is to read these sensors several times per hour and store the data. This data can then be displayed on a web dashboard in order to view current values as well as weekly, monthly, and yearly trends as data is gathered.</p>



<p>All of this data flow will be handled via an API (both reading and writing) which I&#8217;ll discuss in a later post. You can view the <a href="https://github.com/Kingy/AirQualityPiSensors/" target="_blank" rel="noopener" title="AirQualityPiSensor">AirQualityPiSensor</a> code over on my GitHub, and keep an eye out for my future posts where I&#8217;ll go over the rest of the project.</p><p>The post <a href="https://www.devhour.net/monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor/">Monitoring air quality with a Raspberry Pi & PMS5003 Sensor</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/monitoring-air-quality-with-a-raspberry-pi-pms5003-sensor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Migrating email to google apps</title>
		<link>https://www.devhour.net/migrating-email-to-google-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrating-email-to-google-apps</link>
					<comments>https://www.devhour.net/migrating-email-to-google-apps/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Tue, 21 Jul 2015 12:38:00 +0000</pubDate>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[gmail]]></category>
		<category><![CDATA[google apps]]></category>
		<category><![CDATA[imapsync]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=42</guid>

					<description><![CDATA[<p>After months of servicing an email account which kept requiring me to delete emails to free up space I finally decided to make the switch to Google Apps and take advantage of GMail and apps for businesses. The setup process of Google Apps was very straight forward however the process of migrating email from one account to [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/migrating-email-to-google-apps/">Migrating email to google apps</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>After months of servicing an email account which kept requiring me to delete emails to free up space I finally decided to make the switch to <a href="http://google.com/apps" target="_blank" rel="noreferrer noopener">Google Apps</a> and take advantage of GMail and apps for businesses.</p>



<p>The setup process of Google Apps was very straight forward however the process of migrating email from one account to the other proved frustrating at best. Google Apps has a built in migration tool but because it was unable to verify the ssl certificate on the other server it wouldn’t continue the process.</p>



<p>Step 2 was to try an app on the Google Apps marketplace called <a href="http://getcarbo.com/" target="_blank" rel="noreferrer noopener">Carbo</a>. This was happy enough to connect to the other server and even started bringing in the emails, but after importing email 90/2878 I got an email saying it was complete. Trying to restart the process to try again proved useless as I had used my 1 and only free migration.</p>



<p>Back to the drawing board and I found a perl script which has been recommended called <a href="https://github.com/imapsync/imapsync" target="_blank" rel="noreferrer noopener">imapsync</a>. While this was a little more manual than I would have liked, it actually worked beautifully and all mail was imported successfully. Below I’ll outline exactly what needed to be done…</p>



<p>Running it on Debian 7 was apparently ‘not easy’ according to the install notes. But in reality there were only a few commands that were needed to be run.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo apt-get install libauthen-ntlm-perl libcrypt-ssleay-perl libdigest-hmac-perl libfile-copy-recursive-perl libio-compress-perl libio-socket-inet6-perl libio-socket-ssl-perl libio-tee-perl libmail-imapclient-perl libmodule-scandeps-perl libnet-ssleay-perl libpar-packer-perl libterm-readkey-perl libtest-pod-perl libtest-simple-perl libunicode-string-perl liburi-perl" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">apt-get</span><span style="color: #575279"> </span><span style="color: #EA9D34">install</span><span style="color: #575279"> </span><span style="color: #EA9D34">libauthen-ntlm-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libcrypt-ssleay-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libdigest-hmac-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libfile-copy-recursive-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libio-compress-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libio-socket-inet6-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libio-socket-ssl-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libio-tee-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libmail-imapclient-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libmodule-scandeps-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libnet-ssleay-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libpar-packer-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libterm-readkey-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libtest-pod-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libtest-simple-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">libunicode-string-perl</span><span style="color: #575279"> </span><span style="color: #EA9D34">liburi-perl</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>This will install all the perl dependencies that are needed.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="cpan Data::Uniqid" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">cpan</span><span style="color: #575279"> </span><span style="color: #EA9D34">Data::Uniqid</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>We manually need to install this perl dependency because debian doesn’t have a package available for it yet.</p>



<p>Next either clone or download the <a href="https://github.com/imapsync/imapsync" target="_blank" rel="noreferrer noopener">imapsync</a> zip from its <a href="https://github.com/imapsync/imapsync" target="_blank" rel="noreferrer noopener">github </a>site.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="git clone https://github.com/imapsync/imapsync.git
cd imapsync
sudo make install" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">git</span><span style="color: #575279"> </span><span style="color: #EA9D34">clone</span><span style="color: #575279"> </span><span style="color: #EA9D34">https://github.com/imapsync/imapsync.git</span></span>
<span class="line"><span style="color: #B4637A; font-style: italic">cd</span><span style="color: #575279"> </span><span style="color: #EA9D34">imapsync</span></span>
<span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">make</span><span style="color: #575279"> </span><span style="color: #EA9D34">install</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>And finally run the sync with the following (making sure you change the bits in &lt;>):</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="imapsync --syncinternaldates --host1 &lt;host1&gt; --port1 993 --ssl1 --user1 &lt;user1&gt; --password1 &lt;pass1&gt; --host2 imap.gmail.com --port2 993 --ssl2 --user2 &lt;user2@email.com&gt; --password2 &lt;pass2&gt; --useheader 'Message-Id' --skipsize --noauthmd5 --reconnectretry1 1 --reconnectretry2 1" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">imapsync</span><span style="color: #575279"> </span><span style="color: #286983">--syncinternaldates</span><span style="color: #575279"> </span><span style="color: #286983">--host1</span><span style="color: #575279"> </span><span style="color: #286983">&lt;</span><span style="color: #EA9D34">host</span><span style="color: #286983">1&gt;</span><span style="color: #575279"> </span><span style="color: #286983">--port1</span><span style="color: #575279"> </span><span style="color: #D7827E">993</span><span style="color: #575279"> </span><span style="color: #286983">--ssl1</span><span style="color: #575279"> </span><span style="color: #286983">--user1</span><span style="color: #575279"> </span><span style="color: #286983">&lt;</span><span style="color: #EA9D34">user</span><span style="color: #286983">1&gt;</span><span style="color: #575279"> </span><span style="color: #286983">--password1</span><span style="color: #575279"> </span><span style="color: #286983">&lt;</span><span style="color: #EA9D34">pass</span><span style="color: #286983">1&gt;</span><span style="color: #575279"> </span><span style="color: #286983">--host2</span><span style="color: #575279"> </span><span style="color: #EA9D34">imap.gmail.com</span><span style="color: #575279"> </span><span style="color: #286983">--port2</span><span style="color: #575279"> </span><span style="color: #D7827E">993</span><span style="color: #575279"> </span><span style="color: #286983">--ssl2</span><span style="color: #575279"> </span><span style="color: #286983">--user2</span><span style="color: #575279"> </span><span style="color: #286983">&lt;</span><span style="color: #EA9D34">user2@email.co</span><span style="color: #575279">m</span><span style="color: #286983">&gt;</span><span style="color: #575279"> </span><span style="color: #286983">--password2</span><span style="color: #575279"> </span><span style="color: #286983">&lt;</span><span style="color: #EA9D34">pass</span><span style="color: #286983">2&gt;</span><span style="color: #575279"> </span><span style="color: #286983">--useheader</span><span style="color: #575279"> </span><span style="color: #EA9D34">&#39;Message-Id&#39;</span><span style="color: #575279"> </span><span style="color: #286983">--skipsize</span><span style="color: #575279"> </span><span style="color: #286983">--noauthmd5</span><span style="color: #575279"> </span><span style="color: #286983">--reconnectretry1</span><span style="color: #575279"> </span><span style="color: #D7827E">1</span><span style="color: #575279"> </span><span style="color: #286983">--reconnectretry2</span><span style="color: #575279"> </span><span style="color: #D7827E">1</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>It’s as easy as that!</p><p>The post <a href="https://www.devhour.net/migrating-email-to-google-apps/">Migrating email to google apps</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/migrating-email-to-google-apps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Raspberry Pi and Motion (Weather App Pt 2) (Revised)</title>
		<link>https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=raspberry-pi-and-motion-weather-app-pt-2-revised</link>
					<comments>https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/#comments</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Wed, 23 Jul 2014 12:37:00 +0000</pubDate>
				<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[Motion]]></category>
		<category><![CDATA[raspberry pi camera]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=40</guid>

					<description><![CDATA[<p>Having written the original Raspberry Pi and Motion (Weather App Pt 2) and promptly put it on the back burner (read: got lazy and didn’t finish it) I’ve come back to finish it off. Firstly, I’m going to can the webcam in favour of the Raspberry Pi Camera Module. This is mainly due to the fact that a [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/">Raspberry Pi and Motion (Weather App Pt 2) (Revised)</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Having written the original <a href="https://www.devhour.net/raspberry-pi-and-motion-pt-2/">Raspberry Pi and Motion (Weather App Pt 2)</a> and promptly put it on the back burner (read: got lazy and didn’t finish it) I’ve come back to finish it off.</p>



<p>Firstly, I’m going to can the webcam in favour of the <a href="https://www.raspberrypi.org/help/camera-module-setup/" target="_blank" rel="noreferrer noopener">Raspberry Pi Camera Module</a>. This is mainly due to the fact that a lot of webcams either;</p>



<ol class="wp-block-list">
<li>Don’t work due to lack of driver support</li>



<li>Can’t perform at their optimal resolutions again because of shoddy drivers</li>



<li>Require an external USB hub in order to have enough power to work</li>
</ol>



<p>So after jumping on <a href="https://www.amazon.com/Raspberry-5MP-Camera-Board-Module/dp/B00E1GGE40" target="_blank" rel="noreferrer noopener">Amazon</a> and purchasing the module I got to work setting it up on the Raspberry Pi. There isn’t much to it as it just plugs into small slot behind the ethernet port (pull the tabs out, slide the module in, and shut the tabs). Once you’ve got to that point you need to enable the camera. So power on the Pi and once logged in type the following;</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo raspi-config" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">raspi-config</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Mid-way down the list of options you’ll see the option to Enable the camera. Do so, and then reboot the device. NB: If you can’t see that option then you need to run update/upgrade on the device first.<a href="https://web.archive.org/web/20170714234055/https://www.devhour.net/wp-content/uploads/2014/07/rpisetup.jpg"></a></p>



<figure class="wp-block-image size-full"><img decoding="async" width="499" height="322" src="https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt2-Camera.jpeg" alt="Enable Camera in Raspberry Pi Config" class="wp-image-54" srcset="https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt2-Camera.jpeg 499w, https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt2-Camera-300x194.jpeg 300w" sizes="(max-width: 499px) 100vw, 499px" /><figcaption class="wp-element-caption">Enable Camera in Raspberry Pi Config</figcaption></figure>



<p>In order to test out the camera simply run the following command after logging in;</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="raspistill -o image.jpg" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">raspistill</span><span style="color: #575279"> </span><span style="color: #286983">-o</span><span style="color: #575279"> </span><span style="color: #EA9D34">image.jpg</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>You should see an image of the camera pop up on screen for a few seconds and then you’ll find a lovely file called image.jpg.</p>



<p>Now natively motion doesn’t work nicely with the camera module but some nice folks have created a port called <a href="https://github.com/dozencrows/motion/tree/mmal-test" target="_blank" rel="noreferrer noopener">motion-mmal</a> that does.</p>



<p>To install it we just run the following;</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="wget https://www.dropbox.com/s/0gzxtkxhvwgfocs/motion-mmal.tar.gztar zxvf motion-mmal.tar.gzsudo ./motion -c motion-mmalcam.conf" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">wget</span><span style="color: #575279"> </span><span style="color: #EA9D34">https://www.dropbox.com/s/0gzxtkxhvwgfocs/motion-mmal.tar.gztar</span><span style="color: #575279"> </span><span style="color: #EA9D34">zxvf</span><span style="color: #575279"> </span><span style="color: #EA9D34">motion-mmal.tar.gzsudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">./motion</span><span style="color: #575279"> </span><span style="color: #286983">-c</span><span style="color: #575279"> </span><span style="color: #EA9D34">motion-mmalcam.conf</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>As you can see the new config file is called motion-mmalcam.conf and can (and should be) edited as required. I won’t go through that here as we already covered that in the previous post.</p>



<p>I promise this time that I’m going to continue on with this series and as I said last time I’m going to write a python script that will grab the weather temperature when motion takes a snapshot. From there I’ll be showing you 2 things. The first will be to set up a web page which shows an image + temperature. The second, sending the time/temperature to a 20×4 LCD screen <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>So stay tuned and as always you can follow me on twitter <a href="https://twitter.com/JAGracie">@JAGracie</a></p><p>The post <a href="https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/">Raspberry Pi and Motion (Weather App Pt 2) (Revised)</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/raspberry-pi-and-motion-weather-app-pt-2-revised/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Raspberry Pi Temperature Sensing Pt 1</title>
		<link>https://www.devhour.net/raspberry-pi-temperature-sensing-pt-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=raspberry-pi-temperature-sensing-pt-1</link>
					<comments>https://www.devhour.net/raspberry-pi-temperature-sensing-pt-1/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Wed, 30 Apr 2014 12:10:00 +0000</pubDate>
				<category><![CDATA[Raspberry Pi]]></category>
		<category><![CDATA[DS18B20]]></category>
		<category><![CDATA[Temperature Sensor]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=15</guid>

					<description><![CDATA[<p>This tutorial is going to teach you how to set up a Raspberry Pi Temperature sensor using GPIO pins and Occidentalis. So like many others before me I decided to pick up a Raspberry Pi to see what all the fuss is about. Now for those stuck under a rock or if you genuinely don’t [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/raspberry-pi-temperature-sensing-pt-1/">Raspberry Pi Temperature Sensing Pt 1</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>This tutorial is going to teach you how to set up a Raspberry Pi Temperature sensor using GPIO pins and Occidentalis.</p>



<p>So like many others before me I decided to pick up a Raspberry Pi to see what all the fuss is about. Now for those stuck under a rock or if you genuinely don’t know what a Raspberry Pi is, it is basically a small computer slightly bigger than a credit card with a cost of less than $50.</p>



<p>With it’s small size, fairly decent specs and the ability to play HD video the options with the Pi  are virtually endless. Add to that the GPIO pins that are attached to the board and it really does open up a whole new world. Already we have seen projects along the lines of <a href="https://www.reddit.com/r/raspberry_pi/comments/y0ehp/video_my_basic_raspberry_pi_home_automation_setup/">home automation</a>, <a href="https://www.raspbmc.com/">media centres</a>, <a href="https://www.youtube.com/watch?v=UjBV6pecjMM">in-car computers</a> and <a href="https://www.raspberrypi.org/archives/2412">arcade gaming</a>.</p>



<p>I haven’t had a lot of time to play around or do much development with it but I’ve decided on making a mini weather application. The plan is that around every hour the application will take the current temperature and an image (using a webcam with Motion) before uploading the results to a website (running via a web server on the Raspberry Pi).</p>



<p>Part 1 is going to be all about setting up the Raspberry Pi temperature sensor and reading the data from it.</p>



<h2 class="wp-block-heading">What you will need</h2>



<ul class="wp-block-list">
<li>Raspberry Pi</li>



<li><a href="https://web.archive.org/web/20160611142626/http://www.adafruit.com/products/914">Adafruit P</a><a href="https://www.adafruit.com/products/914">i</a><a href="https://web.archive.org/web/20160611142626/http://www.adafruit.com/products/914"> Cobbler</a> (optional)</li>



<li><a href="https://www.adafruit.com/products/64">Breadboard</a> (optional)</li>



<li><a href="https://www.ebay.co.uk/itm/DS18b20-Waterproof-digital-probe-thermometer-temperature-sensor-thermal-/130864369025?pt=UK_BOI_Electrical_Components_Supplies_ET&amp;hash=item1e781fcd81">DS18B20 temperature sensor</a></li>



<li>4.7k ohm resistor</li>
</ul>



<h2 class="wp-block-heading">Raspberry Pi Temperature Sensor</h2>



<p>The first step is really setting up the Raspberry Pi itself. This has been done to death in <a href="https://www.google.com/#hl=en&amp;sclient=psy-ab&amp;q=raspberry+pi+setup&amp;oq=raspberry+pi+setup">multiple tutorials</a> so I’m not going to go into the details. I’m currently using the Occidentalis v0.2 distro by Adafruit which by default comes with a lot of the packages you will need.</p>



<p>Once this is all setup and you’re happy then it’s time to move on to wiring up the DS18B20 Raspberry Pi temperature sensor. In the parts list I’ve put the Adafruit Pi Cobbler and breadboard as optional but I highly suggest you get them. It makes life a lot easier and can easily save you from doing damage to the Raspberry Pi itself.</p>



<p>It’s very important to get the wire input correct otherwise you run the risk of killing the sensor before you even get it working. The sensor that I’m using (link in the parts list) uses the following.&nbsp;Red = Power, Yellow = Data, Green = Ground. So applying this layout, on the Pi Cobbler/Raspberry Pi we place the Red wire on the 3.3v pin, the Yellow wire on the GPIO #4 pin and the Green wire on the GND pin. The 4.7k resistor goes between the PWR and Data wires (Red and Yellow).</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-medium"><img decoding="async" width="240" height="300" src="https://www.devhour.net/wp-content/uploads/2014/04/RaspberryPiTempSensorPt1-Wiring-240x300.png" alt="Raspberry Pi Temperature Sensor Wiring Diagram" class="wp-image-50" style="object-fit:cover" srcset="https://www.devhour.net/wp-content/uploads/2014/04/RaspberryPiTempSensorPt1-Wiring-240x300.png 240w, https://www.devhour.net/wp-content/uploads/2014/04/RaspberryPiTempSensorPt1-Wiring.png 753w" sizes="(max-width: 240px) 100vw, 240px" /><figcaption class="wp-element-caption">Raspberry Pi Temperature Sensor Wiring Diagram</figcaption></figure></div>


<p><strong>NB:</strong>&nbsp;There are two things to note. Firstly, if by the end of this tutorial nothing is working then try placing the Red PWR wire on the 5.5v pin instead of 3.3v. The 3.3v didn’t work for me (and &nbsp;hasn’t for many others) so give this a go. Secondly, if you turn the Pi on and the sensor gets extremely hot (enough to burn you when you touch it) then you have the pin layout wrong and need to double check the wire layout.</p>



<p>Now it’s time to fire up the Raspberry Pi and start reading some temperatures. Once it has booted up you need to firstly use the ‘modprobe’ command to load up the GPIO module in order to read the sensors data. So using ssh or desktop type:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo modprobe w1-gpiosudo modprobe w1-therm" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">modprobe</span><span style="color: #575279"> </span><span style="color: #EA9D34">w1-gpiosudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">modprobe</span><span style="color: #575279"> </span><span style="color: #EA9D34">w1-therm</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>Next browse to the system devices folder to find the Raspberry Pi temperature sensor device.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="cd /sys/bus/w1/devicesls" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #B4637A; font-style: italic">cd</span><span style="color: #575279"> </span><span style="color: #EA9D34">/sys/bus/w1/devicesls</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>When you issue the listing command under this directory you should see a folder beginning with 28-00000. This is your temperature sensor device. Go into this directory and read out the temperature by issuing the command:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="cd 28-00000xxxx # change this to your folder name
cat w1-slave" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #B4637A; font-style: italic">cd</span><span style="color: #575279"> </span><span style="color: #D7827E">28</span><span style="color: #EA9D34">-00000xxxx</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">#</span><span style="color: #9893A5; font-style: italic"> change this to your folder name</span></span>
<span class="line"><span style="color: #D7827E">cat</span><span style="color: #575279"> </span><span style="color: #EA9D34">w1-slave</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>You will see an output similar to this:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="675" height="424" src="https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt1-Output.png" alt="Raspberry Pi Temperature Sensor Output" class="wp-image-52" srcset="https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt1-Output.png 675w, https://www.devhour.net/wp-content/uploads/2024/03/RaspberryPiTempSensorPt1-Output-300x188.png 300w" sizes="auto, (max-width: 675px) 100vw, 675px" /><figcaption class="wp-element-caption">Raspberry Pi Temperature Sensor Output</figcaption></figure>



<p>The output will display either YES or NO at the end of the top line. If it is YES, then the temperature is valid and will be at the end of the bottom line. It will show as the temp*1000 so if it looks like a large number just divide it by 1000 to get the correct reading. Eg: 21500/1000 = 21.5C. If it displays NO then re-issue the ‘cat w1-slave’ until you get a correct reading.&nbsp;Putting your fingers over the sensor and issuing the cat command again should show the temperature going up.</p>



<p>Now one annoying part is that each time the Raspberry Pi is restarted you need to re-issue the modprobe commands. A neat little hint I found online will solve this problem. So type this command into a shell terminal and the modprobe commands will be done on startup!</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="sudo sh -c &quot;echo 'w1_gpio\nw1_therm\n' &gt;&gt; /etc/modules&quot;" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #D7827E">sudo</span><span style="color: #575279"> </span><span style="color: #EA9D34">sh</span><span style="color: #575279"> </span><span style="color: #286983">-c</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;echo &#39;w1_gpio\nw1_therm\n&#39; &gt;&gt; /etc/modules&quot;</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">Bash</span></div>



<p>This is all there is to it. In part 3 of this series I’m going to write a python script which will grab the temperature automatically for you as well as some other neat stuff. Next up though will be getting a webcam and motion working to go side by side with the Raspberry Pi temperature sensor.</p>



<p>Until then feel free to leave a comment or any questions (I’ll do my best to answer) and don’t forget to follow me on <a href="https://twitter.com/JAGracie" target="_blank" rel="noreferrer noopener">twitter</a>!</p><p>The post <a href="https://www.devhour.net/raspberry-pi-temperature-sensing-pt-1/">Raspberry Pi Temperature Sensing Pt 1</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/raspberry-pi-temperature-sensing-pt-1/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>If you accept email, Use it!</title>
		<link>https://www.devhour.net/if-you-accept-email-use-it/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=if-you-accept-email-use-it</link>
					<comments>https://www.devhour.net/if-you-accept-email-use-it/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Fri, 11 Apr 2014 12:36:00 +0000</pubDate>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[Contact]]></category>
		<category><![CDATA[Email]]></category>
		<category><![CDATA[Services]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=38</guid>

					<description><![CDATA[<p>One of the many things that bothers me in this day and age is the amount of businesses/services/individuals who accept email as a form of contact yet completely ignore or delay using it. 9 times out of 10 any website that you visit will have a contact section in some shape or form that will [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/if-you-accept-email-use-it/">If you accept email, Use it!</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>One of the many things that bothers me in this day and age is the amount of businesses/services/individuals who accept email as a form of contact yet completely ignore or delay using it.</p>



<p>9 times out of 10 any website that you visit will have a contact section in some shape or form that will either have an email address or contact form encouraging you to get in contact if you have any questions or queries.</p>



<p>However, what I have found when using this method is that I get completely ignored or forgotten about. If that isn’t the case, then waiting 3-7 days for a response isn’t uncommon either.</p>



<p>For an example, late last month I went looking for a WiFI extender for a friends motherboard. I thought what I found to be a decent product on a fairly well known NZ &nbsp;tech website. Not knowing the motherboard properly or knowing if the extender would fit, I hit the large ‘ENQUIRE’ button in the middle of the web page and asked if they were compatible. I sent that email on the 24th March at 9:46am. I got a reply on the 27th at 19:58. Three and a half days later. This from a store who is actually dedicated to computers.</p>



<p>Being in IT and using email as my main form of contact everyday this frustrates me to no end and will usually result in me taking my business elsewhere (which in this case I did).</p>



<p>What I don’t understand is, why is this the case? Technology is now almost everywhere and with the likes of smartphones and tablets email really is at your fingertips. I can understand that people are busy and not all businesses involve having someone sitting in front of a computer all day, but how hard is it to either send a quick reply saying ‘We’ll get back to you by the end of the day’ or even something as simple as flagging it to give yourself a note so that when you are next in front of a PC you know to email back.</p>



<p>Likewise, if you have dedicated call staff or in a shop-front (who usually have computers in front of them) why not have them set up with email in order to respond directly.</p>



<p>At the end of the day if I walked into a store front or rung directly I wouldn’t be ignored and I wouldn’t be waiting a week for a response. So, if you do use email as a form of contact, USE IT!</p>



<p>Do you agree? Not agree? Or just have a general opinion then feel free to comment, or hit me up on twitter <a href="https://www.twitter.com/JAGracie" target="_blank" rel="noreferrer noopener">@JAGracie</a></p><p>The post <a href="https://www.devhour.net/if-you-accept-email-use-it/">If you accept email, Use it!</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/if-you-accept-email-use-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Windows 8.1 and Corrupt nVidia Graphics Drivers</title>
		<link>https://www.devhour.net/windows-8-1-and-corrupt-nvidia-graphics-drivers/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=windows-8-1-and-corrupt-nvidia-graphics-drivers</link>
					<comments>https://www.devhour.net/windows-8-1-and-corrupt-nvidia-graphics-drivers/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Wed, 09 Apr 2014 12:34:00 +0000</pubDate>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Drivers]]></category>
		<category><![CDATA[GeForce]]></category>
		<category><![CDATA[NVIDIA]]></category>
		<category><![CDATA[Windows 8]]></category>
		<category><![CDATA[Windows 8.1]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=36</guid>

					<description><![CDATA[<p>Yesterday I suffered the dreaded ‘Monitor display blank screen issue after driver update‘ on my Windows 8.1 PC (in the middle of my work day to add insult to injury). I’m not sure when my PC decided to do Windows updates and install new drivers but all of a sudden my PC rebooted itself and after [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/windows-8-1-and-corrupt-nvidia-graphics-drivers/">Windows 8.1 and Corrupt nVidia Graphics Drivers</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Yesterday I suffered the dreaded ‘<a href="https://forums.geforce.com/default/topic/648176/geforce-drivers/monitor-display-blank-screen-issue-after-driver-update-updated-1-23-14-/1/" target="_blank" rel="noreferrer noopener">Monitor display blank screen issue after driver update</a>‘ on my Windows 8.1 PC (in the middle of my work day to add insult to injury). I’m not sure when my PC decided to do Windows updates and install new drivers but all of a sudden my PC rebooted itself and after displaying the Windows 8 boot logo both monitors turned off and went blank.</p>



<p>After a wee bit of googling and thinking I found that this is a fairly common issue and is caused by driver update conflicts. I haven’t found an exact reason but it sounds as though Windows basically installs two drivers at once which causes the conflict and thus it doesn’t work at all.</p>



<h2 class="wp-block-heading">The Fix</h2>



<p>In theory the fix is fairly simple but in practice it can be a little tricky. The gist of it is that you boot your machine in safe mode (I’ll explain that next as it isn’t quite as easy as it once was), uninstall the graphics drivers, download and install drivers, and then stop Windows updates from doing this all over again. Not the best solution but at least it’ll get you back up and running.</p>



<h3 class="wp-block-heading"><strong>Safe Mode</strong></h3>



<p>The first thing you’ll find with Windows 8/8.1 is that unless you have a very old, very slow computer pressing F8/Shift+F8 to get the advanced boot options won’t work. So the only way I could figure out how to do it was to boot the machine normally, once the logo disappears and the screen went blank I counted to 10 and then rebooted again.</p>



<p>Now when it booted it gave me a Windows startup error and then started ‘Diagnosing my PC’. Eventually you’ll get to a screen where you can ‘Choose an option’:</p>



<ol class="wp-block-list">
<li>Continue (this will just give you a blank screen again)</li>



<li>Troubleshoot (<strong>select this option</strong>)</li>



<li>Turn off your PC (not really going to help)</li>
</ol>



<p>In the troubleshooting screen you’ll again get some options:</p>



<ol class="wp-block-list">
<li>Refresh your PC</li>



<li>Reset your PC</li>



<li>Advance Options (<strong>select this one</strong>)</li>
</ol>



<p>Then in advanced options you’ll get even more choices:</p>



<ol class="wp-block-list">
<li>System Restore (you could try this, but it didn’t work for me)</li>



<li>System Image Recovery (would be handy if you have one)</li>



<li>Automatic Repair (again didn’t work for me)</li>



<li>Command Prompt (could be useful?)</li>



<li>Startup Settings (<strong>select this option</strong>)</li>
</ol>



<p>This will take you to a screen telling you to restart in order to change the Windows startup settings. Go ahead of do this.</p>



<p>Finally now when the machine reboots you’ll be given an advanced boot menu letting you choose Safe mode (<strong>option 4</strong>).</p>



<h3 class="wp-block-heading"><strong>Uninstall Drivers / Disable automatic updates</strong></h3>



<p>Once you’re in safe mode (finally!) you can go ahead and uninstall the drivers. Two ways you can do this. Either go into device manager (right click on the start menu &gt; device manager &gt; display adapters &gt; right click and uninstall) or go to Programs/Features (like you would to uninstall programs) and uninstall all nVidia components.</p>



<p>Next step is to stop Windows updates installing stuff on its own. Go to Control Panel (again right click on the start button) &gt; System and Security &gt; Windows Update &gt; Change Settings (on the left). Personally I have set mine to&nbsp;<strong>Check Only (Do Not Download &amp; Do Not install)&nbsp;</strong>&nbsp;but you could probably get away with Check and Download (Do Not Install). This will allow you to oversee which updates are applied and should hopefully stop you from getting in this pickle again!</p>



<h3 class="wp-block-heading"><strong>Download and Install Drivers</strong></h3>



<p>If you now reboot you’ll find that you now have some generic display driver which lets you back into your machine without needing safe mode. Your next step is to go to the <a href="https://www.nvidia.com/Download/index.aspx?lang=en-us" target="_blank" rel="noreferrer noopener">nVidia drivers download page</a> and download the driver for your machine. For me the latest driver (GeForce 335.23) caused the exact same issue so I had to experiment a bit and rollback even further.</p>



<p>Once it has installed (your screen may flicker/turn off for a bit during the process) you should now find you are back up and running successfully.</p>



<p><strong>NB:&nbsp;</strong>I have been told that there is an automatic update utility in the nVidia control panel which may need to be disabled. So if you find that this keeps happening (even after stopping Windows updates) then this may be your problem.</p>



<p>If you have any questions feel free to comment or hit me up on twitter <a href="https://twitter.com/jagracie" target="_blank" rel="noreferrer noopener">@JAGracie</a></p><p>The post <a href="https://www.devhour.net/windows-8-1-and-corrupt-nvidia-graphics-drivers/">Windows 8.1 and Corrupt nVidia Graphics Drivers</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/windows-8-1-and-corrupt-nvidia-graphics-drivers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Companies who release iOS apps before Android are frustrating</title>
		<link>https://www.devhour.net/companies-who-release-ios-apps-before-android-are-frustrating/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=companies-who-release-ios-apps-before-android-are-frustrating</link>
					<comments>https://www.devhour.net/companies-who-release-ios-apps-before-android-are-frustrating/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Mon, 16 Dec 2013 12:33:00 +0000</pubDate>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Mobile Apps]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=34</guid>

					<description><![CDATA[<p>This is one problem that has just started affecting me recently. I’m starting to find that a lot of companies these days when releasing Mobile Apps are coming out with their iOS version weeks sometimes months before their Android version. Case in point. The recent success of Grand Theft Auto V is known to all, [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/companies-who-release-ios-apps-before-android-are-frustrating/">Companies who release iOS apps before Android are frustrating</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>This is one problem that has just started affecting me recently. I’m starting to find that a lot of companies these days when releasing Mobile Apps are coming out with their iOS version weeks sometimes months before their Android version.</p>



<p>Case in point. The recent success of Grand Theft Auto V is known to all, and those people who played the game (myself included) also know about the iFruit mobile app. While most people found it to be pretty pointless (looking after Chop the dog. Really?) it did include a nice feature to get yourself a custom number plate for your cars. Like most things online, the number plates were first in first served. Better download that app quick smart then right? Wrong! While the iOS version for the iPhone and iPad was released quick smart the <a href="https://www.droid-life.com/2013/10/28/rockstar-finally-releases-gta-v-ifruit-app-sadly-its-pretty-late-to-the-party/" target="_blank" rel="noreferrer noopener">Android app didn’t see the light of day until October 28th</a>. A staggering 1 month and 11 days after the game was released. So much for that number plate…</p>



<p>Case in point number two. Recently in New Zealand the major satellite TV provider <a href="https://skytv.co.nz/" target="_blank" rel="noreferrer noopener">Sky</a> announced that it’s customers can now watch Live and OnDemand TV on their phones and tablets. Heck yeah, I can finally watch the cricket on my commute every afternoon. Can you see where this is going? It’s currently only available on iOS and they have said for Android users to keep their eyes out for an Android version on ‘selected devices’ sometime in the New Year (so… only a month or so late).</p>



<p>As a person who uses Android (Tablet + Phone) this frustrates me to no end! Not only me but a lot of people. A simple <a href="https://www.google.com/search?q=ifruit+android+complaints" target="_blank" rel="noreferrer noopener">google search</a> shows the frustration of the hundreds of GTA users and looking on the <a href="https://www.facebook.com/SKYnewzealand?fref=ts" target="_blank" rel="noreferrer noopener">SkyTV</a> facebook page shows 11 out of the 30 comments (on the announcement of Sky GO) complaining about the lack of an Android App!</p>



<p>It also doesn’t make viable sense to the company. According to recent stats (Q3 2013) <a href="https://www.forbes.com/sites/tonybradley/2013/11/15/android-dominates-market-share-but-apple-makes-all-the-money/" target="_blank" rel="noreferrer noopener">Android made up a staggering 81% of devices shipped</a>. Compared to the 12.9% of iOS. That’s 4 out of every 5 devices! I will admit here however that Apple is still making the most money. In fact in the same time frame – (Q3 2013) – Apple made more money than all of it’s competitors combined by taking in 56% of the profits. So yes, if the company was to be releasing a paid version of the app, then it might make more sense to go for an Apple release first. But they’re not paid apps. They’re free!!</p>



<p>So if this post was to fall into the lap of the decision maker of X company, then please would you consider either:</p>



<p>a) Creating and releasing the Android app first in order to make the most of the many many users.<br>b) How about working on both and releasing them at the same time!</p>



<p>Agree? Disagree? Feel free to comment!</p>



<p>Also follow me on <a href="https://twitter.com/JAGracie" target="_blank" rel="noreferrer noopener">Twitter</a></p>



<h2 class="wp-block-heading">Update:</h2>



<p>There has been some good discussions on this topic (mainly over at <a href="https://www.reddit.com/r/Android" target="_blank" rel="noreferrer noopener">/r/Android</a>) and I think the two main points that have come up are:</p>



<ol class="wp-block-list">
<li>Because there are so many Android devices running so many different versions of the OS + custom ROMs means that development time and testing is far more time consuming and resource intensive.</li>



<li>Even with 81% of devices shipped Android doesn’t touch iOS in terms of revenue generated.</li>
</ol>



<p>These points are both valid and explain why those companies that release a lot of revenue gathering apps (ie that is their business model) choose to go for iOS first.</p>



<p>However, I think the point I’m trying to get across is a lot of companies are only ever going to release a single app, with the intention of putting it on both operating systems, and with a price tag of $0. With that in mind does it still make sense to focus primarily on iOS over Android?</p>



<p>PS. after writing this yesterday I got an email from Fly Buys (New Zealand&#8217;s largest loyalty program) with the good news that they now have an app… for iPhone.</p>



<figure class="wp-block-pullquote"><blockquote><p>Right now, the Fly Buys app only works on iPhones. But for you Android users, keep an eye out for the release of our Android version. Click here to tell us your email address so we can let you know when</p></blockquote></figure><p>The post <a href="https://www.devhour.net/companies-who-release-ios-apps-before-android-are-frustrating/">Companies who release iOS apps before Android are frustrating</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/companies-who-release-ios-apps-before-android-are-frustrating/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Reading a websites contents using PHP and XPath</title>
		<link>https://www.devhour.net/reading-a-websites-contents-using-php-and-xpath/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reading-a-websites-contents-using-php-and-xpath</link>
					<comments>https://www.devhour.net/reading-a-websites-contents-using-php-and-xpath/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Mon, 16 Sep 2013 12:32:00 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Dev Hour]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[XPath]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=32</guid>

					<description><![CDATA[<p>Following on from my previous post Scraping data with PHP and cURL today I’m going to show you about reading a websites contents using PHP and XPath. One of the biggest problems I have faced when dealing with a scraped web page (read: block of HTML) is how to go about getting specific text elements out of it. Several years [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/reading-a-websites-contents-using-php-and-xpath/">Reading a websites contents using PHP and XPath</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>Following on from my previous post <a href="https://www.devhour.net/filling-out-forms-with-php-and-curl/">Scraping data with PHP and cURL</a> today I’m going to show you about reading a websites contents using <a href="https://php.net/" target="_blank" rel="noreferrer noopener">PHP</a> and <a href="https://www.w3schools.com/xpath/xpath_syntax.asp" target="_blank" rel="noreferrer noopener">XPath</a>.</p>



<p>One of the biggest problems I have faced when dealing with a scraped web page (read: block of HTML) is how to go about getting specific text elements out of it. Several years ago I would’ve gone with regex. This was a hassle to me and I’ve still yet to get my head around how it correctly works. These days though, I have discovered a useful little thing called XPath.</p>



<p>Basically, how it works is, you put the HTML in a DOMDocument and then you can use XPath to navigate through elements and attributes of the document getting the data of them in the process.</p>



<h2 class="wp-block-heading">Using PHP and XPath</h2>



<p>Now if we were to consider the following HTML:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&lt;html&gt;   
  &lt;head&gt;
    &lt;title&gt;Test&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;mainDiv&quot;&gt;
      &lt;div id=&quot;leftDiv&quot;&gt;
        &lt;p class=&quot;bodyText&quot;&gt;This is left&lt;/p&gt;
        &lt;img src=&quot;images/test.jpg&quot; /&gt;
      &lt;/div&gt;
      &lt;div id=&quot;rightDiv&quot;&gt;
        &lt;p class=&quot;bodyText&quot;&gt;This is right&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id=&quot;footer&quot;&gt;
      &lt;p class=&quot;smallText&quot;&gt;This is the footer&lt;/p&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #9893A5">&lt;</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">   </span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">Test</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;mainDiv&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;leftDiv&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;bodyText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is left</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">img</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">src</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;images/test.jpg&quot;</span><span style="color: #575279"> </span><span style="color: #9893A5">/&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;rightDiv&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;bodyText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is right</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;footer&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;smallText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is the footer</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">HTML</span></div>



<p>And now, lets say I wanted to get the text of the rightDiv. This is how we would go about it:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&lt;?php
  // $content is the content you scraped (via curl for example)
  $dom = new DOMDocument();
  @$dom-&gt;loadHTML($content)
  $xpath = new DOMXPath($dom);
  $rightDivText = $xpath-&gt;query(&quot;//html/body/div[@id='mainDiv']/div[@id='rightDiv']/p/text()&quot;); 
  
  // Returns: This is right
  echo $rightDivText-&gt;item(0)-&gt;nodeValue;
?&gt;" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #286983">&lt;?php</span></span>
<span class="line"><span style="color: #797593">  </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> $content is the content you scraped (via curl for example)</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMDocument</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #286983">@</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">loadHTML</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">content</span><span style="color: #797593">)</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMXPath</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">rightDivText</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;//html/body/div[@id=&#39;mainDiv&#39;]/div[@id=&#39;rightDiv&#39;]/p/text()&quot;</span><span style="color: #797593">);</span><span style="color: #575279"> </span></span>
<span class="line"><span style="color: #575279">  </span></span>
<span class="line"><span style="color: #797593">  </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> Returns: This is right</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #B4637A; font-style: italic">echo</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">rightDivText</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">;</span></span>
<span class="line"><span style="color: #286983">?&gt;</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>Simply, it will load the $content (HTML) into a DOMDocument and then using XPath it looks for the for the div with the id of ‘mainDiv’ and then inside of ‘mainDiv’ it looks for the div with the id of ‘rightDiv’. Finally it then gets the text of the ‘p’ element.</p>



<p>Now that is one of the more straight forward scenarios and is made easier by the fact that most of the different elements have custom IDs like ‘mainDiv’ or ‘rightDiv’. If we were to look at the same HTML block again but this time without IDs, this is how it would look.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Test&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div&gt;
      &lt;div&gt;
        &lt;p class=&quot;bodyText&quot;&gt;This is left&lt;/p&gt;
        &lt;img src=&quot;images/test.jpg&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;p class=&quot;bodyText&quot;&gt;This is right&lt;/p&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;div id=&quot;footer&quot;&gt;
      &lt;p class=&quot;smallText&quot;&gt;This is the footer&lt;/p&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #9893A5">&lt;</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">Test</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;bodyText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is left</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">img</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">src</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;images/test.jpg&quot;</span><span style="color: #575279"> </span><span style="color: #9893A5">/&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;bodyText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is right</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;footer&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;smallText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is the footer</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">HTML</span></div>



<p>This time lets get the src of the image in the former leftDiv.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&lt;?php
// $content is the content you scraped (via curl for example)
$dom = new DOMDocument();  @$dom-&gt;loadHTML($content)
$xpath = new DOMXPath($dom);
$imgSrc = $xpath-&gt;query(&quot;//html/body/div[1]/div[1]/img/@src&quot;);

// Returns: images/test.jpg
echo $imgSrc-&gt;item(0)-&gt;nodeValue;
?&gt;
" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #286983">&lt;?php</span></span>
<span class="line"><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> $content is the content you scraped (via curl for example)</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMDocument</span><span style="color: #797593">();</span><span style="color: #286983">  @</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">loadHTML</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">content</span><span style="color: #797593">)</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMXPath</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">imgSrc</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;//html/body/div[1]/div[1]/img/@src&quot;</span><span style="color: #797593">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> Returns: images/test.jpg</span></span>
<span class="line"><span style="color: #B4637A; font-style: italic">echo</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">imgSrc</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">;</span></span>
<span class="line"><span style="color: #286983">?&gt;</span></span>
<span class="line"></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>As you can see, the difference this time is that instead of using the divs ID, we used the elements number. Inside the body, it looks for the first div, and then inside of that it again looks for the first child div before returning the src of the img element.</p>



<p>Again though, this is probably another pretty simple solution but definitely gives you an idea of how XPath works and some of the ways it can be used. The next scenario is basically the one I came face to face with, and that scenario is one in which we have multiple divs with the same name. Consider this html:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Test&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;container&quot;&gt;
      &lt;div id=&quot;person&quot;&gt;
        &lt;p&gt;Bob&lt;/p&gt;
        &lt;p&gt;25&lt;/p&gt;
        &lt;p&gt;180lbs&lt;/p&gt;
        &lt;img src=&quot;images/p1.jpg&quot; /&gt;
      &lt;/div&gt;
      &lt;div id=&quot;person&quot;&gt;
        &lt;p&gt;Stacy&lt;/p&gt;
        &lt;p&gt;26&lt;/p&gt;
        &lt;p&gt;187lbs&lt;/p&gt;
        &lt;img src=&quot;images/p2.jpg&quot; /&gt;
      &lt;/div&gt;
      &lt;div id=&quot;person&quot;&gt;
        &lt;p&gt;John&lt;/p&gt;
        &lt;p&gt;21&lt;/p&gt;
        &lt;p&gt;255lbs&lt;/p&gt;
        &lt;img src=&quot;images/p3.jpg&quot; /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id=&quot;footer&quot;&gt;&lt;p class=&quot;smallText&quot;&gt;This is the footer&lt;/p&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #9893A5">&lt;</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">Test</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">title</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">head</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;container&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;person&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">Bob</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">25</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">180lbs</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">img</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">src</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;images/p1.jpg&quot;</span><span style="color: #575279"> </span><span style="color: #9893A5">/&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;person&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">Stacy</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">26</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">187lbs</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">img</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">src</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;images/p2.jpg&quot;</span><span style="color: #575279"> </span><span style="color: #9893A5">/&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;person&quot;</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">John</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">21</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">255lbs</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">img</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">src</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;images/p3.jpg&quot;</span><span style="color: #575279"> </span><span style="color: #9893A5">/&gt;</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #9893A5">&lt;</span><span style="color: #56949F">div</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">id</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;footer&quot;</span><span style="color: #9893A5">&gt;&lt;</span><span style="color: #56949F">p</span><span style="color: #575279"> </span><span style="color: #907AA9; font-style: italic">class</span><span style="color: #797593">=</span><span style="color: #EA9D34">&quot;smallText&quot;</span><span style="color: #9893A5">&gt;</span><span style="color: #575279">This is the footer</span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">p</span><span style="color: #9893A5">&gt;&lt;/</span><span style="color: #56949F">div</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">body</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"><span style="color: #9893A5">&lt;/</span><span style="color: #56949F">html</span><span style="color: #9893A5">&gt;</span></span>
<span class="line"></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">HTML</span></div>



<p>So here we have a webpage that displays a bunch of people with information such as their name, age, weight, and picture. Now as someone who is interested in getting the information of all of these people, I need to scrape the website and then using XPath I can loop through each person and get it.</p>



<p>To do this, we get everything inside the ‘container’ div and then loop through each individual ‘person’ div. Then using XPath on the ‘person’ div we can use the above examples to get the information we want. Finally we store all the results in an array.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" &lt;?php
$dom = new DOMDocument();
@$dom-&gt;loadHTML($content);
$tempDom   = new DOMDocument();
$xpath     = new DOMXPath($dom);
$container = $xpath-&gt;query(&quot;//div[@id='container']&quot;);
foreach ($container as $item) {
    $tempDom-&gt;appendChild($tempDom-&gt;importNode($item, true));
}
$tempDom-&gt;saveHTML();
$peopleXpath = new DOMXPath($tempDom);
$peopleDiv   = $peopleXpath-&gt;query(&quot;div[@id='person']&quot;);
$results     = array();
foreach ($peopleDiv as $people) {
    $newDom = new DOMDocument;
    $newDom-&gt;appendChild($newDom-&gt;importNode($people, true));
    $personXpath = new DOMXPath($newDom);
    $name        = trim($personXpath-&gt;query(&quot;p[1]/text()&quot;)-&gt;item(0)-&gt;nodeValue);
    $age         = trim($resultXpath-&gt;query(&quot;p[2]/text()&quot;)-&gt;item(0)-&gt;nodeValue);
    $weight      = trim($resultXpath-&gt;query(&quot;p[3]/text()&quot;)-&gt;item(0)-&gt;nodeValue);
    $image       = trim($resultXpath-&gt;query(&quot;img[1]/@src&quot;)-&gt;item(0)-&gt;nodeValue);
    $results[]   = array(
        'name' =&gt; $name,
        'age' =&gt; $age,
        'weight' =&gt; $weight,
        'image' =&gt; $image
    );
}
?&gt; " style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #575279"> </span><span style="color: #286983">&lt;?php</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMDocument</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #286983">@</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">loadHTML</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">content</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">tempDom</span><span style="color: #575279">   </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMDocument</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #575279">     </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMXPath</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">dom</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">container</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">xpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;//div[@id=&#39;container&#39;]&quot;</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #286983">foreach</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">container</span><span style="color: #575279"> </span><span style="color: #286983">as</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">item</span><span style="color: #797593">)</span><span style="color: #575279"> </span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">tempDom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">appendChild</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">tempDom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">importNode</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">item</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #D7827E">true</span><span style="color: #797593">));</span></span>
<span class="line"><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">tempDom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">saveHTML</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">peopleXpath</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMXPath</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">tempDom</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">peopleDiv</span><span style="color: #575279">   </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">peopleXpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;div[@id=&#39;person&#39;]&quot;</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">results</span><span style="color: #575279">     </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">array</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #286983">foreach</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">peopleDiv</span><span style="color: #575279"> </span><span style="color: #286983">as</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">people</span><span style="color: #797593">)</span><span style="color: #575279"> </span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">newDom</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMDocument</span><span style="color: #797593">;</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">newDom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">appendChild</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">newDom</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">importNode</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">people</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #D7827E">true</span><span style="color: #797593">));</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">personXpath</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">DOMXPath</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">newDom</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">name</span><span style="color: #575279">        </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">trim</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">personXpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;p[1]/text()&quot;</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">age</span><span style="color: #575279">         </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">trim</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">resultXpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;p[2]/text()&quot;</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">weight</span><span style="color: #575279">      </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">trim</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">resultXpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;p[3]/text()&quot;</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">image</span><span style="color: #575279">       </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">trim</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">resultXpath</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">query</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;img[1]/@src&quot;</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">item</span><span style="color: #797593">(</span><span style="color: #D7827E">0</span><span style="color: #797593">)</span><span style="color: #286983">-&gt;</span><span style="color: #575279; font-style: italic">nodeValue</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">results</span><span style="color: #797593">[]</span><span style="color: #575279">   </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">array</span><span style="color: #797593">(</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #EA9D34">&#39;name&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">name</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #EA9D34">&#39;age&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">age</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #EA9D34">&#39;weight&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">weight</span><span style="color: #797593">,</span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #EA9D34">&#39;image&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">image</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #286983">?&gt;</span><span style="color: #575279"> </span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>There you have it. If you run a print_r on the results array you should have yourself a bunch values containing the information of Bob, Stacy, and John.</p>



<p>Now a totally awesome cheat for this solution is to use the Google Chrome <a href="https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=en" target="_blank" rel="noreferrer noopener">XPath Helper</a> extension. All you need to do is hold down the shift key as you hover over webpage elements. This in turn will return the XPath query which is a HUGE help!</p>



<p>As always feel free to comment and or improve on the above. Also, don’t forget to follow me <a href="https://twitter.com/JAGracie" target="_blank" rel="noreferrer noopener">@JAGracie</a>.</p><p>The post <a href="https://www.devhour.net/reading-a-websites-contents-using-php-and-xpath/">Reading a websites contents using PHP and XPath</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/reading-a-websites-contents-using-php-and-xpath/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Automatically post to a Page using PHP Facebook SDK</title>
		<link>https://www.devhour.net/automatically-post-to-a-page-using-php-facebook-sdk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automatically-post-to-a-page-using-php-facebook-sdk</link>
					<comments>https://www.devhour.net/automatically-post-to-a-page-using-php-facebook-sdk/#respond</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Tue, 10 Sep 2013 12:30:00 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=30</guid>

					<description><![CDATA[<p>During my weekends/time off I tend to watch quite a lot of sport, with the English Premier League (EPL) being one of my favourite things to support. As such, I created and run an EPL facebook page dedicated  to covering fixtures, results, and other news. Now this all good fun and I enjoy doing it, but week after [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/automatically-post-to-a-page-using-php-facebook-sdk/">Automatically post to a Page using PHP Facebook SDK</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>During my weekends/time off I tend to watch quite a lot of sport, with the English Premier League (EPL) being one of my favourite things to support. As such, I created and run an <a href="https://www.facebook.com/EPLNewsInfo" target="_blank" rel="noreferrer noopener">EPL facebook page</a> dedicated  to covering fixtures, results, and other news.</p>



<p>Now this all good fun and I enjoy doing it, but week after week, month after month of posting all the fixtures the day before and posting the results the day after gets a little tedious, especially if I’m short on time. So being the geek I am, I decided that I could easily automate these, and so I did, using the PHP facebook SDK.</p>



<p>It was actually pretty straight forward, the hardest bit was trying to find websites which would give me the information in a straight forward and easy way. In the end, I decided to go with the offical <a href="https://www.premierleague.com/en-gb/matchday/results.html?paramComp_8=true&amp;view=.dateSeason" target="_blank" rel="noreferrer noopener">Premier League website</a>, as not only is it the correct information it is also laid out in a way which makes it easy to retrieve.</p>



<p>So putting my previous posts into good use I used curl to scrape the website and Xpath to dissect it into the important parts (namely the home and away teams, the location, and the final score).</p>



<p>Once I have this important information I can then go away and use the PHP facebook SDK to post a status to my EPL News feed which I will show you how to do now.</p>



<p>Firstly, you will need to create a <a href="https://developers.facebook.com/apps" target="_blank" rel="noreferrer noopener">facebook application</a> which will be integrated in a website. After you’ve created the app you will want to fill out the website URL and hit save. This URL is going to be where the PHP app you are going to create will be stored (ie http://devhour.net/fbapp).</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="707" height="434" src="https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-EPLNewsFeed.png" alt="EPLNewsFeed Facebook Application" class="wp-image-58" srcset="https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-EPLNewsFeed.png 707w, https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-EPLNewsFeed-300x184.png 300w" sizes="auto, (max-width: 707px) 100vw, 707px" /><figcaption class="wp-element-caption">EPLNewsFeed Facebook Application</figcaption></figure>



<p>Next up you’ll need to run the following URL to authorize your app to manage your pages and other such permissions. Remember to replace [APP_ID] and [SITE_URL] with both your facebook APP ID and the website you entered above. You will be prompted to grant access to your app (click Allow).</p>



<pre class="wp-block-code"><code>https:&#47;&#47;graph.facebook.com/oauth/authorize?client_id=&#91;APP_ID]&amp;scope=offline_access,publish_stream,manage_pages&amp;redirect_uri=&#91;SITE_URL]</code></pre>



<p>It will then redirect you back to the URL of the site you specified in the app. If you look closely though you’ll notice that on the end of the url is ?code=aBuNcHoFgIbBeRiSh. Copy everything after the ?code= and keep it in a safe place for now. You’re going to need it in a second.</p>



<p>The next step is to get the long lasting access token which will allow you to keep posting without having to authenticate yourself every time (this is vital to making this whole script automatic). So again go to the following URL and replace [APP_ID], [APP_SECRET], [SITE_URL], and [CODE] (the one you just previously copied).</p>



<pre class="wp-block-code"><code>https:&#47;&#47;graph.facebook.com/oauth/access_token?client_id=&#91;APP_ID]&amp;redirect_uri=&#91;SITE_URL]&amp;client_secret=&#91;APP_SECRET]&amp;code=&#91;CODE]</code></pre>



<p>If all went well you’ll be redirected back to your website and on the screen you should see:</p>



<p>access_token=…….</p>



<p>Store this somewhere because it’s very important <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Now the fun can start. Firstly, you can test the access token by going to the <a href="https://developers.facebook.com/tools/explorer/" target="_blank" rel="noreferrer noopener">Facebook Graph API explorer</a>, pasting the token into the Access token field and trying the following:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="925" height="213" src="https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-GraphAPI.png" alt="Facebook Graph API Explorer" class="wp-image-60" srcset="https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-GraphAPI.png 925w, https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-GraphAPI-300x69.png 300w, https://www.devhour.net/wp-content/uploads/2024/03/AutomaticallyPosttoPHPFacebook-GraphAPI-768x177.png 768w" sizes="auto, (max-width: 925px) 100vw, 925px" /><figcaption class="wp-element-caption">Facebook Graph API Explorer</figcaption></figure>



<p>This will post a test message to your page which will indicate that the access token you have is good to go. Now on to the code…</p>



<p>Before we write any code on our end, you’re going to have to download the <a href="https://github.com/facebook/facebook-php-sdk" target="_blank" rel="noreferrer noopener">PHP facebook SDK</a> from the github repo. Download and store these files somewhere handy and feel free to jump into the examples are have a bit of a play.</p>



<p>On our end however, the first thing we are going to is create a php file and reference the facebook sdk and enter some variable details (fill out as necessary).</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" &lt;?php
require &quot;src/facebook.php&quot;;
$PAGE_ID         = &quot;&quot;; // The page you want to post to (you must be a manager) 
$FACEBOOK_APP_ID = &quot;&quot;; // Your facebook app ID
$FACEBOOK_SECRET = &quot;&quot;; // Your facebook secret
$ACCESS_TOKEN    = &quot;&quot;; // The access token you receieved above
$PAGE_TOKEN      = &quot;&quot;; // Leave this blank. It will be set later " style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #575279"> </span><span style="color: #286983">&lt;?php</span></span>
<span class="line"><span style="color: #286983">require</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;src/facebook.php&quot;</span><span style="color: #797593">;</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_ID</span><span style="color: #575279">         </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;&quot;</span><span style="color: #797593">;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> The page you want to post to (you must be a manager) </span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">FACEBOOK_APP_ID</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;&quot;</span><span style="color: #797593">;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> Your facebook app ID</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">FACEBOOK_SECRET</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;&quot;</span><span style="color: #797593">;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> Your facebook secret</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">ACCESS_TOKEN</span><span style="color: #575279">    </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;&quot;</span><span style="color: #797593">;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> The access token you receieved above</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_TOKEN</span><span style="color: #575279">      </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;&quot;</span><span style="color: #797593">;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">//</span><span style="color: #9893A5; font-style: italic"> Leave this blank. It will be set later </span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>Now we go ahead and create a new facebook instance using our newly created app details.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="$facebook = new Facebook(array('appId' =&gt; $FACEBOOK_APP_ID, 'secret' =&gt; $FACEBOOK_SECRET, 'cookie' =&gt; true,));  
$post = array('access_token' =&gt; $ACCESS_TOKEN);" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">facebook</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #286983">new</span><span style="color: #575279"> </span><span style="color: #56949F">Facebook</span><span style="color: #797593">(</span><span style="color: #B4637A; font-style: italic">array</span><span style="color: #797593">(</span><span style="color: #EA9D34">&#39;appId&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">FACEBOOK_APP_ID</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #EA9D34">&#39;secret&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">FACEBOOK_SECRET</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #EA9D34">&#39;cookie&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #D7827E">true</span><span style="color: #797593">,));</span><span style="color: #575279">  </span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">post</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">array</span><span style="color: #797593">(</span><span style="color: #EA9D34">&#39;access_token&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">ACCESS_TOKEN</span><span style="color: #797593">);</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>The next little piece of code will loop through the pages that you manage and find the PAGE_TOKEN which matches the PAGE_ID you specified. This will allow you to post to that pages wall as the page rather than you.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="try {  
  $res = $facebook-&gt;api('/me/accounts','GET',$post);   
  if (isset($res['data'])) {
    foreach ($res['data'] as $account) {
      if ($PAGE_ID == $account['id']) { 
        $PAGE_TOKEN = $account['access_token']; 
        break; 
      }
    }
  }
} 
catch (Exception $e){  
 echo $e-&gt;getMessage();
}" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #286983">try</span><span style="color: #575279"> </span><span style="color: #797593">{</span><span style="color: #286983">  </span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">res</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">facebook</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">api</span><span style="color: #797593">(</span><span style="color: #EA9D34">&#39;/me/accounts&#39;</span><span style="color: #797593">,</span><span style="color: #EA9D34">&#39;GET&#39;</span><span style="color: #797593">,</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">post</span><span style="color: #797593">);</span><span style="color: #286983">  </span><span style="color: #575279"> </span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #286983">if</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #B4637A; font-style: italic">isset</span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">res</span><span style="color: #797593">[</span><span style="color: #EA9D34">&#39;data&#39;</span><span style="color: #797593">]))</span><span style="color: #575279"> </span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #286983">foreach</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">res</span><span style="color: #797593">[</span><span style="color: #EA9D34">&#39;data&#39;</span><span style="color: #797593">]</span><span style="color: #575279"> </span><span style="color: #286983">as</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">account</span><span style="color: #797593">)</span><span style="color: #575279"> </span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #286983">if</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_ID</span><span style="color: #575279"> </span><span style="color: #286983">==</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">account</span><span style="color: #797593">[</span><span style="color: #EA9D34">&#39;id&#39;</span><span style="color: #797593">])</span><span style="color: #575279"> </span><span style="color: #797593">{</span><span style="color: #286983"> </span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_TOKEN</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">account</span><span style="color: #797593">[</span><span style="color: #EA9D34">&#39;access_token&#39;</span><span style="color: #797593">];</span><span style="color: #286983"> </span></span>
<span class="line"><span style="color: #575279">        </span><span style="color: #286983">break</span><span style="color: #797593">;</span><span style="color: #286983"> </span></span>
<span class="line"><span style="color: #575279">      </span><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #575279">    </span><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #797593">}</span><span style="color: #575279"> </span></span>
<span class="line"><span style="color: #286983">catch</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #56949F">Exception</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">e</span><span style="color: #797593">){</span><span style="color: #286983">  </span></span>
<span class="line"><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">echo</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">e</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">getMessage</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #797593">}</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>Taking all the information we have so far received we can now go ahead and post to the pages wall.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-bottom-disabled cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#575279;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#faf4ed"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="$message = &quot;This is a test message&quot;;
$post = array('access_token' =&gt; $PAGE_TOKEN, 'message' =&gt; $message);
try{
  $res = $facebook-&gt;api(&quot;/$PAGE_ID/feed&quot;,&quot;POST&quot;,$post);
}
catch (Exception $e){
  echo $e-&gt;getMessage();
}
?&gt;" style="color:#575279;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki rose-pine-dawn" style="background-color: #faf4ed" tabindex="0"><code><span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">message</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #EA9D34">&quot;This is a test message&quot;</span><span style="color: #797593">;</span></span>
<span class="line"><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">post</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #B4637A; font-style: italic">array</span><span style="color: #797593">(</span><span style="color: #EA9D34">&#39;access_token&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_TOKEN</span><span style="color: #797593">,</span><span style="color: #575279"> </span><span style="color: #EA9D34">&#39;message&#39;</span><span style="color: #575279"> </span><span style="color: #286983">=&gt;</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">message</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #286983">try</span><span style="color: #797593">{</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">res</span><span style="color: #575279"> </span><span style="color: #286983">=</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">facebook</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">api</span><span style="color: #797593">(</span><span style="color: #EA9D34">&quot;/</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">PAGE_ID</span><span style="color: #EA9D34">/feed&quot;</span><span style="color: #797593">,</span><span style="color: #EA9D34">&quot;POST&quot;</span><span style="color: #797593">,</span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">post</span><span style="color: #797593">);</span></span>
<span class="line"><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #286983">catch</span><span style="color: #575279"> </span><span style="color: #797593">(</span><span style="color: #56949F">Exception</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">e</span><span style="color: #797593">){</span></span>
<span class="line"><span style="color: #575279">  </span><span style="color: #B4637A; font-style: italic">echo</span><span style="color: #575279"> </span><span style="color: #797593; font-style: italic">$</span><span style="color: #575279; font-style: italic">e</span><span style="color: #286983">-&gt;</span><span style="color: #D7827E">getMessage</span><span style="color: #797593">();</span></span>
<span class="line"><span style="color: #797593">}</span></span>
<span class="line"><span style="color: #286983">?&gt;</span></span></code></pre><span style="display:flex;align-items:flex-end;padding:10px;width:100%;justify-content:flex-end;background-color:#faf4ed;color:#625c88;font-size:12px;line-height:1;position:relative">PHP</span></div>



<p>And that’s it. It’s actually really straight forward and easy to do. Feel free to play around with it and I’d be interested in seeing what you can come up with.</p>



<p>As always, follow me on twitter: <a href="https://twitter.com/JAGracie" target="_blank" rel="noreferrer noopener">@JAGracie</a></p><p>The post <a href="https://www.devhour.net/automatically-post-to-a-page-using-php-facebook-sdk/">Automatically post to a Page using PHP Facebook SDK</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/automatically-post-to-a-page-using-php-facebook-sdk/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Build a quadcopter (Part 3) – Preparing the quadcopter</title>
		<link>https://www.devhour.net/build-a-quadcopter-part-3-preparing-the-quadcopter/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=build-a-quadcopter-part-3-preparing-the-quadcopter</link>
					<comments>https://www.devhour.net/build-a-quadcopter-part-3-preparing-the-quadcopter/#comments</comments>
		
		<dc:creator><![CDATA[Jamie]]></dc:creator>
		<pubDate>Sat, 17 Aug 2013 12:29:00 +0000</pubDate>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Multirotor]]></category>
		<category><![CDATA[Quadcopter]]></category>
		<guid isPermaLink="false">https://www.devhour.net/?p=28</guid>

					<description><![CDATA[<p>Preparing the Quadcopter Welcome back to this third installment on how to build a quadcopter. If you haven’t already check out part 1 (the parts) and part 2 (the build) to get up to speed and then read on to start preparing the quadcopter for it’s first flight. KK2.0 Motor Layout The first thing we want to do is [&#8230;]</p>
<p>The post <a href="https://www.devhour.net/build-a-quadcopter-part-3-preparing-the-quadcopter/">Build a quadcopter (Part 3) – Preparing the quadcopter</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">Preparing the Quadcopter</h2>



<p>Welcome back to this third installment on how to build a quadcopter. If you haven’t already check out <a href="https://www.devhour.net/build-a-quadcopter-part-1-the-parts/">part 1 (the parts)</a> and <a href="https://www.devhour.net/build-a-quadcopter-part-1-the-build/">part 2 (the build)</a> to get up to speed and then read on to start preparing the quadcopter for it’s first flight.</p>



<h2 class="wp-block-heading">KK2.0 Motor Layout</h2>



<p>The first thing we want to do is tell the flight controller what our quadcopter layout looks like so that when it comes to receiving commands it knows exactly what to do and where to do it.</p>



<p>This is easy enough to do. Firstly Plug the battery harness into the battery and wait for the KK2.0 to fire up and follow these steps:</p>



<ol class="wp-block-list">
<li>Press button 4 (below the word ‘Menu’)</li>



<li>Press button 3 (down) until you reach ‘Load motor layout’</li>



<li>Press button 4 (enter)</li>



<li>Press button 3 (down) until you reach Quadcopter – X</li>



<li>Hit button 4 (change)</li>
</ol>



<p>Just like that! You can then either go back (press button 1 over and over until you get back to the start) or press button 3 to scroll through each individual motor on the X layout. If you scroll through the motors you should take note that it shows you an arrow telling you which way the motor should spin (CW or CCW). This is important as this is what we’re going to cover next.</p>



<figure class="wp-block-image size-medium"><img loading="lazy" decoding="async" width="300" height="292" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-Preparing-300x292.jpg" alt="Preparing the quadcopter – Motor layout" class="wp-image-75" srcset="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-Preparing-300x292.jpg 300w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-Preparing-768x748.jpg 768w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-Preparing.jpg 900w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">Preparing the quadcopter – Motor layout</figcaption></figure>



<h2 class="wp-block-heading">Motor Rotation</h2>



<p>Now basically unless your motors spin the correct way (in line with the motor layout from above) you’re going to have a hard time flying. By hard time I mean the quadcopter will most likely flip before it gets off the ground and cause a bit of damage to itself. In other words this is also quite an important step.</p>



<p>If we follow what we saw in the previous step then&nbsp;motors 1&amp;3 spin are going to spin CW and 2&amp;4 will spin CCW. Check out the image below it you’re not sure:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="300" height="214" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-MotorRotation.jpg" alt="Preparing the quadcopter – Motor rotation" class="wp-image-77"/><figcaption class="wp-element-caption">Preparing the quadcopter – Motor rotation</figcaption></figure>



<p>The only way to find out if your motors are spinning in the correct direction is to fire it up and apply a little bit of throttle. So go ahead and turn on your radio, plug the battery into the harness and check each motor in turn.</p>



<p>By referencing the image above double check to make sure each motor is spinning in the right direction. If you find they aren’t, then all you need to do is switch 2 of the wires connecting from the motors to the ESCs (ie take the yellow and black and switch them). If you don’t know which wires I’m talking about, then these:</p>



<figure class="wp-block-image size-medium"><img loading="lazy" decoding="async" width="300" height="220" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-MotorWiring-300x220.jpg" alt="Preparing the quadcopter – Motor wiring" class="wp-image-78" srcset="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-MotorWiring-300x220.jpg 300w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-MotorWiring.jpg 565w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">Preparing the quadcopter – Motor wiring</figcaption></figure>



<p>Again double check they’re spinning in the correct direction (rinse and repeat the above step for the other motors if needed) and then move onward!</p>



<h2 class="wp-block-heading">Receiver Test</h2>



<p>There are two reasons we need to do this. One, we need to zero out these numbers in order to make sure the quadcopter doesn’t decide to fly off on it’s own and two, we want to check to see if the radio inputs are going in the right direction (ie pushing forward actually makes the quad go forward).&nbsp;If you had trouble with the receiver in the previous post (ie trying to arm it by going to the bottom right didn’t work) then this is where we will hopefully fix those issues.</p>



<p>Firstly, switch on your radio and plug the battery into the harness to power it all up. On the KK2.0 do the following:</p>



<ol class="wp-block-list">
<li>Press the menu button (button 4)</li>



<li>Press down and enter into ‘Receiver Test’</li>



<li>You should come across the following:</li>
</ol>



<figure class="wp-block-image size-medium"><img loading="lazy" decoding="async" width="300" height="237" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-ReceiverTest-300x237.jpg" alt="Preparing the quadcopter – Receiver test" class="wp-image-79" srcset="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-ReceiverTest-300x237.jpg 300w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-ReceiverTest-1024x808.jpg 1024w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-ReceiverTest-768x606.jpg 768w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-ReceiverTest.jpg 1200w" sizes="auto, (max-width: 300px) 100vw, 300px" /><figcaption class="wp-element-caption">Preparing the quadcopter – Receiver test</figcaption></figure>



<p>This shows all the different channels (throttle, aileron, elevator, rudder, and aux) of your receiver. If you go ahead and move the sticks on your radio you will see the numbers next to the channels increase and decrease as you do so (this is a good sign).</p>



<p>We’re going to check all the inputs one-by-one now.</p>



<p>We’ll start off with the throttle first. So, on the radio move the throttle stick to idle. If you look at the KK2.0 board and the throttle input it showing both ‘0’ and ‘idle’ then this is correct. If you push the throttle up you’ll see the number increase. If this isn’t right then you need to reverse the input on your radio.</p>



<p>Next check the rudder. On the left stick (same stick as the throttle) move it from side to side. When you move it left it should give you a negative number and ‘left’ and vise verse for right. Again, if it isn’t then you’ll need to reverse it.</p>



<p>Rinse and repeat this for the aileron and elevator.</p>



<p>The next step is to zero out all the numbers. Firstly, set the throttle to idle and center and center the right stick both vertically and horizontally. Then, using the trim and subtrim options on your radio adjust the throttle, rudder, aileron, and elevator until they are all displaying 0 on the KK2.0 board.</p>



<p>Sensor Calibration</p>



<p>The next step is to calibrate the ACC sensors. The reason we do this is to make sure the quadcopter knows exactly what is level and what is not (fairly important when it comes to self-levelling).</p>



<p>Firstly making sure your quadcopter is sitting on a flat surface and is level (a table or counter-top is ideal) and then:</p>



<ol class="wp-block-list">
<li>Press menu on the KK2.0 board</li>



<li>Press down and enter into ‘ACC Calibration’</li>



<li>It will tell you to put the quad on a flat surface. Press button 4 to continue</li>
</ol>



<p>It will now count down 5 seconds before calibrating. Once done you should see the all OK on the X,Y, and Z sensors:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="360" height="270" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-SensorTest.jpg" alt="Preparing the quadcopter – Sensor test" class="wp-image-80" srcset="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-SensorTest.jpg 360w, https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-SensorTest-300x225.jpg 300w" sizes="auto, (max-width: 360px) 100vw, 360px" /><figcaption class="wp-element-caption">Preparing the quadcopter – Sensor test</figcaption></figure>



<h2 class="wp-block-heading">ESC Calibration</h2>



<p>One of the small tweaks you need to do is the ESC calibration. You may find that when you fire up the quadcopter and apply a little throttle the motors will start at different times. Basically we just need to calibrate them in order for all 4 to start at the same time. This can get a little bit fiddly so it may take a couple of times to complete</p>



<ol class="wp-block-list">
<li>Turn on your radio and apply full throttle</li>



<li>Press and hold the 1st and 4th button on the KK2.0</li>



<li>Plug in the battery while still holding the buttons</li>



<li>Wait for 2 short beeps from all your ESCs</li>



<li>Move the throttle to idle</li>



<li>Then you should hear 1 short beep (you can take your fingers off the buttons now)</li>
</ol>



<p>Now fire up the motors and you will find they all start at the same time.</p>



<h2 class="wp-block-heading">Balancing and Attaching Props</h2>



<p>Balancing the props isn’t extremely necessary, but having said that it is quite important. Having balanced props generally means a smoother flight with less vibrations. This will be very helpful for those of you who want to continue on to uses cameras and FPV on your quadcopters. It can also mean that screws are less likely to vibrate themselves loose, so after all that it probably is quite a good idea to do this.</p>



<p>If you got the cheap and easy balancer from part 1 then really all you need to do is screw the prop into it and then balance it between two objects the same height (I use tissue boxes). If the prop falls to one side then all you need to do is either add tape to the lighter side or using high grit sandpaper, sand the heavier side.</p>



<p>Once you’ve found the sweet spot (the prop will sit level in the balancer) then you’re done. Do the other props and you’re set to go.</p>



<p>Once the props are balanced it’s time to attach them. Now you need to be careful you attach the right props to the right motor. When you bought props you got a set of CW and CCW props. So make sure that you attach the CW props to the motors spinning CW and vise versa for CCW.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="300" height="264" src="https://www.devhour.net/wp-content/uploads/2024/03/BuildQuadcopter-Pt3-Props.jpg" alt="Preparing the quadcopter – Attached Props" class="wp-image-81"/><figcaption class="wp-element-caption">Preparing the quadcopter – Attached Props</figcaption></figure>



<h2 class="wp-block-heading">Test Flight</h2>



<p>Now this is it. Time to fly this bad boy. More than likely it will be horribly out of tune so it will be fairly hard to fly. Feel free to skip this flight and move on to part 4 (tuning the KK2.) in order to ensure a more stable flight. However if you’re feeling up to it:</p>



<ol class="wp-block-list">
<li>Charge up the battery</li>



<li>Take the quadcopter outside (in a large enough area to fly. I suggest a park or football field)</li>



<li>Turn on the radio</li>



<li>Plug the battery into the harness</li>



<li>Step away a few meters and arm the quadcopter</li>



<li>Apply enough throttle to get off the ground</li>



<li>Practice flying and have fun!</li>
</ol>



<p>Once you’ve tried it out I suggest reading part 4 in order to tune and upgrade the KK2.0</p><p>The post <a href="https://www.devhour.net/build-a-quadcopter-part-3-preparing-the-quadcopter/">Build a quadcopter (Part 3) – Preparing the quadcopter</a> first appeared on <a href="https://www.devhour.net">Devhour</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://www.devhour.net/build-a-quadcopter-part-3-preparing-the-quadcopter/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
