<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tony Gambone</title>
    <description>Software developer and family man in Richmond, Virginia.
</description>
    <link>http://tonygambone.org/</link>
    <atom:link href="http://tonygambone.org/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Fri, 21 Oct 2016 03:54:32 +0000</pubDate>
    <lastBuildDate>Fri, 21 Oct 2016 03:54:32 +0000</lastBuildDate>
    <generator>Jekyll v3.2.1</generator>
    
      <item>
        <title>CPU Temperature Monitoring using Google Docs</title>
        <description>&lt;p&gt;I have a Gateway laptop that I bought (refurbished) about five years ago.  It’s running Linux Mint, and I use it for light web browsing and playing music on the sound system. It’s not
great - the build quality was pretty poor to begin with, and it’s definitely showing its age - but it works, mostly.&lt;/p&gt;

&lt;p&gt;This summer, however, it began to turn itself off.  Hard shutdown, no warning, just instantly dead.  The most common cause of this is overheating - the system shutting itself
off to prevent damage.  But the laptop wasn’t that hot to the touch.  It was running its fans on high speed most of the time, but I’d felt laptops get a lot hotter before.  The problem
got worse, though.  Eventually it was so bad that it would shut off within minutes of booting, even after hours of sitting idle.&lt;/p&gt;

&lt;p&gt;I started to think it might be the thermal paste - the goop that transfers heat from the CPU and GPU to the heat sink, and from there out of the case.  What if it had dried out?  I could
replace it, but I didn’t relish the prospect of cracking the case on this thing for no reason (luckily, it had become useless anyway, so I could risk accidentally destroying it).&lt;/p&gt;

&lt;p&gt;I wanted to be sure that overheating was the cause of the shutdowns. I needed to log the temperature readings from the motherboard sensors, and I wanted to send them to a healthy system
so I could see what was happening.  I decided to see if I could send them to a Google Docs spreadsheet - I could collect the data there, and also analyze it or export it as necessary.&lt;/p&gt;

&lt;p&gt;First of all, I installed the &lt;code class=&quot;highlighter-rouge&quot;&gt;sensors&lt;/code&gt; package.  Running this gave me output like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;acpitz-virtual-0
Adapter: Virtual device
temp1:        +94.0°C  (crit = +100.0°C)
temp2:        +87.0°C  (crit = +100.0°C)

k10temp-pci-00c3
Adapter: PCI adapter
temp1:        +94.1°C  (high = +95.0°C)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Okay, so I have three sensors in this machine, and they were running pretty freaking hot. Not good. Now I needed to parse that output for just the current values, removing all of the other
stuff.  After some command-line fiddling, I settled on:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sensors | grep ^temp | tr -d &quot;°C+&quot; | tr -s &quot; &quot; | cut -d&quot; &quot; -f2 | paste -sd &quot; &quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which resulted in one line with all three values on it: &lt;code class=&quot;highlighter-rouge&quot;&gt;94.0 87.0 94.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Google Docs, I created a spreadsheet with the columns I wanted - a timestamp and three sensor fields. To collect the data, I linked a survery form to the spreadsheet - I’d be able
to write a script to submit the sensor values using a simple HTTP POST.  The source code for the form contained the field names I’d need to send.&lt;/p&gt;

&lt;p&gt;My final script would post the sensor values every 30 seconds. It looked like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;nv&quot;&gt;TARGET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;https://docs.google.com/forms/d/1Atc69Dy4ZFnOQJMKd9grcd5cy8iYNT0T-BwYJFXjVpA/formResponse
&lt;span class=&quot;nv&quot;&gt;S1NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;entry.1507057940
&lt;span class=&quot;nv&quot;&gt;S2NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;entry.1234041023
&lt;span class=&quot;nv&quot;&gt;S3NAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;entry.1730611246

