Daniel's Weblog
Posts Tags Colophon
About

Tags / Posts

Pens, Pencils, and Paper Products in NYC

Dec 10, 2018


Need more pens, paper, and other writing products? Me neither, but I’m going to buy some anyways.

MUJI Fifth Avenue

My preferred Muji location is right across the street from Bryant Park and the New York Public Library (Which is also worth visiting either for books or to reenact Ghostbusters). They also have other locations throughout the city including Hudson Yards.

Google Maps describes Muji as “Minimalist Japanese retailer with a wide range of generic products, including apparel & home goods.” which is not technically wrong, but disregards their offerings of pens, mechanical pencils, and unbleached paper products (envelopes, pads of paper, sticky notes, etc.). None of their products are branded.

At their door is a table full of ink stamps where you can personalize your new notebook or an envelope you’re about to send to someone.

Of particular note are their following items:

  • Capped Gel Ink pens

    Wide range of covers, comfortable to hold and come in multiple sizes. Good for every day writing and note taking. Like most gel pens they will smudge on glossy surfaces, and not very water resistant. The pens can be bought individually or as a set.

  • Envelopes

    Okay, they’re really just envelopes. But they’re made out of kraft paper which makes them stand out and feel special.

  • Aluminum Round Fountain Pen

    This is probably the most expensive pen in the store, but it’s pretty inexpensive as fountain pens go. If you’re looking to dip your toes in the world of fountain pens this is a good way to start. Muji only sells black ink cartridges for this pen, but elsewhere you can buy convertors (like at Goods for the Study Mullberry detailed later) that allow you to refill it with whatever ink you like.

Stationary products are on the ground level, household goods, clothing, and more can be found in the basement. Muji products can also be ordered online on their website.

Casey Rubber Stamps

On East 11th Street between First and Second Avenues is a tiny store almost overflowing with rubber stamps. They’re more expensive than the stamps you’d find at your local craft store the broad selection is incredible. See something in the catalog that isn’t on the shelf? Wait 10 minutes and they’ll assemble it for you. Need custom stamps? They can do that too.

As the brochure says, “All of our equipment is state of the art circa 1955”. You can also order online from their website.

Kinokuniya New York

While Muji is restrained and spacious, Kinokuniya Books is doing their best to use every single square foot. On ground floor is a great collection of art, architecture, and design books. Upstairs is a Japanese cafe, manga, anime, and some western comic books too. In the basement is a huge collection of Japanese literature. I can’t read Japanese, but the way the series are color coordinated on the shelves is incredibly satisfying.

But we’re here to talk about pens, and a quarter of the basement is dedicated to pens, pencils, and decorative cards. Unlike Muji they don’t produce their own products, but if you need to restock your supply of Marvey LePen or pick up some more Blackwing pencils this store is conveniently located.

Goods for the Study Mullberry

Leaving midtown and heading south takes us to Goods for the Study Mulberry which is under the same ownership as McNally Jackson Books just around the corner. This store is split between two adjacent storefronts. On the right is notebooks, paperclips in the shape of animals, pen cases, paperweights, rulers, and more.

The store on the left is a more interactive experience. Jars of pens and mechanical pencils fill the walls and you’re invited to try them out. It’s a bit reminiscent of the Ollivander’s Wand Store in Harry Potter. If you’re searching for the perfect writing utensil this is the place to go.

Fountain pens and jars of ink are available here too. This in fact is where I bought a converter for my Muji fountain pen.

CW Pencil Enterprise

CW Pencil Enterprise takes a different approach from Goods for the Study. Instead of having many options, they have a small, carefully curated selection of pencils. If your idea of a writing utensil is a piece of wood with graphite in the middle, this is the place to visit.

Bowne Printers

Part of the Seaport museum, this is another store in two parts, Bowne and Co. Stationers has my favorite NYC-themed postcard designs. Right next door is Bowne Printers which is a 19th print shop selling cards and prints made there. They can also be commissioned for business cards and other prints.

Places I have not yet visited


Nov 27, 2018


Temperature Sensors Part 4: PCBs and Programming

