Browse Source

Add openpreppad post

Thomas Dy 7 years ago
parent
commit
edd6f975bf

+ 182 - 0
content/posts/openpreppad.md

@@ -0,0 +1,182 @@
++++
+date = "2017-01-15T19:31:00+08:00"
+title = "OpenPrepPad"
+tags = [ "hardware", "bluetooth" ]
+
++++
+
+Smart electronics and IoT (Internet of Things) are all the rage these days. You
+have a lot of companies sprout up trying to make the next big thing, which also
+leads to a lot of failures big and small. Pebble, the maker of my smartwatch,
+got bought out by Fitbit recently. This left watch owners without any official
+support, but thankfully, community members [stepped up][1] to continue
+maintaining it.
+
+Another casualty of the IoT boom was the [Orange Chef][2] [Prep Pad][3]. It's a
+bluetooth connected weighing scale to make it easy to track your calories and
+carb/fat/protein intake. My dad bought it last year only to find out that the
+app was incredibly buggy. The search function doesn't work which makes the whole
+thing practically useless. I also found out later that you can't even download
+the app to use the scale anymore.
+
+**Note** I just found out as I was writing this post that it *may* get supported
+by [another company][4].
+
+So the app is useless, but at least you can use it as a scale, right?
+
+![Prep Pad](/galleries/openpreppad/preppad.jpg)
+
+Nope. The device has no display whatsoever. The only controls on it are the
+on/off button and a green LED that isn't even that useful at telling you whether
+it's on or not. At this point, it's just a giant paperweight.
+
+## Reverse Engineering
+
+Since I essentially had nothing to lose, I tried poking at the thing to figure
+out how it works. I didn't really have experience with bluetooth besides trying
+to get my bluetooth mouse connected on Linux. The main thing I used then was
+`bluetoothctl` which is essentially a CLI for managing bluetooth devices so I
+started there.
+
+I started up `bluetoothctl` and turned on the Prep Pad. And it showed up!
+
+```text
+[bluetooth]# power on
+[CHG] Controller ... Class: 0x00010c
+Changing power on succeeded
+[CHG] Controller ... Powered: yes
+[bluetooth]# scan on
+Discovery started
+[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
+```
+
+I then connected to it, which was surprisingly easy.
+
+```text
+[bluetooth]# connect 1C:BA:8C:21:7C:BB
+Attempting to connect to 1C:BA:8C:21:7C:BB
+[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
+```
+
+Now normally, when you turn the device on, the green light flashes occasionally.
+Once I connected to it, the green light stayed on permanently. Clearly, I was
+making progress. A lot of services were also discovered but I had no idea what
+those things were at that point.
+
+After a lot of poking around, I could check the general device information.  You
+could get hardware, software and firmware version. There's also the device
+serial number which was nowhere on the actual physical device.
+
+```text
+[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CH BTScale_00:/service0010/char0017]# attribute-info
+Characteristic - Firmware Revision String
+	UUID: 00002a26-0000-1000-8000-00805f9b34fb
+	Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
+	Value: 0x31
+	Value: 0x2e
+	Value: 0x31
+	Value: 0x33
+	Value: 0x41
+	Value: 0x00
+	Flags: read
+[CH BTScale_00:/service0010/char0017]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
+  31 2e 31 33 41 00                                1.13A.
+[CH BTScale_00:/service0010/char0017]#
+```
+
+There was also a service which contained Accel Enable, Accel Range, Accel
+X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for
+accelerometer, which is probably what it uses to weigh things.
+
+```text
+[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CH BTScale_00:/service0023/char0024/desc0026]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+  41 63 63 65 6c 20 45 6e 61 62 6c 65              Accel Enable
+```
+
+I couldn't read from any of the Accel Coordinates. It kept saying permission
+denied. I could however, notify on them. But that didn't yield anything as well.
+What I *could* read was Accel Enable, which was set to 00. I guess that means it
+was off. After writing 01 to Accel Enable, I found I could get values out of
+Accel X-Coordinate!
+
+```text
+[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# write 01
+Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
+[CH BTScale_00:/service0023/char002a]# notify on
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
+Notify started
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+```
+
+I tried pressing the scale down a few times, and the values changed accordingly.
+Now, I just had to figure out how to convert the values into grams. It looked
+like the values were 32-bit integers sent as 4 bytes. In the above example it
+would be `0x0002a35b`, `0x0002a355`, `0x0002a359` or 172891, 172855, 172899. The
+values also decrease as you exert more effort on the scale. So assuming you have
+take the initial value as *tare*, you simply subtract any succeeding from that
+*tare* and you can have your "weight".
+
+The values I got didn't seem to be grams though. After weighing some things on
+an actual scale and comparing the values I got, I found I can just divide the
+values by 14 and get something in grams. That 14 is entirely a magic number
+though and I have no idea whether other Prep Pad's would have the same constant.
+
+## OpenPrepPad
+
+With all that figured out, I went ahead and made a [simple CLI application][5]
+to interface with the Prep Pad. Ironically, node was the simplest thing I found
+that had [nice bluetooth library support][6] so that's what I wrote it in. I
+also added most of the technical details in the README for that as well.
+
+While this is all well and cool, I doubt the intersection of Linux users and
+people who <s>got ripped off</s> bought the Prep Pad is anyone besides me. In
+light of that, I'm in the process of making a React Native version of the app,
+but that's still a work in progress. Who knows, if the new owners of Prep Pad
+are good, I might not even need to finish it.
+
+[1]: http://rebble.io/
+[2]: http://theorangechef.com/
+[3]: https://www.amazon.com/Orange-Chef-Smart-Scale-Silver/dp/B00KFW8L90
+[4]: http://www.prnewswire.com/news-releases/perfect-company-acquires-orange-chefs-prep-pad-related-ip-continues-momentum-in-the-connected-kitchen-300383178.html
+[5]: https://github.com/thatsmydoing/openpreppad
+[6]: https://github.com/sandeepmistry/noble
+

BIN
output/galleries/openpreppad/preppad.jpg


+ 173 - 25
output/index.html

@@ -35,6 +35,179 @@
 <main id="content" role="main">
 <div class="postindex">
 	