&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;do
 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;FIELDS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;sensors | grep ^temp | tr -d &lt;span class=&quot;s2&quot;&gt;&quot;°C+&quot;&lt;/span&gt; | tr -s &lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt; | cut -d&lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt; -f2 | paste -sd &lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;nv&quot;&gt;S1VAL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$FIELDS&lt;/span&gt; | cut -d&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt; -f1&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;nv&quot;&gt;S2VAL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$FIELDS&lt;/span&gt; | cut -d&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt; -f2&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;nv&quot;&gt;S3VAL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$FIELDS&lt;/span&gt; | cut -d&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt; -f3&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S1NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S1VAL&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S2NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S2VAL&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S3NAME&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$S3VAL&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; | POST -d &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$TARGET&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
 sleep 30
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;(The form is no longer accepting responses.) I set it up as a cron job to run on system startup: &lt;code class=&quot;highlighter-rouge&quot;&gt;@reboot /root/templog.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the spreadsheet happily accepting my sensor values, I rebooted the machine a few times, letting it turn itself off each time and cool down for a while. While I waited, I put together
a chart view of the sensor data. The result was &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1ZrOIIzPUbQYuPiaLOiLyeDF8wbLX7Mv_wAF5c83HS4U/pubchart?oid=1554113740&amp;amp;format=interactive&quot;&gt;this&lt;/a&gt;:&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/spreadsheets/d/1ZrOIIzPUbQYuPiaLOiLyeDF8wbLX7Mv_wAF5c83HS4U/pubchart?oid=1554113740&amp;amp;format=interactive&quot; style=&quot;height:380px;width:100%;border:0;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;In the end, I didn’t need to do much analysis. It was clear that in each case, the system temperature climbed until sensors #1 and #3 were near 100°, and then the system shut down, 
registering no data points until it started up again at a much lower temperature.&lt;/p&gt;

&lt;p&gt;So heat was definitely the culprit. I ordered a tube of thermal paste.&lt;/p&gt;

&lt;p&gt;I opened up the laptop, carefully collecting all the tiny screws (a strongish magnet in a stainless steel bowl works great!).  The heat sink assembly was mounted near the
very bottom of the case.  I unscrewed and removed the heat sink, exposing the thermal paste on the CPU and GPU. It was fairly dry and crumbly. I scraped it off, removing the last remnants 
with isopropyl alcohol, and applied the new paste.  With that done, I reassembled the laptop and (to put it mildly) was quite relieved when it booted up normally.&lt;/p&gt;

&lt;p&gt;Here are the &lt;a href=&quot;https://docs.google.com/spreadsheets/d/1ZrOIIzPUbQYuPiaLOiLyeDF8wbLX7Mv_wAF5c83HS4U/pubchart?oid=2022279560&amp;amp;format=interactive&quot;&gt;post-op temperature readings&lt;/a&gt;:&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/spreadsheets/d/1ZrOIIzPUbQYuPiaLOiLyeDF8wbLX7Mv_wAF5c83HS4U/pubchart?oid=2022279560&amp;amp;format=interactive&quot; style=&quot;height:380px;width:100%;border:0;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Pretty good. It still runs a bit hotter than I’d like, particularly under load, but it hasn’t turned itself off once since it got the new thermal paste. All in all, a very satisfying result.&lt;/p&gt;

</description>
        <pubDate>Sun, 28 Sep 2014 00:00:00 +0000</pubDate>
        <link>http://tonygambone.org/2014/09/28/cpu-temperature-monitoring-using-google-docs.html</link>
        <guid isPermaLink="true">http://tonygambone.org/2014/09/28/cpu-temperature-monitoring-using-google-docs.html</guid>
        
        
      </item>
    
      <item>
        <title>Monotask</title>
        <description>&lt;p&gt;Monotask was an attention management application, a joint startup effort between &lt;a href=&quot;http://charliepark.org&quot;&gt;Charlie Park&lt;/a&gt;