This is post number 4 in a series describing my DIY temperature and humidity sensors.

Printed Circuit Boards

For the past month my two prototype sensors have been dutifully reporting the temperature and humidity in my house with any complaint. At this point I want to get a PCB made to make assembly easier. I’ve never done any serious board layout, but learn.sparkfun.com has an well-written, two-part tutorial called Using EAGLE.

This is what I came up with after an evening of work:

I decided to order the boards from OSH Park who are charging me a grand total of $7.35 for three boards (with free shipping!).

These differ from my hand-made prototypes in two ways:

  1. I’ve added a three holes on the board (labeled J3) for easy access to VCC, 3.3V, and GND
  2. There’s a button! More on that in the next section

Programming Changes

Up to this point all of the sensor’s settings have been hard-coded in the program. If I wanted to change a sensor’s name, it’s recording interval, or the InfluxDB server it reported to I had to change the program and re-flash the ESP8266 with the new version.

This process entails the following:

  1. Remove ESP8266 from sensor and place on breadboard
  2. Attach FTDI breakout to the breadboard
  3. Connect FTDI and ESP8266 together going through a level shifter
  4. Make changes to program
  5. Flash the new program to ESP8266
  6. Put ESP8266 back in sensor

I made a jig to make this process easier, but it’s a pain, and if you need an FTDI breakout to program this sensor it drives the cost up even more at $15.95 for the FTDI breakout (you could also use an Arduino UNO with the ATMEGA removed, but that’s even more of a pain) and $2.95 for a logic level converter .

This is where the button comes in. If you hold the button down while plugging the sensor in it will enter configuration mode. In this mode the sensor acts as a Wi-Fi hotspot and broadcasts a network called “Sensor Setup”. Navigating to 192.168.4.1 provides configuration options.

These settings are saved in the ESP8266’s flash memory so they persist across power cycles. To leave the configuration mode, simply unplug the sensor and plug it back in again.

“But wait!” you cry, “doesn’t the ESP8266 only have two GPIO pins in this configuration? And you’re using them both for I2C to communicate with the sensor!” And in fact you’re right, only two pins are dedicated to GPIO in this configuration… but the RX and TX pins can be repurposed as GPIO pins. Check out how on Stack Overflow.

The full code can be found on Github


Nov 9, 2018


Do you like planes? Do you ever wish you could… track them? This guide will cover setting up your Raspberry Pi as an ADSB feeder and sending the data to various aggregators.

I’m going to be using a Raspberry Pi model 1B+, but the instructions should work for other Raspberry Pi boards and possibily other Debian systems as well.

What you need

  • A single-board computer with a good power supply. I’m using a Raspberry Pi 1B+
  • A monitor for said-computer and a keyboard
    • Alternatively you can turn on SSH by default and then do everything remotely, but I’m not going to cover that here
  • A RTL-SDR dongle and antenna. RTL-SDR.com has good kits.
  • An internet connection for said single-board computer
  • A clear view of the sky through a window

Part #1: Set up Raspbian

  1. Let’s start with a clean install of Raspbian Lite. Follow the instructions in the official guide.

    • As of this writing, the most recent version is Raspbian Stretch.
  2. Boot it up for the first time and login!

    • In case you forgot, the default username is “pi” and the password is “raspberry”
  3. Drop in to the configuration utility with sudo raspi-config and lets go through some defaults to make life better(tm)

    • Change the user password. THIS IS NON-NEGOTIABLE. You are not allowed to read the rest of this guide unless you change the password.
    • Change the hostname in Network Options > Hostname
    • Set up Wi-Fi *(if applicapable) in Network Options > Wi-Fi
    • Turn on SSH in Interfacing Options > SSH
    • Change your locale in Localisation Options > Change Locale
      • As an American, I select en_US.UTF-8 here and then select it again when asked what should be the default. I don’t find myself using the Euro or Pound symbol on my ADSB feeders :-)
    • Set your keyboard to the appropriate layout in Localization Options > Change Keyboard Layout
      • I use “Generic 105-key (Intel) PC” and “English US”. To change from “English UK” you have to select “other” and then it will give you a greater list of options.
      • Unless you know you have an AltGr key, just say “The default for the keyboard layout”
      • And again, unless you know better just choose “No compose key”
    • When you’re done select Finish and let it reboot when prompted.
  4. Now that we’re back from the reboot, test your network connection! ping 8.8.8.8 It’s OK, Google’s DNS servers can take it.

  5. Time to update and upgrade. While you’re waiting you can read about the difference here

    • sudo apt-get update
    • sudo apt-get upgrade
    • If you don’t want to deal with those pesky prompts, you can add the flag -y (which stands for “YES”) to each command like sudo apt-get update -y
  6. Install git with sudo apt-get install git

    • I am going to take this time to also install a few other programs I like, including vim, screen, and sl which displays a steam locomotive everytime you misspell the command ls.