+	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
+		<header>
+			<h1 class="p-name entry-title" itemprop="headline">
+				<a href="/posts/openpreppad.html" class="u-url">OpenPrepPad</a>
+			</h1>
+		</header>
+		<div class="e-content entry-content">
+			
+
+<p>Smart electronics and IoT (Internet of Things) are all the rage these days. You
+have a lot of companies sprout up trying to make the next big thing, which also
+leads to a lot of failures big and small. Pebble, the maker of my smartwatch,
+got bought out by Fitbit recently. This left watch owners without any official
+support, but thankfully, community members <a href="http://rebble.io/">stepped up</a> to continue
+maintaining it.</p>
+
+<p>Another casualty of the IoT boom was the <a href="http://theorangechef.com/">Orange Chef</a> <a href="https://www.amazon.com/Orange-Chef-Smart-Scale-Silver/dp/B00KFW8L90">Prep Pad</a>. It&rsquo;s a
+bluetooth connected weighing scale to make it easy to track your calories and
+carb/fat/protein intake. My dad bought it last year only to find out that the
+app was incredibly buggy. The search function doesn&rsquo;t work which makes the whole
+thing practically useless. I also found out later that you can&rsquo;t even download
+the app to use the scale anymore.</p>
+
+<p><strong>Note</strong> I just found out as I was writing this post that it <em>may</em> get supported
+by <a href="http://www.prnewswire.com/news-releases/perfect-company-acquires-orange-chefs-prep-pad-related-ip-continues-momentum-in-the-connected-kitchen-300383178.html">another company</a>.</p>
+
+<p>So the app is useless, but at least you can use it as a scale, right?</p>
+
+<p><img src="/galleries/openpreppad/preppad.jpg" alt="Prep Pad" /></p>
+
+<p>Nope. The device has no display whatsoever. The only controls on it are the
+on/off button and a green LED that isn&rsquo;t even that useful at telling you whether
+it&rsquo;s on or not. At this point, it&rsquo;s just a giant paperweight.</p>
+
+<h2 id="reverse-engineering">Reverse Engineering</h2>
+
+<p>Since I essentially had nothing to lose, I tried poking at the thing to figure
+out how it works. I didn&rsquo;t really have experience with bluetooth besides trying
+to get my bluetooth mouse connected on Linux. The main thing I used then was
+<code>bluetoothctl</code> which is essentially a CLI for managing bluetooth devices so I
+started there.</p>
+
+<p>I started up <code>bluetoothctl</code> and turned on the Prep Pad. And it showed up!</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[bluetooth]# power on
+[CHG] Controller ... Class: 0x00010c
+Changing power on succeeded
+[CHG] Controller ... Powered: yes
+[bluetooth]# scan on
+Discovery started
+[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
+</pre></div>
+
+<p>I then connected to it, which was surprisingly easy.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[bluetooth]# connect 1C:BA:8C:21:7C:BB
+Attempting to connect to 1C:BA:8C:21:7C:BB
+[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
+</pre></div>
+
+<p>Now normally, when you turn the device on, the green light flashes occasionally.
+Once I connected to it, the green light stayed on permanently. Clearly, I was
+making progress. A lot of services were also discovered but I had no idea what
+those things were at that point.</p>
+
+<p>After a lot of poking around, I could check the general device information.  You
+could get hardware, software and firmware version. There&rsquo;s also the device
+serial number which was nowhere on the actual physical device.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CH BTScale_00:/service0010/char0017]# attribute-info
+Characteristic - Firmware Revision String
+	UUID: 00002a26-0000-1000-8000-00805f9b34fb
+	Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
+	Value: 0x31
+	Value: 0x2e
+	Value: 0x31
+	Value: 0x33
+	Value: 0x41
+	Value: 0x00
+	Flags: read
+[CH BTScale_00:/service0010/char0017]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
+  31 2e 31 33 41 00                                1.13A.
+[CH BTScale_00:/service0010/char0017]#
+</pre></div>
+
+<p>There was also a service which contained Accel Enable, Accel Range, Accel
+X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for
+accelerometer, which is probably what it uses to weigh things.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CH BTScale_00:/service0023/char0024/desc0026]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+  41 63 63 65 6c 20 45 6e 61 62 6c 65              Accel Enable
+</pre></div>
+
+<p>I couldn&rsquo;t read from any of the Accel Coordinates. It kept saying permission
+denied. I could however, notify on them. But that didn&rsquo;t yield anything as well.
+What I <em>could</em> read was Accel Enable, which was set to 00. I guess that means it
+was off. After writing 01 to Accel Enable, I found I could get values out of
+Accel X-Coordinate!</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# write 01
+Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
+[CH BTScale_00:/service0023/char002a]# notify on
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
+Notify started
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+</pre></div>
+
+<p>I tried pressing the scale down a few times, and the values changed accordingly.
+Now, I just had to figure out how to convert the values into grams. It looked
+like the values were 32-bit integers sent as 4 bytes. In the above example it
+would be <code>0x0002a35b</code>, <code>0x0002a355</code>, <code>0x0002a359</code> or 172891, 172855, 172899. The
+values also decrease as you exert more effort on the scale. So assuming you have
+take the initial value as <em>tare</em>, you simply subtract any succeeding from that
+<em>tare</em> and you can have your &ldquo;weight&rdquo;.</p>
+
+<p>The values I got didn&rsquo;t seem to be grams though. After weighing some things on
+an actual scale and comparing the values I got, I found I can just divide the
+values by 14 and get something in grams. That 14 is entirely a magic number
+though and I have no idea whether other Prep Pad&rsquo;s would have the same constant.</p>
+
+<h2 id="openpreppad">OpenPrepPad</h2>
+
+<p>With all that figured out, I went ahead and made a <a href="https://github.com/thatsmydoing/openpreppad">simple CLI application</a>
+to interface with the Prep Pad. Ironically, node was the simplest thing I found
+that had <a href="https://github.com/sandeepmistry/noble">nice bluetooth library support</a> so that&rsquo;s what I wrote it in. I
+also added most of the technical details in the README for that as well.</p>
+
+<p>While this is all well and cool, I doubt the intersection of Linux users and
+people who <s>got ripped off</s> bought the Prep Pad is anyone besides me. In
+light of that, I&rsquo;m in the process of making a React Native version of the app,
+but that&rsquo;s still a work in progress. Who knows, if the new owners of Prep Pad
+are good, I might not even need to finish it.</p>
+
+		</div>
+		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2017-01-15">2017-01-15</time></small>
+		| <small class="commentline"><a href="/posts/openpreppad.html#disqus_thread" data-disqus-identifier="cache/posts/.html">Comments</a></small>
+	</article>
+	</article>
+	
 	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
 		<header>
 			<h1 class="p-name entry-title" itemprop="headline">
@@ -264,31 +437,6 @@ twanager bag default <span style="color: #BA2121">&lt;&lt;EOF</span>
 	</article>
 	</article>
 	
-	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
-		<header>
-			<h1 class="p-name entry-title" itemprop="headline">
-				<a href="/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html" class="u-url">Removing PLDTMyDSLBiz from the ZyXEL P-2612HNU</a>
-			</h1>
-		</header>
-		<div class="e-content entry-content">
-			<p>I&rsquo;ve always thought that people were just too lazy to change their SSIDs when I see &ldquo;PLDTMyDSLBizCafeJapan&rdquo;. It became apparent when we got our own PLDT line that it was because the bundled router/modem <em>does not</em> allow you to remove the prefix.</p>
-
-<p>This is not the kind of thing you expect as a business customer. Even for home customers, I feel it&rsquo;s still a bit dishonest. I&rsquo;d be fine if it was just the default SSID, but forcing people to have it as part of their SSID is like advertising that your company (I mean PLDT) is a douche.</p>
-
-<p>Of course, we couldn&rsquo;t just leave the SSID prefix there, so we tried a number of things to get rid of it. There are articles for removing it from the <a href="http://www.phandroidinternet.com/2013/06/how-to-remove-on-wifi-name-or-ssid-on.html">Prolink H5004N</a> or the <a href="http://www.symbianize.com/showthread.php?t=730091">ZyXEL P-660HN-T1A</a> but not for the one we got which was the ZyXEL P-2612HNU-F1F.</p>
-
-<p>We did still try the firebug/inspector tricks, but it seems that there is a server-side check that adds in the &ldquo;PLDTMyDSLBiz&rdquo;. We tried a number of things, but the one that ultimately worked (and we had a good laugh about) was to backup the configuration, edit the dumped file and restore it.</p>
-
-<p>The backup is actually just an XML file. You can search for SSID and change the parameter there. It&rsquo;s a bit annoying because the router has to restart after restoring the configuration, but it works!</p>
-
-<p>A minor note, the router doesn&rsquo;t seem to support SSIDs with a comma (,) well. It just gets everything before the comma as the SSID for some reason.</p>
-
-		</div>
-		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-11-27">2013-11-27</time></small>
-		| <small class="commentline"><a href="/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html#disqus_thread" data-disqus-identifier="cache/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html">Comments</a></small>
-	</article>
-	</article>
-	
 </div>
 <nav class="postindexpager">
 	<ul class="pager clearfix">

+ 25 - 27
output/page/2.html

@@ -35,6 +35,31 @@
 <main id="content" role="main">
 <div class="postindex">
 	
+	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
+		<header>
+			<h1 class="p-name entry-title" itemprop="headline">
+				<a href="/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html" class="u-url">Removing PLDTMyDSLBiz from the ZyXEL P-2612HNU</a>
+			</h1>
+		</header>
+		<div class="e-content entry-content">
+			<p>I&rsquo;ve always thought that people were just too lazy to change their SSIDs when I see &ldquo;PLDTMyDSLBizCafeJapan&rdquo;. It became apparent when we got our own PLDT line that it was because the bundled router/modem <em>does not</em> allow you to remove the prefix.</p>
+
+<p>This is not the kind of thing you expect as a business customer. Even for home customers, I feel it&rsquo;s still a bit dishonest. I&rsquo;d be fine if it was just the default SSID, but forcing people to have it as part of their SSID is like advertising that your company (I mean PLDT) is a douche.</p>
+
+<p>Of course, we couldn&rsquo;t just leave the SSID prefix there, so we tried a number of things to get rid of it. There are articles for removing it from the <a href="http://www.phandroidinternet.com/2013/06/how-to-remove-on-wifi-name-or-ssid-on.html">Prolink H5004N</a> or the <a href="http://www.symbianize.com/showthread.php?t=730091">ZyXEL P-660HN-T1A</a> but not for the one we got which was the ZyXEL P-2612HNU-F1F.</p>
+
+<p>We did still try the firebug/inspector tricks, but it seems that there is a server-side check that adds in the &ldquo;PLDTMyDSLBiz&rdquo;. We tried a number of things, but the one that ultimately worked (and we had a good laugh about) was to backup the configuration, edit the dumped file and restore it.</p>
+
+<p>The backup is actually just an XML file. You can search for SSID and change the parameter there. It&rsquo;s a bit annoying because the router has to restart after restoring the configuration, but it works!</p>
+
+<p>A minor note, the router doesn&rsquo;t seem to support SSIDs with a comma (,) well. It just gets everything before the comma as the SSID for some reason.</p>
+
+		</div>
+		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-11-27">2013-11-27</time></small>
+		| <small class="commentline"><a href="/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html#disqus_thread" data-disqus-identifier="cache/posts/removing-pldtmydslbiz-from-the-zyxel-p-2612hnu.html">Comments</a></small>
+	</article>
+	</article>
+	
 	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
 		<header>
 			<h1 class="p-name entry-title" itemprop="headline">
