Author Archive

Updating Realtek Drivers for PFSense on a ZOTAC ZBox

January 25, 2019 3 comments

A long while back I built a ZOTAC Zbox (ZBOX-CI323NANO-U) to run PFSense and act as my router. For the most part, it has worked pretty well.  The features are great, without any of the gimmicky stuff you’d find on a consumer router. It’s also a lot more upgradable than a consumer router.

One problem though, on occasion I’d have to restart the ZBOX when the internet would stop working. The display I had connected to the PFSense machine said this during a failure:

re1: watchdog timeout

Each time the error occurred, I would hunt around the internet for a few minutes to find a solution, but I was never able to find one. I gave up for a while. But recently I took a deeper dive.

I found some pages blaming the default network adapter drivers and how they don’t work well with realtek adapters. I also found this page announcing new realtek drivers. I’ve dabbled with Linux a bit, but I’d still consider myself pretty novice. It was pretty difficult for me to get the drivers copied over to the machine, and then installed.

Here’s the process I followed to get them installed:

  1. Download drivers
  2. Extract ZIP file
    1. I put mine on my desktop.
  3. Identify the IP address of your PFSense Router
  4. Open terminal
  5. Change directory to the desktop of your local machine
    1. Command “cd” will change directory
    2. Opening the terminal on a Mac should put you into your user’s home director. So “cd desktop” should bring you to the desktop as your working directory, and where the file is located
      cd desktop
  6. Copy the file with the SCP command.
    1. Make sure to use the “root” username, not “admin”, for the target.
    2. When entering a directory structure “..” will go up, or back, one level.
    3. Default directory on target is “root” so that has to be changed to the kernel folder.
    4. My full command was:
      scp if_re.ko root@
  7. You should get prompted for a password and then a progress indicator will show that the system is copying the file
  8. Now, SSH into the PFSense machine; enter your password when prompted
    ssh admin@
  9. Enter “8” to get to the shell
  10. Change directory to the kernel folder

    cd ../boot/kernel

  11.  Modify the file
    chown root:wheel if_re.ko
    chmod 0555 if_re.ko
  12. Open your PFSense admin page ( in your browser
  13. Go to Diagnostics -> Edit File
  14. Location: /boot/loader.conf.local
  15. Edit the file to look like this (if copy/pasting, replace smart-quotes with standard quotes):
  16. Save

During the process, I ended up replacing my loader.conf file with a blank new one. So if that happens, here is the correct details I got from a fresh install file (if copy/pasting, replace smart-quotes with standard quotes):

So far, I’ve had no problems! Wahoo for stable internet!


Whole Home Humidifier

January 23, 2018 2 comments

1320352173735008201water-droplet-hi.pngDry air is very unpleasant to be in for extended periods of time. Last winter I tried to rectify the problem by using a single ultrasonic humidifier. It seemed totally inadequate, so I purchased a second higher capacity unit. I quickly became annoyed at how tedious it was to fill the reservoirs. And neither really solved my problem well. This year, I decided to install a whole home humidifier system.

Installing a Humidifier is not an easy task, and required quite a bit of knowledge of different building systems. See below for all of the work that I did, what I learned, and a list of parts.

System Selection

The most common type of whole home humidifier is a bypass humidifier, where water trickles down a special mesh pad that heated air passes over. The humidifier unit itself is quite large and must be attached to a fairly large surface area of unobstructed flat ductwork, as well as have a return/supply bypass. Unfortunately I did not have the space on either side of my furnace (cold air return, or heated air supply) to place the bypass unit.

I did quite a bit of research to find some alternatives. I selected a steam humidifier; an AprilAire 800. The AprilAire 800 is a steam generating machine which placed on a wall/support close to the hot air supply of the furnace. A steam pipe is connected from the steam generator to the ductwork. The AprilAire 800 has a replaceable canister with electrodes in it.  The unit fills the canister with water and generates steam. Periodically, the system will flush the mineral rich water out to reduce mineral buildup in the canister.

A significant benefit to a steam system is that it doesn’t need the furnace to run heat at the same time it is humidifying, it only requires air circulation.

The unit has a capacity of 34.6 gallons a day, but my configuration will be at 23.3 gallons a day. Seems the maximum capacity of a bypass unit would be about 12 gallons a day. Ultrasonic units have a capacity closer to 3 gallons a day.


Looking at any HVAC system, the largest part is usually the furnace/blower which heats and moves the air.  The air conditioning coils, which cool air, are usually hidden within duct work following the furnace. It was important not to damage the AC evaporative coils when drilling a hole and inserting the steam pipe.

Vent Stack

In order to fit the steam generator into my closet, and avoid the furnace’s gas supply line, I had to adjust the placement of the exhaust stack. I have an 80% efficiency gas furnace which requires an exhaust stack made of type B vent.  Type B vent is essentially double walled metal duct. I tied into my building’s common exhaust stack on the second floor, so I have to deal with the stack coming up from the unit below me.  The unit below me also has an 80% efficiency furnace.

My first attempt was removing the long 6 foot 5.5″ diameter section, and re-routing it with new 45 degree elbows, and smaller vent sections.  After getting the parts, and starting assembly, I discovered two things:

  1. I did not calculate the section lengths correctly.
  2. Type B vent from Amerivent is painfully difficult to work with.

Instead of buying additional type B vent parts and correcting my calculation error, I decided to rig my own system up with parts from Home Depot. The most important part of this vent stack was that it was double walled. The exhaust from the system below me needed to stay hot so that it would rise and leave the building above the 3rd floor.  And the exterior of the vent needed to remain cool so not to have any risk of fire or burns. My solution was a 6″ to 4″ reducer collar on both ends of the 5.5″ section I was taking out, and a 4″ flexible dryer vent within a 6″ flexible dryer vent as the ductwork.


I installed a Nest thermostat several years ago. I knew it had the ability to operate a humidity supply system when I started on this new humidifier project of mine, however, connecting the Nest to the AprilAire 800 was not as simple as connecting a wire to both devices. The nest can only connect to one device directly. In my situation, it was the furnace/blower/AC system. The AprilAire 800 is turned on and off by completing a circuit. The solution was to add a “common” wire from my furnace to the Nest, and then connect a relay to the common line and the asterisk connection on the Nest.  Here is the wiring diagram:

Nest W-Powered Humidifier

After connecting all the wires, the Nest detected the change, and I went through the options of how the humidifier needs controlled.  I selected that when humidity is requested, the fan should also operate.

The guided setup was pretty slick. I was even able to select what time the humidifier should NOT operate, which is nice when combined with my ComEd hourly electric supply pricing; I only run the humidifier at night when electricity is generally cheaper. If only Nest had a way to integrate the ComEd hourly price API and set an electricity price threshold for the humidifier to operate.

Power Supply

The AprilAire 800 can operate at 120 or 240 volts AC and run at 11.5 or 15 amps. It’s shipped to accept the most efficient and common configuration; 240 volts at 11.5 amps. Lucky for me, my 200 amp load center is right behind where I wanted to put my AprilAire 800, there was plenty of empty positions in the panel, and there was already an easily accessible conduit used for a whole home surge protector to run the new circuit within.  Through the research I conducted, I found 14 AWG wire was plenty for my 4 foot run of cable. One odd thing to me was that I didn’t need a neutral wire. Apparently that is how the 240 volt system works. Instead of a hot and neutral, there are two hot lines, but on different phases.

Water Supply

Almost any humidifier system on the market accepts a 1/4″ connection, which can be installed without soldering copper pipe. I was able to run a poly pipe from my HVAC closet down through my neighbor’s closet, and then into the basement. I tapped into my neighbors humidifier supply line with a tee, so there was no need to pierce another section of pipe.

One important thing I learned is this: when using compression fittings (rather than quick connect), poly pipe should use plastic sleeves, and copper should use copper sleeves. If copper is used on a poly pipe, the copper cuts into the pipe instead of compresses/seals the pipe, leading to leaks and possible 100% disconnection. I ran into both problems attempting to install my line. It’s only after significant research that I found the problem. What is most concerning is that kits sold with poly pipe frequently include all brass fittings! It’s funny to read the reviews on Home Depot’s website where most are negative, and if people are not complaining about leaking or failures, they are suggesting buying the proper plastic sleeve to prevent leaks.

The brass sleeves that came with the copper tee also had to be changed out with plastic sleeves. It wasn’t the simplest task, as the brass sleeves were somewhat “built into” the tee. Some force had to be used to remove them.


My HVAC closet already had a simple PVC drain system in place for AC condensate.  I connected to that with a new tee and even added a P trap.  I feel like such an accomplished plumber. Protecting my floor was important, the PVC cleaner and cement would easily damage the wood floor.


Installed Pictures

Fixing my Zyxel NWA1123-AC

October 6, 2017 Leave a comment

My home network is pretty advanced. I have a PFSense home-built router (based on Zotac ZBOX CI323) that connects to my modem, several smart switches (Netgear JGS524E), and 2 wireless Access Points.  The two access points are both made by Zyxel; an NWA1123-AC and an NWA1123-ACv2.  I thought it would be prudent to upgrade the firmware of both devices this week but ran into a problem.

Since both need different firmware, I first downloaded the firmware for the v2 device, and then did the v1 device.  Somehow I managed to download the NWA1121-NI firmware for the v1 device, and then applied it. As I was doing some configuration on the device, I saw I was missing the 5 Ghz settings, which lead me to figuring out I had flashed it with the wrong firmware. I thought it would be easy to revert back since I was able to go one way, but that proved wrong! The device wouldn’t accept the correct firmware.

I did some hunting around the internet, gave up quick, and submitted a technical support request.  Zyxel got back to me the following day saying I would have to RMA the device, sending it back to them, assuming it was in warranty. After some following correspondents,  it was determined that I was out of warranty/support. I turned back to the internet.

I found, on Zyxel’s website (PDF), they had directions on how to have the device pull firmware from a TFTP server before the router fully booted. However, there were some critical steps missing.

  • There’s no serial port on the AP; WHAT?
  • How do I unzip a bin file? And how do I unzip what comes out of that?
  • What software do I use to TFTP?
  • What software do I use for a terminal?

Zyxel support insisted that this KB article on their site did not apply to my AP problem, and there was no way I could recover the device without sending it in to them.

I did some more hunting and found someone over at the site posted the internal parts of the NWA1123-AC AP, as well as some serial port details. I also found a page for serial port specifics saying I needed a USB TTL adapter.  The same page had details on the pins to connect the adapter to on the AP (see: Router with serial port / header / pins). Turns out Amazon and my local MicroCenter both carried a USB to TTL adapter, for use with RaspberryPi devices. I biked over to MicroCenter, and picked one up.

Once I got home, opened up my AP, connected everything, downloaded and set up Tera Term and TFTPD64, and starting going through the KB article. I used 7zip to extract the contents of the bin file, and the contents of the subsequent file. I ended up with the files shown in the KB article, so even though 7zip said there was extra contents that wasn’t extracted, I figured I was on the right track.

Everything seemed to work great, and got my device flashed with the correct firmware! Sadly, Zyxel’s poor design required me to clear my browser cache to get the AP’s config page working correctly, but if that was the only hiccup, I wasn’t too angry, and I had been stupid enough to flash the wrong firmware on the AP in the first place.

Access Point saved from certain death!

Amazon Alexa Skill – Electric Price

July 26, 2017 3 comments


I was sick of opening up my phone to check the ComEd hourly price of electric supply, so I decided to make an Alexa app for my Amazon Echo!

It took about 2 hours. It was strange I had to set up both an Alexa skill and the AWS Lamda function, then link the two. I ended up copying most of the code from someones reference code on checking stock prices. Changed the regular expression function which found the stock price to a substring of the ComEd API returned text. Works pretty well! Only problem I’ve had is when the ComEd API is down. If it happens too much, I guess I’ll have to update it with some error handling.

Alexa Skill: Electric Price

Ask: “Alexa, ask Electric Price for Current Price.”

The logo is crap, I know.  And I couldn’t use the ComEd company name in any of the program details/functions, so its a bit generic.  But pretty good for my first try if I do say so myself!

Raspberry Pi CTA Tracker Kiosk

February 9, 2017 Leave a comment



I purchased a Raspberry Pi 3 about a year ago and finally got around to creating a fully functional CTA bus/train tracker out of it.

Parts Needed

Raspberry Pi 

Micro SDHC Cards


Cable (Cable that came with screen was defective)

Keyboard and Mouse (any will do, but I like this)

CTA Tracker URL:

Create your specific CTA Tracker URL and save it for later

Read more…

Generating XML in PL/SQL

January 17, 2017 Leave a comment

At work we have historically been using concatenation for generating XML Data. I stumbled upon these XML functions the other day, and thought it was worth sharing. They seem to be the proper, and I’m sure more efficient, way to generate XML using Oracle PL/SQL. I’m dumbfounded that our developers didn’t use this method, but who am I to judge!

Oracle Documentation:

Easier to Understand Guide:

Example Query for Delivery Lines

Should produce XML for a Delivery with its lines, where lines contain the Item Number, Description, Shipped Quantity, and Requested Quantity.

 msib.segment1 AS "ITEM_NUMBER",
 FROM wsh_delivery_assignments wda,
 wsh_delivery_details wdd,
 mtl_system_items_b msib,
 mtl_system_items_TL msibTL
 WHERE wda.delivery_id = wnd.delivery_id
 AND wda.delivery_detail_id = wdd.delivery_detail_id
 AND wdd.inventory_item_id = msib.inventory_item_id
 AND msib.organization_id = WND.ORGANIZATION_ID
 AND wdd.inventory_item_id = msibTL.inventory_item_id
 AND msibTL.organization_id = WND.ORGANIZATION_ID
 FROM wsh_new_deliveries wnd
 WHERE delivery_id = :delivery_id))
 AS xmlserialize_doc