Part #2: Set up ADSB!

Part 2-A: FlightAware

The company Flightaware provides free enterprise accounts for anyone who feeds ADSB data to them and also maintains the most recent version of the dump1090 software, so we’ll start with them.

There are two pieces of software you need to know about:

Dump1090 is the software that actually interacts with the RTL-SDR dongle and interprets the ADSB data. The “1090” part of it’s name refers to the frequency 1090 MHz which ADSB runs on. More details about that can be found on the Cincinnati Avionics webpage.

PiAware is FlightAware’s custom software that sends them the data Dump1090 produces, does multilateration (more on that in Step #6 below), and a few other nifty features.

Instructions:

  1. Register for a FlightAware account
  2. Plug in your RTL-SDR dongle if it wasn’t already (again, if your Pi reboots when you do that you probably need a better power supply!)
  3. Follow their instructions
  4. Claim your receiver at flightaware.com/adsb/piaware/claim
    • This works by comparing your web browser’s IP address with the IP address of the new transmitter. Make sure you’re on the same network.
    • Sometimes it takes a few minutes for the new feeder to appear
  5. Refresh the page and you should see that your account should have been automatically upgraded to an Enterprise Account. A new link should appear in the top left of the screen saying “My ADSB”. Click on it!
  6. Find the gear icon on the right hand side of the screen and click on it, then click on the “Configure Location” and “Configure Height” buttons, set those values appropriately, and press “save”.

If the planes are reporting their location over ADS-B why does FA need to know the receiver’s location? Planes without ADS-B transponders do not report their location… but FA can estimate their location using multilateration. They have an more in-depth description of the functionality on this webpage 7. That’s it! Congratulations, you are now feeding to FlightAware.

What can you do with this:

  • PiAware has an interface you can view directly from your Raspberry Pi! Navigate to http://192.168.1.200:8080 (substitute in your own IP address) to see it.
  • You can see stats about your feeder on FlightAware.com/adsb/stats/user/YourUsername
  • If you click on the gear icon like we did in step #6, you can remotly update and reboot your device.

https://discussions.flightaware.com/t/bake-a-pi/19886/5

Railway Logos and the Marching 97

Nov 5, 2018


There’s something magnetic about classic railway logos and graphics, they’re bright, they’re clean, they’re bold, and many have been around for decades!

Once upon a time Lehigh University’s unofficial mascot was the “Engineers”. There’s some debate whether this refers to the school’s engineering program or the Lehigh Valley Railroad which passed through Bethlehem and founder Asa Packer was heavily involved with.

Despite a 1995 decision to change the university mascot to the “Mountain Hawk” Lehigh’s band, the Marching 97, stands by the train engineer definition and still wears shirts with locomotives under their uniform.

I’ve made a couple railway-inspired logos for the band. As manager in fall of 2017 I gave out Union Pacific inspired pins at band camp (please don’t sue me, UP).

This year for Alumni Band Day (Nov. 8th) I was itching to make something– I hadn’t even opened up Photoshop since the yearbook was finished in August! Drawing inspiration from the Delaware and Hudson Railway, this graphic is probably more lawsuit-safe as the Lehigh Valley railroad was bought in 1976 (please don’t sue me, Conrail).

One other graphic I’ve been working on since before the 2018 London Trip is a riff on the Chicago NorthWestern logo. It won’t fit on a button as well as the other logos, but maybe it’ll exist as a sticker someday?

Notes

  • I keep an album on Flickr solely of railway graphics I come across. Many of these photos were taken at the Whippany Railroad Museum in Whippany, NJ, which has an excellent collection of exhibits and equipment! The uncredited photos in this post were taken there.
  • If you’re looking for more train-based graphic design inspiration, Reagan Ray has a wonderful collection of good, clean, scans of railway logos on his website.
  • Christian Annyas has written a fascinating blog post on the evolution of these graphics.

Oct 31, 2018


Temperature Sensors Part 3: Sensor Hardware

This is post number 3 in a series describing my DIY temperature and humidity sensors.

The Sensor:

Profile view of the sensor

Hardware Breakdown:

The sensors themselves are pretty simple, consisting of only five components.

Not including solder, various lengths of wire, and the perf board that the components are mounted on. I used a Sparkfun Snappable Protoboard ($7.95) as the base for each of my sensors.

  1. ESP8266 WiFi Module ($6.95)
  2. Si7021 Humidity and Temperature Breakout Board ($7.95)
  3. LD1117V33 Voltage Regulator ($1.95)
  4. USB Type A plug ($1.50)

Total cost before tax: $18.35

Prices given are from Sparkfun as of September, 2018

Design Choices:

The goal was a sub-twenty dollar, reasonably accurate temperature sensor that I could place anywhere in my house and forget about.

Data Transmission

I want to store this data in InfluxDB (Detailed in Part I) so I can visualize it in Grafana (Detailed in Part II).

My house isn’t wired for Ethernet– if it was I could solve both the transmission and power problems with Power over Ethernet.

In the past I’ve worked with the Nordic NRF24L01+ radios which are reasonabley priced and have decent range, but I would need some sort of relay that could receive the wireless transmission and send it over TCP/IP to the InfluxDB. Someone has done this, but it seems like extra work when I already have a Wi-Fi network in my house.

So I went with the ESP-8266 Wi-Fi module because I had two laying around. Future iterations may use a different version of the chip.

Power

Some impressive work has been done making the ESP8266 run on batteries for a very long time, but batteries eveuntally need charging or changing.

What I do have lying around though, is a bunch of USB wall chargers that can put out 5V and more than enough amperage which, using a LD1117, can be converted from 5V into the 3.3V that the ESP-8266 and sensor need. The ESP-8266 only consumes 170mA tops and the Si7021 sensor uses all of 150 μA, so the LD1117’s max of 800mA is overkill, but hey, I majored in Computer Science and it seems like a good solution to me.

In summary 120V AC power comes out of the wall, gets converted to 5V DC by the USB wall charger, which the sensor is plugged in to. Onboard the circuit board the voltage is dropped again to 3.3V which the radio and the sensor can use.

Right now I’m only using the USB power and ground lines, but I dream of being able to fit some sort of USB Serial Adapter and a logic level converter so that the ESP-8266 can be programmed directly from the USB port. At the moment it’s a bit of a pain to change Wi-Fi networks, I have to remove the ESP8266, and plug it into a jig to reprogram it.

In Action

One issue is that a lot of stress can be put on the pins connecting the USB port to the sensor board.


Oct 29, 2018


Temperature Sensors Part 2: Grafana

Recording temperature into InfluxDB isn’t very useful if I can’t visualize it. Thanksfully, Grafana exists.

This is part 2 in a series describing my DIY temperature and humidity sensors.

Grafana Setup

I have Grafana running on the same webserver as this website, configured with two different data sources:

  1. My InfluxDB server (Currently a Raspberry Pi)
  2. The DarkySky.net plugin for an approximate idea of the outside temperature (Plotted as apparentTemperature on the graph below)

Records:

  • The recorded temperature in my room was 56.09°F on October 19th at 8 AM. Later that day the heat was turned on
  • Since the heat has been turned on:
    • Living room:
      • Max Low: 67°F
      • Max High: 68.34°F
    • My Room:
      • Max Low: 36.65°F
      • Max High: 75.02°F

Takeaways

  • My third floor room is colder than the second floor living room directly below by about 5-7°F on average.
  • Turning on the living room ceiling fan lowers the living room temperature, but does not change the temperature in my room.

Actual Graphs

Below is a “snapshot” of the data my temperature sensors collected between Oct 22nd and Oct 29th, 2018. To make it load quickly I’ve set the resolution to 30 minutes (each point on this plot is the average of the past 30 minutes).

Temperature Graph (Direct)

I’m also collecting relative humidity data:

Relative Humidity Graph (Direct)


Oct 19, 2018


Temperature Sensors Part 1: Influx DB

This is part 1 in a series describing my DIY temperature and humidity sensors.

I built some temperature and humidity sensors based on ESP8266 Wi-Fi modules for house so I know just how cold I am at any given moment. This details the settings on the InfluxDB server that stores everything. I made package this up in to a little library (Github) to make things easier.

InfluxDB

Each sensor has it’s own measurement (the name of the room they’re located in) and updates the database multiple times per minute. This is excessive, but I forgot about it and it’s a bit of pain to reprogram them.

name: DanielsRoom
time                           fahrenheit host                 region  relative_humidity
----                           ---------- ----                 ------  -----------------
2018-10-20T00:00:02.328505836Z            esp8266-DanielsRoom1 us-east 0.547224
2018-10-20T00:00:03.528801987Z 72.574486  esp8266-DanielsRoom1 us-east 
2018-10-20T00:00:03.768001235Z            esp8266-DanielsRoom1 us-east 0.547147
2018-10-20T00:00:04.687234974Z 72.574486  esp8266-DanielsRoom1 us-east 
name: LivingRoom
time                           fahrenheit host                region  relative_humidity
----                           ---------- ----                ------  -----------------
2018-10-20T00:00:02.643783571Z 72.207687  esp8266-LivingRoom1 us-east 
2018-10-20T00:00:03.048582528Z            esp8266-LivingRoom1 us-east 0.504728
2018-10-20T00:00:03.79192576Z  72.188385  esp8266-LivingRoom1 us-east 
2018-10-20T00:00:04.052576581Z            esp8266-LivingRoom1 us-east 0.504651

LivingRoom and DanielsRoom belong to a retention policy called two_hours which stores the data points for… two hours!

name      duration shardGroupDuration replicaN default
----      -------- ------------------ -------- -------
autogen   0s       168h0m0s           1        false
two_hours 2h0m0s   1h0m0s             1        true
forever   0s       168h0m0s           1        false

Long before the two hour time limit is up a continuous query runs and calculates the average sensor value for the past minute and stores it in the forever retention policy which keeps it forever.

name: 
name                               query
----                               -----
cq_1m_danielsroom_humidity         CREATE CONTINUOUS QUERY cq_1m_danielsroom_humidity ON  BEGIN SELECT mean(relative_humidity) AS mean_relative_humidity INTO HouseholdDatabase.forever.danielsroom_relative_humidity FROM HouseholdDatabase.two_hours.DanielsRoom GROUP BY time(1m) END
cq_1m_danielsroom_fahrenheit       CREATE CONTINUOUS QUERY cq_1m_danielsroom_fahrenheit ON  BEGIN SELECT mean(fahrenheit) AS mean_fahrenheit INTO HouseholdDatabase.forever.danielsroom_fahrenheit FROM HouseholdDatabase.two_hours.DanielsRoom GROUP BY time(1m) END
cq_1m_livingroom_fahrenheit        CREATE CONTINUOUS QUERY cq_1m_livingroom_fahrenheit ON  BEGIN SELECT mean(fahrenheit) AS mean_fahrenheit INTO HouseholdDatabase.forever.livingroom_fahrenheit FROM HouseholdDatabase.two_hours.LivingRoom GROUP BY time(1m) END
cq_1m_livingroom_relative_humidity CREATE CONTINUOUS QUERY cq_1m_livingroom_relative_humidity ON  BEGIN SELECT mean(relative_humidity) AS mean_relative_humidity INTO HouseholdDatabase.forever.livingroom_relative_humidity FROM HouseholdDatabase.two_hours.LivingRoom GROUP BY time(1m) END
Self-Hosting Gitea

Oct 9, 2018


Since I graduated my student discount expired and I don’t want to pay $7 a month to Github for private repositories. So time to take Gitea for a whirl.

  1. Install from the binary
  2. Set up the service
    One minor change here, since I’m running Grafana on port 3000 already I’m going to run Gitea on port 4000 by doing modifying the following line:
ExecStart=/usr/local/bin/gitea web -p 4000 -c /etc/gitea/app.ini
  1. Add a proxy pass rule for Apache:
    /etc/apache2/sites-enabled/danielbeadle.net.conf
ProxyPass /git http://localhost:4000
  1. Set the root_url for Gitea /etc/gitea/app.ini
ROOT_URL = https://danielbeadle.net/git/
  1. Navigate to the install page https://danielbeadle.net/git/install
  • Database type: SQLite3
  • Path: /home/git/gitea/data/gitea.db
  • Repo Root Path: /home/git/gitea-repositories
  • Run as Username: git
  • ssh Server domain: danielbeadle.net

Update as of November, 2018: I have migrated all of my private repositories (including the one this website is tracked with) over to Gitea and it is working wonderfully. In was as simple as cloning my private repos from Github, initalizing a new repo in Gitea, changing the remote, and pushing.

Angular Recipes

Jul 29, 2018


Or: things I have implemented multiple times while developing in Angular 2 / Angular 6. Mostly for my own reference, but if it helsp someone else, great. This is a living post that I will add to and edit as I continue to develop in Angular without necessarily timestamping changes.

<a [routerLink]="['/interface-client']">All Clients</a> > <a [routerLink]="['/interface-client/', id]">{{ client.name }}</a>

Display Scrollbar while Bootstrap Modal is open

.modal-open
{
  overflow-y: scroll;
}

Source

Monitor how Bootstrap Modal was closed from parent

parent.component.ts

openModal() {
  const modalRef = this.modalService.open(ConfirmModalComponent); // Open modal
  modalRef.componentInstance.model = this.model; // Pass object to modal

  // Change the variable submitted based on how the modal was closed
  modalRef.result.then(value => { this.submitted = value === 'submitted' ? true : false; });
}

confirm-modal.component.ts:

onSubmit() {
  this.dataService.newApp(this.model);
  this.activeModal.close('submitted');
}

onCancel() {
  this.activeModal.close('canceled');
}

Dynamically Change Dropdown Contents (Angular Forms)

Say I have two dropdown elements in the form of select tags, one with id “species” and the other with id “name”. I want the available names to change based on the species currently selected, and I never want either dropdown to be blank.

More good advice: KastePanyan24 on Medium

Here is a working example on stackblitz.

app.component.html

<h3>INPUT:</h3>

<form *ngIf="formReady === true">
  <div class="form-group">
    <label for="species">Species: </label>
    <select class="form-control"
            id="species"
            (change)="onChange($event.target.value)"
            [(ngModel)]="model.species"
            name="f_species">
      <option *ngFor="let species_singular of species" [value]="species_singular">
        {{ species_singular }}
    </select>
  </div>

  <div class="form-group">
    <label for="name">Name: </label>
    <select class="form-control"
            id="name"
            [(ngModel)]="model.name"
            name="f_name">
      <option *ngFor="let name of appropriateNames" [value]="name.name">
        {{ name.name }}
    </select>
  </div>
</form>

<h3>OUTPUT:</h3>
<pre>{{ model.species }}, {{ model.name }}</pre>

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  /* The model the form begins with. */
  model = { species: 'cat', name: 'spot' }

  /* Our data */
  species: string[] = ['cat', 'dog'];
  names = [
    { species: 'cat', name: 'smokey' },
    { species: 'cat', name: 'spot' },
    { species: 'dog', name: 'kobe' },
    { species: 'dog', name: 'cheddar' }
  ];

  /* The names allowed to be used with the currently selected species */
  appropriateNames;

  /* Delay rendering of the form until appropriateName has been populated.
   * Without this the name dropdown is empty until the species is changed, which
   * is rather inconvenient if you want to use the first species in the dropdown */
  formReady: boolean = false; 

  ngOnInit()
  {
    /* Run the change event handler on page load to populate appropriateNames
     * variable and the name dropdown */
    this.onChange(this.model.species);
    this.formReady = true;
  }

  /**
   * Runs every time the species drop down is changed and populates
   * the name dropdown with the names available for that species.
   * 
   * @param species The species currently selected
   */
  onChange(species: string) {
    console.log('selected species: ', species);

    /* Everytime the dropdown changes the name array is iterated through. 
     * With large arrays this could slow things down, but I haven't had any 
     * issues with small arrays */
    this.appropriateNames= this.names.filter(obj => {
      return obj.species === species;
    });

    /* Change the name dropdown to the first item in the appropriateName array */
    this.model.name = this.appropriateNames[0].name;

    console.log(this.appropriateNames);
  }
}