@@ -187,33 +212,6 @@ sed -i .bak <span style="color: #BA2121">&#39;/^72/ s/,600/,60/&#39;</span> freq
 	</article>
 	</article>
 	
-	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
-		<header>
-			<h1 class="p-name entry-title" itemprop="headline">
-				<a href="/posts/elevation-data-in-otp.html" class="u-url">Elevation Data in OTP</a>
-			</h1>
-		</header>
-		<div class="e-content entry-content">
-			<p><img src="../galleries/transit/otpelevation.png" alt="OpenTripPlanner showing elevation data" /></p>
-
-<p>One thing I hadn&rsquo;t tested out last time was OTP&rsquo;s support for elevation data. It makes use of this by showing the elevation you have to traverse while walking along the suggested route. It can also take it into account when suggesting bike routes.</p>
-
-<p>The <a href="https://github.com/openplans/OpenTripPlanner/wiki/FiveMinutes">5 minute tutorial</a> actually discusses the elevation data briefly, but a more in-depth thing you can look at is the <a href="https://github.com/openplans/OpenTripPlanner/wiki/GraphBuilder#elevation-data">GraphBuilder documentation</a>. It suggests using the ASTER dataset which is free but requires registration. I just opted to use the SRTM data available from the <a href="http://www.philgis.org/freegisdata.htm">PhilGIS website</a>.</p>
-
-<p>I don&rsquo;t know about the ASTER dataset, but the PhilGIS data was in the ERDAS img format. OTP only supports GeoTIFF so there was a need to convert it beforehand. You can use <a href="http://www.gdal.org/">GDAL</a> for this. You&rsquo;d just then run,</p>
-<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>gdal_translate srtm41_90m_phl.img phil.tiff
-</pre></div>
-
-<p>Afterwards, it&rsquo;s just a matter of following the OTP instructions on using a local elevation dataset. The process actually doubled the size of the generated Graph.obj so it might not be ideal if you&rsquo;re running on limited RAM.</p>
-
-<p>I&rsquo;ve actually hosted a <a href="http://maps.pleasantprogrammer.com">working example</a>. It&rsquo;s pretty much at the limits of the RAM so it might be slow and unreliable, but you can test it out just for fun. Please don&rsquo;t abuse it though.</p>
-
-		</div>
-		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-07-23">2013-07-23</time></small>
-		| <small class="commentline"><a href="/posts/elevation-data-in-otp.html#disqus_thread" data-disqus-identifier="cache/posts/elevation-data-in-otp.html">Comments</a></small>
-	</article>
-	</article>
-	
 </div>
 <nav class="postindexpager">
 	<ul class="pager clearfix">

+ 27 - 37
output/page/3.html

@@ -35,6 +35,33 @@
 <main id="content" role="main">
 <div class="postindex">
 	
+	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
+		<header>
+			<h1 class="p-name entry-title" itemprop="headline">
+				<a href="/posts/elevation-data-in-otp.html" class="u-url">Elevation Data in OTP</a>
+			</h1>
+		</header>
+		<div class="e-content entry-content">
+			<p><img src="../galleries/transit/otpelevation.png" alt="OpenTripPlanner showing elevation data" /></p>
+
+<p>One thing I hadn&rsquo;t tested out last time was OTP&rsquo;s support for elevation data. It makes use of this by showing the elevation you have to traverse while walking along the suggested route. It can also take it into account when suggesting bike routes.</p>
+
+<p>The <a href="https://github.com/openplans/OpenTripPlanner/wiki/FiveMinutes">5 minute tutorial</a> actually discusses the elevation data briefly, but a more in-depth thing you can look at is the <a href="https://github.com/openplans/OpenTripPlanner/wiki/GraphBuilder#elevation-data">GraphBuilder documentation</a>. It suggests using the ASTER dataset which is free but requires registration. I just opted to use the SRTM data available from the <a href="http://www.philgis.org/freegisdata.htm">PhilGIS website</a>.</p>
+
+<p>I don&rsquo;t know about the ASTER dataset, but the PhilGIS data was in the ERDAS img format. OTP only supports GeoTIFF so there was a need to convert it beforehand. You can use <a href="http://www.gdal.org/">GDAL</a> for this. You&rsquo;d just then run,</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>gdal_translate srtm41_90m_phl.img phil.tiff
+</pre></div>
+
+<p>Afterwards, it&rsquo;s just a matter of following the OTP instructions on using a local elevation dataset. The process actually doubled the size of the generated Graph.obj so it might not be ideal if you&rsquo;re running on limited RAM.</p>
+
+<p>I&rsquo;ve actually hosted a <a href="http://maps.pleasantprogrammer.com">working example</a>. It&rsquo;s pretty much at the limits of the RAM so it might be slow and unreliable, but you can test it out just for fun. Please don&rsquo;t abuse it though.</p>
+
+		</div>
+		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-07-23">2013-07-23</time></small>
+		| <small class="commentline"><a href="/posts/elevation-data-in-otp.html#disqus_thread" data-disqus-identifier="cache/posts/elevation-data-in-otp.html">Comments</a></small>
+	</article>
+	</article>
+	
 	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
 		<header>
 			<h1 class="p-name entry-title" itemprop="headline">
@@ -383,43 +410,6 @@ Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
 	</article>
 	</article>
 	
-	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
-		<header>
-			<h1 class="p-name entry-title" itemprop="headline">
-				<a href="/posts/one-bus-or-maybe-jeep-away.html" class="u-url">One Bus (or maybe Jeep) Away</a>
-			</h1>
-		</header>
-		<div class="e-content entry-content">
-			<p>Link: <a href="http://onebusaway.org/">http://onebusaway.org/</a></p>
-
-<p><strong>TL;DR</strong> no routing; useless in Philippines</p>
-
-<p>OneBusAway is a transit information app. It provides data on what bus stops are near you, which buses pass by. You can also get schedules and the route of a particular bus given the number. It can also provide realtime updates like how many minutes until the next bus arrives. It does not, however, provide routing. There is no support for providing directions to get from point A to point B.</p>
-
-<p>It&rsquo;s comparable to what you get in some bus stops abroad. You&rsquo;d get a vicinity map and a list of buses passing through the stop. You might also get the times when the next buses will pass. It&rsquo;s useful for locals who already know how to get around, and want to avoid waiting for the bus. But it&rsquo;s not particularly good for people who want to know how to get around the city.</p>
-
-<p>OneBusAway is quite comprehensive in its platform support though. There is a webapp, apps for iOS, Android and Windows Phone, as well as SMS and Voice support. This would all be nice but we don&rsquo;t have the necessary infrastructure yet in the Philippines. We don&rsquo;t have bus or jeepney stops. We also wouldn&rsquo;t have realtime data to make the app particularly useful.</p>
-
-<p>You can try it out for yourself by following their <a href="https://github.com/OneBusAway/onebusaway-application-modules/wiki/OneBusAway-Quickstart-Guide">Quickstart Guide</a>. One caveat is you will have to add <code>-P tripEntriesFactory.throwExceptionOnInvalidStopToShapeMappingException=false</code> when building the bundle. This has to do with the OneBusAway having difficulty matching the <a href="https://github.com/OneBusAway/onebusaway-application-modules/wiki/Stop-to-Shape-Matching">stops to the shape data</a>.</p>
-
-<p>Here&rsquo;s some screenshots of the app with the Philippine data. Notice how you only see the stops but there isn&rsquo;t a line for the route. This is a problem with our GTFS data. Also, at some points it&rsquo;s hard to tell where the jeep is going to pass since there isn&rsquo;t any indication of order either. This is more of a OneBusAway problem. It usually expects there to be shape data available.</p>
-
-<p><a href="../galleries/transit/onebusaway1.png"><img src="../galleries/transit/onebusaway1.png" alt="OneBusAway" title="All the stops along Katipunan Avenue are named Katipunan Avenue." /></a></p>
-
-<p>It doesn&rsquo;t really handle too many routes passing through a stop. The list just overflows past the bubble. You can still actually read it by panning the map. It&rsquo;s just a bit weird though.</p>
-
-<p>If you also noticed, there are usually 2 of each route. This is how the jeepney data was modeled as jeep routes might be different going one way and going back. This isn&rsquo;t the case for all jeeps though, so it might also be an implementation issue with the GTFS editor.</p>
-
-<p><a href="../galleries/transit/onebusaway2.png"><img src="../galleries/transit/onebusaway2.png" alt="OneBusAway" /></a></p>
-
-<p><a href="../galleries/transit/onebusaway3.png"><img src="../galleries/transit/onebusaway3.png" alt="OneBusAway" /></a></p>
-
-		</div>
-		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-07-09">2013-07-09</time></small>
-		| <small class="commentline"><a href="/posts/one-bus-or-maybe-jeep-away.html#disqus_thread" data-disqus-identifier="cache/posts/one-bus-or-maybe-jeep-away.html">Comments</a></small>
-	</article>
-	</article>
-	
 </div>
 <nav class="postindexpager">
 	<ul class="pager clearfix">