Sending ZPL to a Label Printer Using PL/SQL

January 9, 2017 Leave a comment

Oracle’s WMS package has some label printing capabilities, but the functionality is quite poor, and requires knowledge of XML Label printing.

XML Label printing, generally, is the ability to send an XML file to a label printer, where the XML file contains the label format to use, and the data/variables to print on the label.  This allows you to have one label “template” which can be reused for printing similar data.  Printing a shipping label for example.  The label format never changes, but the data does.  The standard solution requires a ZPL Template to be stored on a Zebra printer’s flash memory.  That ZPL template can be coded by hand, or by using Zebra Designer software.  One drawback to this solution is that templates must be downloaded to every printer which will be used. Centralized label template storage would be ideal.

There are several third party solutions that bolt onto the Oracle functionality and allow for a centralized label template, but they also have their own drawbacks, and can cost several hundred thousand dollars to implement, in addition to the ongoing maintenance and server costs.  Even with the third party solutions, the user is still left with quite a few deficiencies with the Oracle WMS feature set.

There is an alternative to the template centralization problem which I think is ideal.  Store the templates on the server which will be generating the print requests.  Instead of having the Zebra printer or third party add on tool merge the XML with the ZPL template, have the same server that is generating the label print requests merge the template/date.

I’ve come up with a simple PL/SQL script which allows a programmer to send a string of text to a label printer through the network using TCP/IP protocol.  It uses the same function that Oracle uses to send the XML to the printer when printing without a third part tool, but instead of sending XML, one can send ZPL.  This script can easily be added to a procedure that splices data with a ZPL template.

The strange thing about this function is that it has multiple outputs and cannot be used in a SELECT statement like most functions.  I’m not sure why Oracle decided to use a function rather than a procedure, but here’s how you can run it:


 l_return_msg           VARCHAR2(3000);
 l_printer_status       VARCHAR2(3000);
 l_return               VARCHAR2(3000);
 l_zpl                  CLOB;
 l_printer_ip           VARCHAR2(20);
 l_printer_port         VARCHAR2(10);
 l_zpl :=’^XA^FO50,300^A0N,125,125^FDTEST^XZ’;  –String to send to printer
 l_printer_ip      :=’′; –IP Address of printer
 l_printer_port    :=’9100′;
        p_ip_address => l_printer_ip
    ,   p_port => to_char(l_printer_port)
    ,   p_xml_content => l_zpl
    ,   x_return_msg => l_return_msg
    ,   x_printer_status => l_printer_status