Ng2-Smart-Table is a great library. Unfortunately, linking inside of a cell is a little difficult. I wanted to use [routerLink] inside the cell, but Angular kept sanitizing it.

To use [routerLink] inside of a cell, create a sub-component.

The table variables look like this:

// Table Stuff
private values = [];
source: LocalDataSource;
settings = {
  actions: {
    add: false,
    edit: false,
    delete: false
  },
  mode: 'external',
  columns:
  {
    tableData: {
      title: 'Hostname',
      type: 'custom',
      renderComponent: LinkComponent
    }
  }

And to populate the table data:

this.dataService.fetchHosts(key).subscribe((result: object[])  => {
  result.map(mapped => {
    const value = mapped['value'];
    this.values.push({ tableData: value });
  });
  this.source.load(this.values);
});

The subcomponent, LinkComponent looks like this:

export class HostnameCellComponent implements OnInit{
  @Input() value: string;

Pass multiple pieces of data in to a Ng2-Smart-Table sub-component

Okay, but what if your link needs multiple variables to generate it? Unfortunately, the easiest way I found to do this is to create a sub-component as above, concatenate your variables in to a single, comma seperated, string, pass said string in to the component, and split it up there.

This is gross, but it means the table is still sortable.

valuelink.component.ts:

export class HostnameCellComponent implements OnInit{
  @Input() value: string;
  value_part1: string = '';
  value_part2: string = '';

  constructor(private route: ActivatedRoute, private router: Router) {
  }

  ngOnInit()
  {
    const array: string[] = this.value.split(',');
    this.value_part1 = array[0];
    this.value_part2 = array[1];
  }
}
On/Off AC Control Systems

May 5, 2018


It’s gotten very warm the past few days… lets take a crack at adding some logic to my “dumb” window AC unit to keep things cool!

The Cooling System:

My in-window air conditioner is not particurarly fancy.

What it can’t do:

❌ Remote Control
❌ Automatic turn on / off
❌ Network connectivity
❌ Turn on at set time

What it can do:

✅ Put out cool air

And to its credit, it does do a decent job at that, but I want more!

Making it smarter!

I need to know is the current temperature in the room. I’m currently doing that with an Arduino, an ethernet shield, and an Si7021 temperature / humidity sensor. It sits on my cabinet on the other side of the room and when I punch in it’s IP address it responds with a bare-bones website displaying the current data

Once a minute it also pushes a reading to my local InfluxDB server (hosted on site on a Raspberry Pi) for record keeping. I’m using Grafana to make all fo these pretty graphs.

I’ve got another Raspberry Pi connected to a Powerswitch Tail 2. It queries the InfluxDB every 2 minutes or so to get the temperature in the room and turns on, or off, the AC accordingly.

{
  "fahrenheit": 72.65,
  "celsius": 22.58,
  "relative humidity": 40.62,
  "relative light level": 0
}

You can see the code running the Arduino Sensor and the Raspberry Pi