+ 37 - 0
output/page/4.html

@@ -35,6 +35,43 @@
 <main id="content" role="main">
 <div class="postindex">
 	
+	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
+		<header>
+			<h1 class="p-name entry-title" itemprop="headline">
+				<a href="/posts/one-bus-or-maybe-jeep-away.html" class="u-url">One Bus (or maybe Jeep) Away</a>
+			</h1>
+		</header>
+		<div class="e-content entry-content">
+			<p>Link: <a href="http://onebusaway.org/">http://onebusaway.org/</a></p>
+
+<p><strong>TL;DR</strong> no routing; useless in Philippines</p>
+
+<p>OneBusAway is a transit information app. It provides data on what bus stops are near you, which buses pass by. You can also get schedules and the route of a particular bus given the number. It can also provide realtime updates like how many minutes until the next bus arrives. It does not, however, provide routing. There is no support for providing directions to get from point A to point B.</p>
+
+<p>It&rsquo;s comparable to what you get in some bus stops abroad. You&rsquo;d get a vicinity map and a list of buses passing through the stop. You might also get the times when the next buses will pass. It&rsquo;s useful for locals who already know how to get around, and want to avoid waiting for the bus. But it&rsquo;s not particularly good for people who want to know how to get around the city.</p>
+
+<p>OneBusAway is quite comprehensive in its platform support though. There is a webapp, apps for iOS, Android and Windows Phone, as well as SMS and Voice support. This would all be nice but we don&rsquo;t have the necessary infrastructure yet in the Philippines. We don&rsquo;t have bus or jeepney stops. We also wouldn&rsquo;t have realtime data to make the app particularly useful.</p>
+
+<p>You can try it out for yourself by following their <a href="https://github.com/OneBusAway/onebusaway-application-modules/wiki/OneBusAway-Quickstart-Guide">Quickstart Guide</a>. One caveat is you will have to add <code>-P tripEntriesFactory.throwExceptionOnInvalidStopToShapeMappingException=false</code> when building the bundle. This has to do with the OneBusAway having difficulty matching the <a href="https://github.com/OneBusAway/onebusaway-application-modules/wiki/Stop-to-Shape-Matching">stops to the shape data</a>.</p>
+
+<p>Here&rsquo;s some screenshots of the app with the Philippine data. Notice how you only see the stops but there isn&rsquo;t a line for the route. This is a problem with our GTFS data. Also, at some points it&rsquo;s hard to tell where the jeep is going to pass since there isn&rsquo;t any indication of order either. This is more of a OneBusAway problem. It usually expects there to be shape data available.</p>
+
+<p><a href="../galleries/transit/onebusaway1.png"><img src="../galleries/transit/onebusaway1.png" alt="OneBusAway" title="All the stops along Katipunan Avenue are named Katipunan Avenue." /></a></p>
+
+<p>It doesn&rsquo;t really handle too many routes passing through a stop. The list just overflows past the bubble. You can still actually read it by panning the map. It&rsquo;s just a bit weird though.</p>
+
+<p>If you also noticed, there are usually 2 of each route. This is how the jeepney data was modeled as jeep routes might be different going one way and going back. This isn&rsquo;t the case for all jeeps though, so it might also be an implementation issue with the GTFS editor.</p>
+
+<p><a href="../galleries/transit/onebusaway2.png"><img src="../galleries/transit/onebusaway2.png" alt="OneBusAway" /></a></p>
+
+<p><a href="../galleries/transit/onebusaway3.png"><img src="../galleries/transit/onebusaway3.png" alt="OneBusAway" /></a></p>
+
+		</div>
+		<small class="dateline">Posted: <time class="published dt-published" itemprop="datePublished" datetime="2013-07-09">2013-07-09</time></small>
+		| <small class="commentline"><a href="/posts/one-bus-or-maybe-jeep-away.html#disqus_thread" data-disqus-identifier="cache/posts/one-bus-or-maybe-jeep-away.html">Comments</a></small>
+	</article>
+	</article>
+	
 	<article class="h-entry post-text" itemscope itemtype="http://schema.org/Blog">
 		<header>
 			<h1 class="p-name entry-title" itemprop="headline">

+ 5 - 0
output/posts.html

@@ -39,6 +39,11 @@
 	</header>
 	<ul class="postlist">
 		
+		<li>
+			<a class="listtitle" href="/posts/openpreppad.html">OpenPrepPad</a>
+			<span class="entry-meta"><time itemprop="datePublished" datetime="2017-01-15">2017-01-15</time></span>
+		</li>
+		
 		<li>
 			<a class="listtitle" href="/posts/haproxy-charset.html">Haproxy Charset</a>
 			<span class="entry-meta"><time itemprop="datePublished" datetime="2016-06-24">2016-06-24</time></span>

+ 4 - 0
output/posts/haproxy-charset.html

@@ -74,6 +74,10 @@ rspirep (Content-Type.*) \1;\ charset=utf-8 unless has_charset
 				</li>
 				
 				
+				<li class="next">
+					<a href="/posts/openpreppad.html" rel="next" title="OpenPrepPad">Next post &rarr;</a>
+				</li>
+				
 			</ul>
 		</nav>
 	</aside>

+ 279 - 0
output/posts/openpreppad.html