and me. We worked on it from 2011 to 2013.&lt;/p&gt;
&lt;p&gt;It consisted of a Rails application that would allow users to specify a weekly
schedule of sites to block, to help our users stay focused on their work.  There was also a client application, written in C++/Qt, that would synchronize with the 
web application and use the schedule data to control an HTTP proxy server (a custom Apache build).  The proxy server would
disallow access to the desired sites using rewrite rules.&lt;/p&gt;
&lt;p&gt;The client software was my primary focus; it went through several iterations. We were initially targeting Windows and
Mac, and the first version was a C#/.NET/Mono application.  At the time there was poor support for certain OS X features,
so I moved to a C++/Qt client that worked quite well.  Parts of the application needed OS-specific C++ and C code,
and the platform was flexible enough to allow this.&lt;/p&gt;
&lt;p&gt;The biggest pain point was reliably controlling the Apache instance; it would sometimes not come back up after
hibernation, for example, and was difficult to restart on Windows.  At the time that we closed the project down, I was
investigating various ways to integrate the proxy more fully into the control application; I was looking at a &lt;a href=&quot;https://gist.github.com/tonygambone/2422322&quot;&gt;Node.js
solution for this&lt;/a&gt;, and also experimenting with my own C++ HTTP forward proxy.&lt;/p&gt;
&lt;p&gt;We decided to shut the project down because we weren't able to meet our subscriber goals, but we were both very satisfied with
the application we'd built.&lt;/p&gt;
</description>
        <pubDate>Sun, 21 Sep 2014 00:00:00 +0000</pubDate>
        <link>http://tonygambone.org/projects/2014/09/21/monotask.html</link>
        <guid isPermaLink="true">http://tonygambone.org/projects/2014/09/21/monotask.html</guid>
        
        
        <category>projects</category>
        
      </item>
    
      <item>
        <title>DEQ CATS</title>
        <description>&lt;p&gt;CATS (Certification and Accreditation Tracking System) is a web application for people who need to get
various certifications through DEQ. This includes erosion &amp;amp; sediment control, stormwater management, and 
responsible land disturber (RLD) certificates.  The app allows users to pay for and take online courses,
track recertification hours, and print their certificates.&lt;/p&gt;
&lt;p&gt;I am the architect and lead developer on the CATS project. It consists of an ASP.NET MVC 5 web application
backed by SQL Server, plus some additional supporting utilities.&lt;/p&gt;
&lt;p&gt;This project is currently in development but should be feature complete by the end of the year. The most
interesting aspect of the project has been the various other systems it needs to integrate with. This includes:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;Legacy data:&lt;/strong&gt; Many of these certifications had been administered by another state agency
    (DCR) for several years, and so we have developed a process to load the legacy data into our production
    systems. This also includes some cleanup tasks, such as deduping, string normalization, etc.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Pearson VUE:&lt;/strong&gt; Some certification tests are administered at Pearson testing centers, and they make the test
    data available to us on an SFTP server. I wrote an ETL application that downloads the previous day's test data,
    parses and verifies it, and loads it into the CATS production database.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Articulate/SCORM:&lt;/strong&gt; For the RLD certification, users will pay for the certification and
    then take an online course and quiz.  The course is developed by our training staff using Articulate,
    and is &lt;a href=&quot;http://scorm.com/scorm-explained/&quot;&gt;SCORM&lt;/a&gt;-compatible. Rather than standing up a full LMS,
    I wrote a basic implementation of the SCORM API, enough to launch the course and retrieve the results.&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Elavon:&lt;/strong&gt; To accept payments, we need to integrate with the state-approved payment 
    gateway vendor. We are using Elavon's hosted payment form to accept credit card info so it does not pass
    through our systems. I was able to build on some work done on another DEQ project that was set up to accept
    payments and process them in daily batches. For CATS, we will handle the payments in real time.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CATS is also the second DEQ project to use a new security framework that provides an integrated login and
permission system for both internal and external users. Members of the public will not need to create separate
accounts for separate applications as we continue to bring more publicly accessible apps online. Internal users
can use their Active Directory credentials to access any of the apps. I helped to design the security framework
and have continued to update it.&lt;/p&gt;
</description>
        <pubDate>Sat, 20 Sep 2014 00:00:00 +0000</pubDate>
        <link>http://tonygambone.org/projects/2014/09/20/deq-cats.html</link>
        <guid isPermaLink="true">http://tonygambone.org/projects/2014/09/20/deq-cats.html</guid>
        
        
        <category>projects</category>
        
      </item>
    
  </channel>
</rss>