@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<html lang="en-us">
+<head>
+	<meta charset="utf-8">
+	<meta name="generator" content="Hugo 0.18.1" />
+	<meta name="viewport" content="width=device-width, initial-scale=1">
+	<link rel="stylesheet" href="/assets/css/theme.css">
+	<link rel="alternate" href="/rss.xml" type="application/rss+xml" title="Pleasant Programmer">
+	<script type="text/javascript" src="//use.typekit.net/iwm5axp.js"></script>
+	<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
+	<title>OpenPrepPad - Pleasant Programmer</title>
+</head>
+
+<body>
+	<header id="header" role="banner">
+		<div id="thomas">
+			<img src="/assets/img/thomas.gif" alt="DJ THOMAS IN DA HAUS">
+			<img src="/assets/img/thomas.png" alt="Pleasant Programmer">
+		</div>
+		<h1 class="site-title"><a href="/">Pleasant Programmer</a></h1>
+		<nav id="menu" role="navigation">
+			<ul>
+				<li class="twitter">
+					<a href="http://twitter.com/pleasantprog">@pleasantprog</a>
+				</li>
+				<li><a href="/posts.html">archives</a></li>
+				<li><a href="/tags.html">tags</a></li>
+				<li><a href="/rss.xml">rss</a></li>
+			</ul>
+		</nav>
+	</header>
+	<div id="container">
+
+
+<main id="content" role="main">
+<article itemscope itemtype="http://schema.org/BlogPosting">
+	<h1 class="p-name entry-title" itemprop="headline name">
+		<a href="/posts/openpreppad.html">OpenPrepPad</a></h1>
+	<small>
+		<span class="dateline">Posted: <time itemprop="datePublished" datetime="2017-01-15">2017-01-15</time></span>
+		| More posts about
+		
+		<a class="tag p-category" href="/tags/hardware.html" rel="tag">
+			hardware
+		</a>
+		
+		<a class="tag p-category" href="/tags/bluetooth.html" rel="tag">
+			bluetooth
+		</a>
+		
+	</small>
+	<div class="e-content entry-content" itemprop="entry-text">
+		
+
+<p>Smart electronics and IoT (Internet of Things) are all the rage these days. You
+have a lot of companies sprout up trying to make the next big thing, which also
+leads to a lot of failures big and small. Pebble, the maker of my smartwatch,
+got bought out by Fitbit recently. This left watch owners without any official
+support, but thankfully, community members <a href="http://rebble.io/">stepped up</a> to continue
+maintaining it.</p>
+
+<p>Another casualty of the IoT boom was the <a href="http://theorangechef.com/">Orange Chef</a> <a href="https://www.amazon.com/Orange-Chef-Smart-Scale-Silver/dp/B00KFW8L90">Prep Pad</a>. It&rsquo;s a
+bluetooth connected weighing scale to make it easy to track your calories and
+carb/fat/protein intake. My dad bought it last year only to find out that the
+app was incredibly buggy. The search function doesn&rsquo;t work which makes the whole
+thing practically useless. I also found out later that you can&rsquo;t even download
+the app to use the scale anymore.</p>
+
+<p><strong>Note</strong> I just found out as I was writing this post that it <em>may</em> get supported
+by <a href="http://www.prnewswire.com/news-releases/perfect-company-acquires-orange-chefs-prep-pad-related-ip-continues-momentum-in-the-connected-kitchen-300383178.html">another company</a>.</p>
+
+<p>So the app is useless, but at least you can use it as a scale, right?</p>
+
+<p><img src="/galleries/openpreppad/preppad.jpg" alt="Prep Pad" /></p>
+
+<p>Nope. The device has no display whatsoever. The only controls on it are the
+on/off button and a green LED that isn&rsquo;t even that useful at telling you whether
+it&rsquo;s on or not. At this point, it&rsquo;s just a giant paperweight.</p>
+
+<h2 id="reverse-engineering">Reverse Engineering</h2>
+
+<p>Since I essentially had nothing to lose, I tried poking at the thing to figure
+out how it works. I didn&rsquo;t really have experience with bluetooth besides trying
+to get my bluetooth mouse connected on Linux. The main thing I used then was
+<code>bluetoothctl</code> which is essentially a CLI for managing bluetooth devices so I
+started there.</p>
+
+<p>I started up <code>bluetoothctl</code> and turned on the Prep Pad. And it showed up!</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[bluetooth]# power on
+[CHG] Controller ... Class: 0x00010c
+Changing power on succeeded
+[CHG] Controller ... Powered: yes
+[bluetooth]# scan on
+Discovery started
+[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
+</pre></div>
+
+<p>I then connected to it, which was surprisingly easy.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[bluetooth]# connect 1C:BA:8C:21:7C:BB
+Attempting to connect to 1C:BA:8C:21:7C:BB
+[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
+</pre></div>
+
+<p>Now normally, when you turn the device on, the green light flashes occasionally.
+Once I connected to it, the green light stayed on permanently. Clearly, I was
+making progress. A lot of services were also discovered but I had no idea what
+those things were at that point.</p>
+
+<p>After a lot of poking around, I could check the general device information.  You
+could get hardware, software and firmware version. There&rsquo;s also the device
+serial number which was nowhere on the actual physical device.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CH BTScale_00:/service0010/char0017]# attribute-info
+Characteristic - Firmware Revision String
+	UUID: 00002a26-0000-1000-8000-00805f9b34fb
+	Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
+	Value: 0x31
+	Value: 0x2e
+	Value: 0x31
+	Value: 0x33
+	Value: 0x41
+	Value: 0x00
+	Flags: read
+[CH BTScale_00:/service0010/char0017]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
+  31 2e 31 33 41 00                                1.13A.
+[CH BTScale_00:/service0010/char0017]#
+</pre></div>
+
+<p>There was also a service which contained Accel Enable, Accel Range, Accel
+X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for
+accelerometer, which is probably what it uses to weigh things.</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CH BTScale_00:/service0023/char0024/desc0026]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+  41 63 63 65 6c 20 45 6e 61 62 6c 65              Accel Enable
+</pre></div>
+
+<p>I couldn&rsquo;t read from any of the Accel Coordinates. It kept saying permission
+denied. I could however, notify on them. But that didn&rsquo;t yield anything as well.
+What I <em>could</em> read was Accel Enable, which was set to 00. I guess that means it
+was off. After writing 01 to Accel Enable, I found I could get values out of
+Accel X-Coordinate!</p>
+<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# write 01
+Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
+[CH BTScale_00:/service0023/char002a]# notify on
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
+Notify started
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+</pre></div>
+
+<p>I tried pressing the scale down a few times, and the values changed accordingly.
+Now, I just had to figure out how to convert the values into grams. It looked
+like the values were 32-bit integers sent as 4 bytes. In the above example it
+would be <code>0x0002a35b</code>, <code>0x0002a355</code>, <code>0x0002a359</code> or 172891, 172855, 172899. The
+values also decrease as you exert more effort on the scale. So assuming you have
+take the initial value as <em>tare</em>, you simply subtract any succeeding from that
+<em>tare</em> and you can have your &ldquo;weight&rdquo;.</p>
+
+<p>The values I got didn&rsquo;t seem to be grams though. After weighing some things on
+an actual scale and comparing the values I got, I found I can just divide the
+values by 14 and get something in grams. That 14 is entirely a magic number
+though and I have no idea whether other Prep Pad&rsquo;s would have the same constant.</p>
+
+<h2 id="openpreppad">OpenPrepPad</h2>
+
+<p>With all that figured out, I went ahead and made a <a href="https://github.com/thatsmydoing/openpreppad">simple CLI application</a>
+to interface with the Prep Pad. Ironically, node was the simplest thing I found
+that had <a href="https://github.com/sandeepmistry/noble">nice bluetooth library support</a> so that&rsquo;s what I wrote it in. I
+also added most of the technical details in the README for that as well.</p>
+
+<p>While this is all well and cool, I doubt the intersection of Linux users and
+people who <s>got ripped off</s> bought the Prep Pad is anyone besides me. In
+light of that, I&rsquo;m in the process of making a React Native version of the app,
+but that&rsquo;s still a work in progress. Who knows, if the new owners of Prep Pad
+are good, I might not even need to finish it.</p>
+
+	</div>
+	<aside class="postpromonav">
+		<nav>
+			<ul class="pager clearfix">
+				
+				<li class="previous">
+					<a href="/posts/haproxy-charset.html" rel="prev" title="Haproxy Charset">&larr; Previous post</a>
+				</li>
+				
+				
+			</ul>
+		</nav>
+	</aside>
+	<section class="comments">
+		<div id="disqus_thread"></div>
+<script type="text/javascript">
+var disqus_shortname = 'pleasantprog';
+var disqus_url = 'http:\/\/pleasantprogrammer.com\/posts\/openpreppad.html';
+var disqus_title = 'OpenPrepPad';
+var disqus_identifier = 'cache/posts/.html';
+
+(function() {
+    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+    dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
+    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+})();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
+
+	</section>
+</article>
+</main>
+
+
+	<footer id="footer" role="contentinfo">
+		<p>
+		<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_US">
+			<img alt="CC-BY-SA" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/80x15.png">
+		</a> &copy; 2015 Thomas Dy - Powered by <a href="http://gohugo.io">Hugo</a></p>
+	</footer>
+</div>
+
+<script src="/assets/js/konami.js"></script>
+<script>
+var easter_egg = new Konami();
+easter_egg.code = function() {
+	var el = document.getElementById('thomas');
+	if(el.className == "whoa") {
+		el.className = "";
+	}
+	else {
+		el.className = "whoa";
+	}
+	document.body.scrollTop = document.documentElement.scrollTop = 0;
+}
+easter_egg.load();
+
+
+
+</script>
+
+
+
+</body>
+</html>
+

+ 169 - 33
output/posts/rss.xml

@@ -6,9 +6,177 @@
     <description>Recent content in Posts on Pleasant Programmer</description>
     <generator>Hugo -- gohugo.io</generator>
     <language>en-us</language>
-    <lastBuildDate>Fri, 24 Jun 2016 00:00:00 +0000</lastBuildDate>
+    <lastBuildDate>Sun, 15 Jan 2017 19:31:00 +0800</lastBuildDate>
     <atom:link href="http://pleasantprogrammer.com/posts/rss.xml" rel="self" type="application/rss+xml" />
     
+    <item>
+      <title>OpenPrepPad</title>
+      <link>http://pleasantprogrammer.com/posts/openpreppad.html</link>
+      <pubDate>Sun, 15 Jan 2017 19:31:00 +0800</pubDate>
+      
+      <guid>http://pleasantprogrammer.com/posts/openpreppad.html</guid>
+      <description>
+
+&lt;p&gt;Smart electronics and IoT (Internet of Things) are all the rage these days. You
+have a lot of companies sprout up trying to make the next big thing, which also
+leads to a lot of failures big and small. Pebble, the maker of my smartwatch,
+got bought out by Fitbit recently. This left watch owners without any official
+support, but thankfully, community members &lt;a href=&#34;http://rebble.io/&#34;&gt;stepped up&lt;/a&gt; to continue
+maintaining it.&lt;/p&gt;
+
+&lt;p&gt;Another casualty of the IoT boom was the &lt;a href=&#34;http://theorangechef.com/&#34;&gt;Orange Chef&lt;/a&gt; &lt;a href=&#34;https://www.amazon.com/Orange-Chef-Smart-Scale-Silver/dp/B00KFW8L90&#34;&gt;Prep Pad&lt;/a&gt;. It&amp;rsquo;s a
+bluetooth connected weighing scale to make it easy to track your calories and
+carb/fat/protein intake. My dad bought it last year only to find out that the
+app was incredibly buggy. The search function doesn&amp;rsquo;t work which makes the whole
+thing practically useless. I also found out later that you can&amp;rsquo;t even download
+the app to use the scale anymore.&lt;/p&gt;
+
+&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; I just found out as I was writing this post that it &lt;em&gt;may&lt;/em&gt; get supported
+by &lt;a href=&#34;http://www.prnewswire.com/news-releases/perfect-company-acquires-orange-chefs-prep-pad-related-ip-continues-momentum-in-the-connected-kitchen-300383178.html&#34;&gt;another company&lt;/a&gt;.&lt;/p&gt;
+
+&lt;p&gt;So the app is useless, but at least you can use it as a scale, right?&lt;/p&gt;
+
+&lt;p&gt;&lt;img src=&#34;http://pleasantprogrammer.com/galleries/openpreppad/preppad.jpg&#34; alt=&#34;Prep Pad&#34; /&gt;&lt;/p&gt;
+
+&lt;p&gt;Nope. The device has no display whatsoever. The only controls on it are the
+on/off button and a green LED that isn&amp;rsquo;t even that useful at telling you whether
+it&amp;rsquo;s on or not. At this point, it&amp;rsquo;s just a giant paperweight.&lt;/p&gt;
+
+&lt;h2 id=&#34;reverse-engineering&#34;&gt;Reverse Engineering&lt;/h2&gt;
+
+&lt;p&gt;Since I essentially had nothing to lose, I tried poking at the thing to figure
+out how it works. I didn&amp;rsquo;t really have experience with bluetooth besides trying
+to get my bluetooth mouse connected on Linux. The main thing I used then was
+&lt;code&gt;bluetoothctl&lt;/code&gt; which is essentially a CLI for managing bluetooth devices so I
+started there.&lt;/p&gt;
+
+&lt;p&gt;I started up &lt;code&gt;bluetoothctl&lt;/code&gt; and turned on the Prep Pad. And it showed up!&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[bluetooth]# power on
+[CHG] Controller ... Class: 0x00010c
+Changing power on succeeded
+[CHG] Controller ... Powered: yes
+[bluetooth]# scan on
+Discovery started
+[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I then connected to it, which was surprisingly easy.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[bluetooth]# connect 1C:BA:8C:21:7C:BB
+Attempting to connect to 1C:BA:8C:21:7C:BB
+[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;Now normally, when you turn the device on, the green light flashes occasionally.
+Once I connected to it, the green light stayed on permanently. Clearly, I was
+making progress. A lot of services were also discovered but I had no idea what
+those things were at that point.&lt;/p&gt;
+
+&lt;p&gt;After a lot of poking around, I could check the general device information.  You
+could get hardware, software and firmware version. There&amp;rsquo;s also the device
+serial number which was nowhere on the actual physical device.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CH BTScale_00:/service0010/char0017]# attribute-info
+Characteristic - Firmware Revision String
+	UUID: 00002a26-0000-1000-8000-00805f9b34fb
+	Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
+	Value: 0x31
+	Value: 0x2e
+	Value: 0x31
+	Value: 0x33
+	Value: 0x41
+	Value: 0x00
+	Flags: read
+[CH BTScale_00:/service0010/char0017]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
+  31 2e 31 33 41 00                                1.13A.
+[CH BTScale_00:/service0010/char0017]#
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;There was also a service which contained Accel Enable, Accel Range, Accel
+X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for
+accelerometer, which is probably what it uses to weigh things.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CH BTScale_00:/service0023/char0024/desc0026]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+  41 63 63 65 6c 20 45 6e 61 62 6c 65              Accel Enable
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I couldn&amp;rsquo;t read from any of the Accel Coordinates. It kept saying permission
+denied. I could however, notify on them. But that didn&amp;rsquo;t yield anything as well.
+What I &lt;em&gt;could&lt;/em&gt; read was Accel Enable, which was set to 00. I guess that means it
+was off. After writing 01 to Accel Enable, I found I could get values out of
+Accel X-Coordinate!&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# write 01
+Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
+[CH BTScale_00:/service0023/char002a]# notify on
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
+Notify started
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I tried pressing the scale down a few times, and the values changed accordingly.
+Now, I just had to figure out how to convert the values into grams. It looked
+like the values were 32-bit integers sent as 4 bytes. In the above example it
+would be &lt;code&gt;0x0002a35b&lt;/code&gt;, &lt;code&gt;0x0002a355&lt;/code&gt;, &lt;code&gt;0x0002a359&lt;/code&gt; or 172891, 172855, 172899. The
+values also decrease as you exert more effort on the scale. So assuming you have
+take the initial value as &lt;em&gt;tare&lt;/em&gt;, you simply subtract any succeeding from that
+&lt;em&gt;tare&lt;/em&gt; and you can have your &amp;ldquo;weight&amp;rdquo;.&lt;/p&gt;
+
+&lt;p&gt;The values I got didn&amp;rsquo;t seem to be grams though. After weighing some things on
+an actual scale and comparing the values I got, I found I can just divide the
+values by 14 and get something in grams. That 14 is entirely a magic number
+though and I have no idea whether other Prep Pad&amp;rsquo;s would have the same constant.&lt;/p&gt;
+
+&lt;h2 id=&#34;openpreppad&#34;&gt;OpenPrepPad&lt;/h2&gt;
+
+&lt;p&gt;With all that figured out, I went ahead and made a &lt;a href=&#34;https://github.com/thatsmydoing/openpreppad&#34;&gt;simple CLI application&lt;/a&gt;
+to interface with the Prep Pad. Ironically, node was the simplest thing I found
+that had &lt;a href=&#34;https://github.com/sandeepmistry/noble&#34;&gt;nice bluetooth library support&lt;/a&gt; so that&amp;rsquo;s what I wrote it in. I
+also added most of the technical details in the README for that as well.&lt;/p&gt;
+
+&lt;p&gt;While this is all well and cool, I doubt the intersection of Linux users and
+people who &lt;s&gt;got ripped off&lt;/s&gt; bought the Prep Pad is anyone besides me. In
+light of that, I&amp;rsquo;m in the process of making a React Native version of the app,
+but that&amp;rsquo;s still a work in progress. Who knows, if the new owners of Prep Pad
+are good, I might not even need to finish it.&lt;/p&gt;
+</description>
+    </item>
+    
     <item>
       <title>Haproxy Charset</title>
       <link>http://pleasantprogrammer.com/posts/haproxy-charset.html</link>
@@ -717,38 +885,6 @@ Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
 &lt;p&gt;GTFS Editor is very much in development. Just getting it to run was problematic. There also seem to be a lot of missing issues judging from the Github Issues page. If you want to try it out for yourself, I suggest you clone &lt;a href=&#34;https://github.com/thatsmydoing/gtfs-editor&#34;&gt;my branch&lt;/a&gt; as I&amp;rsquo;ve fixed the issues discussed earlier. The default login is &lt;code&gt;admin:admin&lt;/code&gt;.&lt;/p&gt;
 
 &lt;p&gt;Even after getting it to run, it&amp;rsquo;s still not quite usable. Not in the UX sense, but you really can&amp;rsquo;t do much with it. There is no way to import the GTFS data into the webapp. There is something like import from TransitWand but even that is unclear to me. And even if we do get that running as well, we still don&amp;rsquo;t have any data we can play around with. We would need database dumps from the already running tools for these to be of any use right now.&lt;/p&gt;
-</description>
-    </item>
-    
-    <item>
-      <title>One Bus (or maybe Jeep) Away</title>
-      <link>http://pleasantprogrammer.com/posts/one-bus-or-maybe-jeep-away.html</link>
-      <pubDate>Tue, 09 Jul 2013 00:00:00 +0000</pubDate>
-      
-      <guid>http://pleasantprogrammer.com/posts/one-bus-or-maybe-jeep-away.html</guid>
-      <description>&lt;p&gt;Link: &lt;a href=&#34;http://onebusaway.org/&#34;&gt;http://onebusaway.org/&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; no routing; useless in Philippines&lt;/p&gt;
-
-&lt;p&gt;OneBusAway is a transit information app. It provides data on what bus stops are near you, which buses pass by. You can also get schedules and the route of a particular bus given the number. It can also provide realtime updates like how many minutes until the next bus arrives. It does not, however, provide routing. There is no support for providing directions to get from point A to point B.&lt;/p&gt;
-
-&lt;p&gt;It&amp;rsquo;s comparable to what you get in some bus stops abroad. You&amp;rsquo;d get a vicinity map and a list of buses passing through the stop. You might also get the times when the next buses will pass. It&amp;rsquo;s useful for locals who already know how to get around, and want to avoid waiting for the bus. But it&amp;rsquo;s not particularly good for people who want to know how to get around the city.&lt;/p&gt;
-
-&lt;p&gt;OneBusAway is quite comprehensive in its platform support though. There is a webapp, apps for iOS, Android and Windows Phone, as well as SMS and Voice support. This would all be nice but we don&amp;rsquo;t have the necessary infrastructure yet in the Philippines. We don&amp;rsquo;t have bus or jeepney stops. We also wouldn&amp;rsquo;t have realtime data to make the app particularly useful.&lt;/p&gt;
-
-&lt;p&gt;You can try it out for yourself by following their &lt;a href=&#34;https://github.com/OneBusAway/onebusaway-application-modules/wiki/OneBusAway-Quickstart-Guide&#34;&gt;Quickstart Guide&lt;/a&gt;. One caveat is you will have to add &lt;code&gt;-P tripEntriesFactory.throwExceptionOnInvalidStopToShapeMappingException=false&lt;/code&gt; when building the bundle. This has to do with the OneBusAway having difficulty matching the &lt;a href=&#34;https://github.com/OneBusAway/onebusaway-application-modules/wiki/Stop-to-Shape-Matching&#34;&gt;stops to the shape data&lt;/a&gt;.&lt;/p&gt;
-
-&lt;p&gt;Here&amp;rsquo;s some screenshots of the app with the Philippine data. Notice how you only see the stops but there isn&amp;rsquo;t a line for the route. This is a problem with our GTFS data. Also, at some points it&amp;rsquo;s hard to tell where the jeep is going to pass since there isn&amp;rsquo;t any indication of order either. This is more of a OneBusAway problem. It usually expects there to be shape data available.&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway1.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway1.png&#34; alt=&#34;OneBusAway&#34; title=&#34;All the stops along Katipunan Avenue are named Katipunan Avenue.&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;It doesn&amp;rsquo;t really handle too many routes passing through a stop. The list just overflows past the bubble. You can still actually read it by panning the map. It&amp;rsquo;s just a bit weird though.&lt;/p&gt;
-
-&lt;p&gt;If you also noticed, there are usually 2 of each route. This is how the jeepney data was modeled as jeep routes might be different going one way and going back. This isn&amp;rsquo;t the case for all jeeps though, so it might also be an implementation issue with the GTFS editor.&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway2.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway2.png&#34; alt=&#34;OneBusAway&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway3.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway3.png&#34; alt=&#34;OneBusAway&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
 </description>
     </item>
     

+ 169 - 33
output/rss.xml

@@ -6,9 +6,177 @@
     <description>Recent content on Pleasant Programmer</description>
     <generator>Hugo -- gohugo.io</generator>
     <language>en-us</language>
-    <lastBuildDate>Fri, 24 Jun 2016 00:00:00 +0000</lastBuildDate>
+    <lastBuildDate>Sun, 15 Jan 2017 19:31:00 +0800</lastBuildDate>
     <atom:link href="http://pleasantprogrammer.com/rss.xml" rel="self" type="application/rss+xml" />
     
+    <item>
+      <title>OpenPrepPad</title>
+      <link>http://pleasantprogrammer.com/posts/openpreppad.html</link>
+      <pubDate>Sun, 15 Jan 2017 19:31:00 +0800</pubDate>
+      
+      <guid>http://pleasantprogrammer.com/posts/openpreppad.html</guid>
+      <description>
+
+&lt;p&gt;Smart electronics and IoT (Internet of Things) are all the rage these days. You
+have a lot of companies sprout up trying to make the next big thing, which also
+leads to a lot of failures big and small. Pebble, the maker of my smartwatch,
+got bought out by Fitbit recently. This left watch owners without any official
+support, but thankfully, community members &lt;a href=&#34;http://rebble.io/&#34;&gt;stepped up&lt;/a&gt; to continue
+maintaining it.&lt;/p&gt;
+
+&lt;p&gt;Another casualty of the IoT boom was the &lt;a href=&#34;http://theorangechef.com/&#34;&gt;Orange Chef&lt;/a&gt; &lt;a href=&#34;https://www.amazon.com/Orange-Chef-Smart-Scale-Silver/dp/B00KFW8L90&#34;&gt;Prep Pad&lt;/a&gt;. It&amp;rsquo;s a
+bluetooth connected weighing scale to make it easy to track your calories and
+carb/fat/protein intake. My dad bought it last year only to find out that the
+app was incredibly buggy. The search function doesn&amp;rsquo;t work which makes the whole
+thing practically useless. I also found out later that you can&amp;rsquo;t even download
+the app to use the scale anymore.&lt;/p&gt;
+
+&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; I just found out as I was writing this post that it &lt;em&gt;may&lt;/em&gt; get supported
+by &lt;a href=&#34;http://www.prnewswire.com/news-releases/perfect-company-acquires-orange-chefs-prep-pad-related-ip-continues-momentum-in-the-connected-kitchen-300383178.html&#34;&gt;another company&lt;/a&gt;.&lt;/p&gt;
+
+&lt;p&gt;So the app is useless, but at least you can use it as a scale, right?&lt;/p&gt;
+
+&lt;p&gt;&lt;img src=&#34;http://pleasantprogrammer.com/galleries/openpreppad/preppad.jpg&#34; alt=&#34;Prep Pad&#34; /&gt;&lt;/p&gt;
+
+&lt;p&gt;Nope. The device has no display whatsoever. The only controls on it are the
+on/off button and a green LED that isn&amp;rsquo;t even that useful at telling you whether
+it&amp;rsquo;s on or not. At this point, it&amp;rsquo;s just a giant paperweight.&lt;/p&gt;
+
+&lt;h2 id=&#34;reverse-engineering&#34;&gt;Reverse Engineering&lt;/h2&gt;
+
+&lt;p&gt;Since I essentially had nothing to lose, I tried poking at the thing to figure
+out how it works. I didn&amp;rsquo;t really have experience with bluetooth besides trying
+to get my bluetooth mouse connected on Linux. The main thing I used then was
+&lt;code&gt;bluetoothctl&lt;/code&gt; which is essentially a CLI for managing bluetooth devices so I
+started there.&lt;/p&gt;
+
+&lt;p&gt;I started up &lt;code&gt;bluetoothctl&lt;/code&gt; and turned on the Prep Pad. And it showed up!&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[bluetooth]# power on
+[CHG] Controller ... Class: 0x00010c
+Changing power on succeeded
+[CHG] Controller ... Powered: yes
+[bluetooth]# scan on
+Discovery started
+[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I then connected to it, which was surprisingly easy.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[bluetooth]# connect 1C:BA:8C:21:7C:BB
+Attempting to connect to 1C:BA:8C:21:7C:BB
+[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
+[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
+[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;Now normally, when you turn the device on, the green light flashes occasionally.
+Once I connected to it, the green light stayed on permanently. Clearly, I was
+making progress. A lot of services were also discovered but I had no idea what
+those things were at that point.&lt;/p&gt;
+
+&lt;p&gt;After a lot of poking around, I could check the general device information.  You
+could get hardware, software and firmware version. There&amp;rsquo;s also the device
+serial number which was nowhere on the actual physical device.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CH BTScale_00:/service0010/char0017]# attribute-info
+Characteristic - Firmware Revision String
+	UUID: 00002a26-0000-1000-8000-00805f9b34fb
+	Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
+	Value: 0x31
+	Value: 0x2e
+	Value: 0x31
+	Value: 0x33
+	Value: 0x41
+	Value: 0x00
+	Flags: read
+[CH BTScale_00:/service0010/char0017]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
+  31 2e 31 33 41 00                                1.13A.
+[CH BTScale_00:/service0010/char0017]#
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;There was also a service which contained Accel Enable, Accel Range, Accel
+X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for
+accelerometer, which is probably what it uses to weigh things.&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CH BTScale_00:/service0023/char0024/desc0026]# read
+Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
+  41 63 63 65 6c 20 45 6e 61 62 6c 65              Accel Enable
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I couldn&amp;rsquo;t read from any of the Accel Coordinates. It kept saying permission
+denied. I could however, notify on them. But that didn&amp;rsquo;t yield anything as well.
+What I &lt;em&gt;could&lt;/em&gt; read was Accel Enable, which was set to 00. I guess that means it
+was off. After writing 01 to Accel Enable, I found I could get values out of
+Accel X-Coordinate!&lt;/p&gt;
+&lt;div class=&#34;highlight&#34; style=&#34;background: #f8f8f8&#34;&gt;&lt;pre style=&#34;line-height: 125%&#34;&gt;&lt;span&gt;&lt;/span&gt;[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# write 01
+Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
+[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
+[CH BTScale_00:/service0023/char002a]# notify on
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
+Notify started
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
+[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
+&lt;/pre&gt;&lt;/div&gt;
+
+&lt;p&gt;I tried pressing the scale down a few times, and the values changed accordingly.
+Now, I just had to figure out how to convert the values into grams. It looked
+like the values were 32-bit integers sent as 4 bytes. In the above example it
+would be &lt;code&gt;0x0002a35b&lt;/code&gt;, &lt;code&gt;0x0002a355&lt;/code&gt;, &lt;code&gt;0x0002a359&lt;/code&gt; or 172891, 172855, 172899. The
+values also decrease as you exert more effort on the scale. So assuming you have
+take the initial value as &lt;em&gt;tare&lt;/em&gt;, you simply subtract any succeeding from that
+&lt;em&gt;tare&lt;/em&gt; and you can have your &amp;ldquo;weight&amp;rdquo;.&lt;/p&gt;
+
+&lt;p&gt;The values I got didn&amp;rsquo;t seem to be grams though. After weighing some things on
+an actual scale and comparing the values I got, I found I can just divide the
+values by 14 and get something in grams. That 14 is entirely a magic number
+though and I have no idea whether other Prep Pad&amp;rsquo;s would have the same constant.&lt;/p&gt;
+
+&lt;h2 id=&#34;openpreppad&#34;&gt;OpenPrepPad&lt;/h2&gt;
+
+&lt;p&gt;With all that figured out, I went ahead and made a &lt;a href=&#34;https://github.com/thatsmydoing/openpreppad&#34;&gt;simple CLI application&lt;/a&gt;
+to interface with the Prep Pad. Ironically, node was the simplest thing I found
+that had &lt;a href=&#34;https://github.com/sandeepmistry/noble&#34;&gt;nice bluetooth library support&lt;/a&gt; so that&amp;rsquo;s what I wrote it in. I
+also added most of the technical details in the README for that as well.&lt;/p&gt;
+
+&lt;p&gt;While this is all well and cool, I doubt the intersection of Linux users and
+people who &lt;s&gt;got ripped off&lt;/s&gt; bought the Prep Pad is anyone besides me. In
+light of that, I&amp;rsquo;m in the process of making a React Native version of the app,
+but that&amp;rsquo;s still a work in progress. Who knows, if the new owners of Prep Pad
+are good, I might not even need to finish it.&lt;/p&gt;
+</description>
+    </item>
+    
     <item>
       <title>Haproxy Charset</title>
       <link>http://pleasantprogrammer.com/posts/haproxy-charset.html</link>
@@ -717,38 +885,6 @@ Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
 &lt;p&gt;GTFS Editor is very much in development. Just getting it to run was problematic. There also seem to be a lot of missing issues judging from the Github Issues page. If you want to try it out for yourself, I suggest you clone &lt;a href=&#34;https://github.com/thatsmydoing/gtfs-editor&#34;&gt;my branch&lt;/a&gt; as I&amp;rsquo;ve fixed the issues discussed earlier. The default login is &lt;code&gt;admin:admin&lt;/code&gt;.&lt;/p&gt;
 
 &lt;p&gt;Even after getting it to run, it&amp;rsquo;s still not quite usable. Not in the UX sense, but you really can&amp;rsquo;t do much with it. There is no way to import the GTFS data into the webapp. There is something like import from TransitWand but even that is unclear to me. And even if we do get that running as well, we still don&amp;rsquo;t have any data we can play around with. We would need database dumps from the already running tools for these to be of any use right now.&lt;/p&gt;
-</description>
-    </item>
-    
-    <item>
-      <title>One Bus (or maybe Jeep) Away</title>
-      <link>http://pleasantprogrammer.com/posts/one-bus-or-maybe-jeep-away.html</link>
-      <pubDate>Tue, 09 Jul 2013 00:00:00 +0000</pubDate>
-      
-      <guid>http://pleasantprogrammer.com/posts/one-bus-or-maybe-jeep-away.html</guid>
-      <description>&lt;p&gt;Link: &lt;a href=&#34;http://onebusaway.org/&#34;&gt;http://onebusaway.org/&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; no routing; useless in Philippines&lt;/p&gt;
-
-&lt;p&gt;OneBusAway is a transit information app. It provides data on what bus stops are near you, which buses pass by. You can also get schedules and the route of a particular bus given the number. It can also provide realtime updates like how many minutes until the next bus arrives. It does not, however, provide routing. There is no support for providing directions to get from point A to point B.&lt;/p&gt;
-
-&lt;p&gt;It&amp;rsquo;s comparable to what you get in some bus stops abroad. You&amp;rsquo;d get a vicinity map and a list of buses passing through the stop. You might also get the times when the next buses will pass. It&amp;rsquo;s useful for locals who already know how to get around, and want to avoid waiting for the bus. But it&amp;rsquo;s not particularly good for people who want to know how to get around the city.&lt;/p&gt;
-
-&lt;p&gt;OneBusAway is quite comprehensive in its platform support though. There is a webapp, apps for iOS, Android and Windows Phone, as well as SMS and Voice support. This would all be nice but we don&amp;rsquo;t have the necessary infrastructure yet in the Philippines. We don&amp;rsquo;t have bus or jeepney stops. We also wouldn&amp;rsquo;t have realtime data to make the app particularly useful.&lt;/p&gt;
-
-&lt;p&gt;You can try it out for yourself by following their &lt;a href=&#34;https://github.com/OneBusAway/onebusaway-application-modules/wiki/OneBusAway-Quickstart-Guide&#34;&gt;Quickstart Guide&lt;/a&gt;. One caveat is you will have to add &lt;code&gt;-P tripEntriesFactory.throwExceptionOnInvalidStopToShapeMappingException=false&lt;/code&gt; when building the bundle. This has to do with the OneBusAway having difficulty matching the &lt;a href=&#34;https://github.com/OneBusAway/onebusaway-application-modules/wiki/Stop-to-Shape-Matching&#34;&gt;stops to the shape data&lt;/a&gt;.&lt;/p&gt;
-
-&lt;p&gt;Here&amp;rsquo;s some screenshots of the app with the Philippine data. Notice how you only see the stops but there isn&amp;rsquo;t a line for the route. This is a problem with our GTFS data. Also, at some points it&amp;rsquo;s hard to tell where the jeep is going to pass since there isn&amp;rsquo;t any indication of order either. This is more of a OneBusAway problem. It usually expects there to be shape data available.&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway1.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway1.png&#34; alt=&#34;OneBusAway&#34; title=&#34;All the stops along Katipunan Avenue are named Katipunan Avenue.&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;It doesn&amp;rsquo;t really handle too many routes passing through a stop. The list just overflows past the bubble. You can still actually read it by panning the map. It&amp;rsquo;s just a bit weird though.&lt;/p&gt;
-
-&lt;p&gt;If you also noticed, there are usually 2 of each route. This is how the jeepney data was modeled as jeep routes might be different going one way and going back. This isn&amp;rsquo;t the case for all jeeps though, so it might also be an implementation issue with the GTFS editor.&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway2.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway2.png&#34; alt=&#34;OneBusAway&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;a href=&#34;../galleries/transit/onebusaway3.png&#34;&gt;&lt;img src=&#34;../galleries/transit/onebusaway3.png&#34; alt=&#34;OneBusAway&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
 </description>
     </item>
     

+ 19 - 2
output/sitemap.xml

@@ -1,6 +1,11 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   
+  <url>
+    <loc>http://pleasantprogrammer.com/posts/openpreppad.html</loc>
+    <lastmod>2017-01-15T19:31:00+08:00</lastmod>
+  </url>
+  
   <url>
     <loc>http://pleasantprogrammer.com/posts/haproxy-charset.html</loc>
     <lastmod>2016-06-24T00:00:00+00:00</lastmod>
@@ -91,6 +96,12 @@
     <lastmod>2013-07-07T00:00:00+00:00</lastmod>
   </url>
   
+  <url>
+    <loc>http://pleasantprogrammer.com/tags/bluetooth.html</loc>
+    <lastmod>2017-01-15T19:31:00+08:00</lastmod>
+    <priority>0</priority>
+  </url>
+  
   <url>
     <loc>http://pleasantprogrammer.com/tags/cloudflare.html</loc>
     <lastmod>2015-12-25T00:00:00+00:00</lastmod>
@@ -103,6 +114,12 @@
     <priority>0</priority>
   </url>
   
+  <url>
+    <loc>http://pleasantprogrammer.com/tags/hardware.html</loc>
+    <lastmod>2017-01-15T19:31:00+08:00</lastmod>
+    <priority>0</priority>
+  </url>
+  
   <url>
     <loc>http://pleasantprogrammer.com/tags/lets-debug.html</loc>
     <lastmod>2013-07-10T00:00:00+00:00</lastmod>
@@ -117,13 +134,13 @@
   
   <url>
     <loc>http://pleasantprogrammer.com/</loc>
-    <lastmod>2016-06-24T00:00:00+00:00</lastmod>
+    <lastmod>2017-01-15T19:31:00+08:00</lastmod>
     <priority>0</priority>
   </url>
   
   <url>
     <loc>http://pleasantprogrammer.com/posts.html</loc>
-    <lastmod>2016-06-24T00:00:00+00:00</lastmod>
+    <lastmod>2017-01-15T19:31:00+08:00</lastmod>
     <priority>0</priority>
   </url>
   

+ 4 - 0
output/tags.html

@@ -41,10 +41,14 @@
 	<ul class="postlist">
 		
 		
+		<li><a class="reference listtitle" href="/tags/bluetooth.html">bluetooth</a> (1)</li>
+		
 		<li><a class="reference listtitle" href="/tags/cloudflare.html">cloudflare</a> (1)</li>
 		
 		<li><a class="reference listtitle" href="/tags/haproxy.html">haproxy</a> (1)</li>
 		
+		<li><a class="reference listtitle" href="/tags/hardware.html">hardware</a> (1)</li>
+		
 		<li><a class="reference listtitle" href="/tags/lets-debug.html">lets-debug</a> (1)</li>
 		
 		<li><a class="reference listtitle" href="/tags/philippine-transit-app.html">philippine-transit-app</a> (12)</li>

BIN
static/galleries/openpreppad/preppad.jpg