Black and Decker Portable AC

I recently picked up a Black and Decker Portable AC https://www.amazon.com/Black-Decker-Portable-Conditioner-Display/dp/B01DLPUWG2 and wanted to port over a Blynk project I had created. I couldn’t find anything online about what the infrared protocol is for the remote. So here you go:

Protocol  : TCL112ACCode      : 0x23CB26010024030D00000000C009 (112 Bits)Mesg Desc.: Power: On, Mode: 3 (Cool), Temp: 18C, Fan: 0 (Auto), Econo: Off, HealProtocol  : TCL112AC
Code      : 0x23CB26010024030D00000000C009 (112 Bits)
Mesg Desc.: Power: On, Mode: 3 (Cool), Temp: 18C, Fan: 0 (Auto), Econo: Off, Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Off
uint16_t rawData[227] = {3134, 1586,  496, 1174,  504, 1166,  502, 334,  494, 366,  474, 362,  476, 1166,  502, 332,  496, 340,  498, 1170,  498, 1172,  496, 366,  474, 1194,  474, 336,  502, 358,  470, 1174,  506, 1164,  504, 332,  496, 1174,  494, 1176,  504, 358,  472, 336,  502, 1166,  502, 334,  494, 340,  500, 1168,  500, 336,  504, 358,  472, 336,  502, 358,  470, 364,  476, 332,  496, 364,  474, 360,  468, 366,  472, 362,  478, 358,  472, 334,  504, 356,  472, 362,  476, 358,  470, 364,  474, 360,  470, 1172,  496, 366,  474, 334,  494, 1174,  504, 330,  498, 336,  502, 1166,  502, 1168,  500, 334,  496, 340,  498, 362,  476, 332,  498, 336,  502, 332,  496, 1172,  496, 338,  502, 1168,  500, 1170,  498, 336,  504, 358,  470, 364,  474, 360,  470, 364,  474, 362,  468, 340,  498, 360,  468, 366,  472, 362,  476, 332,  496, 364,  476, 332,  496, 366,  476, 332,  496, 338,  500, 360,  468, 366,  472, 336,  504, 356,  472, 364,  476, 358,  470, 364,  476, 358,  470, 364,  474, 360,  468, 366,  474, 360,  468, 340,  500, 362,  468, 366,  472, 362,  476, 358,  470, 364,  474, 332,  498, 364,  476, 332,  496, 366,  474, 360,  468, 366,  472, 362,  476, 330,  498, 1198,  472, 1172,  496, 1174,  496, 338,  500, 362,  478, 1164,  504, 330,  498, 364,  476, 360,  468, 366,  474};  // TCL112AC
uint8_t state[14] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x09};
th: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Offuint16_t rawData[227] = {3134, 1586,  496, 1174,  504, 1166,  502, 334,  494, 366,  474, 362,  476, 1166,  502, 332,  496, 340,  498, 1170,  498, 1172,  496, 366,  474, 1194,  474, 336,  502, 358,  470, 1174,  506, 1164,  504, 332,  496, 1174,  494, 1176,  504, 358,  472, 336,  502, 1166,  502, 334,  494, 340,  500, 1168,  500, 336,  504, 358,  472, 336,  502, 358,  470, 364,  476, 332,  496, 364,  474, 360,  468, 366,  472, 362,  478, 358,  472, 334,  504, 356,  472, 362,  476, 358,  470, 364,  474, 360,  470, 1172,  496, 366,  474, 334,  494, 1174,  504, 330,  498, 336,  502, 1166,  502, 1168,  500, 334,  496, 340,  498, 362,  476, 332,  498, 336,  502, 332,  496, 1172,  496, 338,  502, 1168,  500, 1170,  498, 336,  504, 358,  470, 364,  474, 360,  470, 364,  474, 362,  468, 340,  498, 360,  468, 366,  472, 362,  476, 332,  496, 364,  476, 332,  496, 366,  476, 332,  496, 338,  500, 360,  468, 366,  472, 336,  504, 356,  472, 364,  476, 358,  470, 364,  476, 358,  470, 364,  474, 360,  468, 366,  474, 360,  468, 340,  500, 362,  468, 366,  472, 362,  476, 358,  470, 364,  474, 332,  498, 364,  476, 332,  496, 366,  474, 360,  468, 366,  472, 362,  476, 330,  498, 1198,  472, 1172,  496, 1174,  496, 338,  500, 362,  478, 1164,  504, 330,  498, 364,  476, 360,  468, 366,  474};  // TCL112ACuint8_t state[14] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x09};
Protocol  : TCL112ACCode      : 0x23CB26010020030D00000000C106 (112 Bits)Mesg Desc.: Power: Off, Mode: 3 (Cool), Temp: 18C, Fan: 0 (Auto), Econo: Off, Health: Off, Light: On, Turbo: Off, Swing(H): Off, Swing(V): Offuint16_t rawData[227] = {3138, 1582,  502, 1170,  498, 1170,  498, 364,  476, 360,  468, 366,  472, 1196,  472, 364,  476, 360,  468, 1200,  478, 1166,  502, 332,  496, 1200,  468, 368,  472, 362,  476, 1192,  476, 1166,  502, 362,  478, 1192,  476, 1168,  500, 362,  478, 356,  472, 1196,  472, 364,  474, 360,  468, 1200,  478, 330,  498, 364,  476, 360,  468, 364,  474, 360,  468, 366,  472, 362,  476, 358,  470, 364,  474, 360,  468, 364,  474, 360,  468, 366,  472, 362,  476, 358,  470, 364,  474, 360,  468, 364,  474, 360,  468, 366,  472, 1194,  474, 362,  476, 358,  470, 1198,  470, 1174,  504, 358,  470, 364,  474, 360,  468, 366,  474, 362,  478, 358,  470, 1196,  472, 366,  474, 1194,  474, 1170,  498, 364,  476, 360,  468, 366,  474, 360,  468, 368,  472, 362,  476, 358,  470, 366,  474, 362,  466, 366,  474, 362,  468, 366,  472, 362,  476, 360,  470, 364,  474, 360,  468, 366,  474, 362,  478, 356,  472, 364,  476, 358,  470, 366,  474, 362,  478, 356,  472, 366,  474, 358,  470, 364,  474, 360,  468, 366,  472, 362,  478, 356,  472, 362,  476, 358,  470, 364,  474, 360,  468, 366,  474, 1196,  474, 336,  504, 358,  472, 364,  474, 360,  468, 366,  472, 1194,  474, 1170,  498, 364,  476, 1194,  474, 1170,  498, 362,  476, 360,  470, 366,  474, 362,  476, 358,  472};  // TCL112ACuint8_t state[14] = {0x23, 0xCB, 0x26, 0x01, 0x00, 0x20, 0x03, 0x0D, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x06};

TDR with the NanoVNA

The performance of my satellite downlink station is nowhere near as good as I would like. I been doing some various troubleshooting measures to try and figure out what is going on. In my previous post, you can see some of my explorations about antenna tuning. In this post I took my first pass at exploring the feedline situation. It’s been up for at least five years and wanted to make sure nothing untoward had happened to it.

To help measure it, I ran a TDR test on the feedline. This is not a perfect measurement as I left the antenna attached, which messes up some things. But it gives you the opportunity to measure where impedance changes occur in the feedline. Here’s what the resulting plot looks like:

At first I was terribly confused thinking my feedline was terribly broken. It’s important to note that the current NanoVNA-Saver software doesn’t present TDR the way most people expect. It stacks the impedances of the various segments, so you shouldn’t read that big flat segment in the middle as being at 90 ohms.

Breaking it down by segment I get the following: short stub that adapts SMA to UHF connector; 10 feet of LMR 400 equivalent; a big impedance jump as the signal travels through a 3 inch barrel connector through a door; 30 feet of LMR 400 outside; another barrel connector; 10 more feet of LMR 400; then the antenna.

What did I learn in the end? It looks like my various lengths of cable are fine. Most importantly I learned that UHF connectors have a surge impedance of around 35 ohms instead of the 50 ohms we are looking for. That causes reflections and increases the return loss of your feedline. Wikipedia article on the impedance of UHF connectors: https://en.wikipedia.org/wiki/UHF_connector

So where does that leave me?

This showed I didn’t have any problems in my feed lines other than the ones I caused myself by using UHF connectors and patching together shorter lengths of cable. My next steps to evaluate the system performance will be to measure the SWR and return loss of just the feedline without the antenna connected. This means I’ll replace the antenna with a 50 ohm calibration standard to measure return loss; then replace it with a dead short to measure insertion loss. More detail here: https://www.tek.com/blog/improving-vna-measurement-accuracy-quality-cables-and-adapters

I’ve been having a strong desire to replace every UHF connector with a Type N connector. These measurements are an attempt for me to quantify what, if any, practical improvement I would see from that change. I fear that my real problem is that I live in a city and there is just far too much noise around me.

I cut it twice and it’s still too short!

For my satellite ground station I built an antenna from the plans by WA5VJB http://www.wa5vjb.com/references/Cheap%20Antennas-LEOs.pdf

I originally built a 7 element 70cm antenna. But then added on a two element 2m one. While I had tuned the 70cm antenna, it was tuned a little too low after the second cut to shorten the driven element. But it passed, just barely.

While attaching the new antenna to the old, I got frustrated smacking the darn thing into everything and hacked off the end, converting it to a 5 element in short order. With years of experience under my belt I have learned that anger is not a great engineering design philosophy.

I didn’t check the tuning before mounting it up here.

Lets take a look at what the NanoVNA Says. This is the return loss chart for 2 m frequency.

While the tuning is a little low for what I want, it’s close enough to work. For example most satellites are around 145 MHz.

Unfortunately this is awful. I need tuning closer to 435 MHz, this bad boy is coming in at 415 MHz. Looks like it’s time to take out the plumbers torch and solder some more wire back onto the antenna :).

abandoning Pi-Hole for cloudflared

I’ve been using Pi-Hole for a while and it just caused too many problems. Many shopping carts across the web would just fail. I need to run google ad campaigns and you can’t get to the admin UI. Therefore I decided to move dns resolving back to my ER-X and instead use cloudflared to resolve DNS queries so CenturyLink has a harder time selling my browsing history.

I found a great post on how to do this at: https://reichley.tech/dns-over-https-edgerouter-x/ but it doesn’t cover the v2 series of EdgeOS based on Debian 9. These are my quick notes on changes to their directions.

When you install a new update of EdgeOS, it overwrites all the default partitions such as /usr. Therefore I decided to store my files in /config/user-data which is an area that persists between system updates.
On edgeos:
mkdir /config/user-data/cloudflared
On machine used to upload:
scp cloudflared user@erx:/config/user-data/cloudflared

I also decided to store a copy of config.yml in this directory before copying it over to /etc/cloudflared/config.yml. That way after an upgrade I have less work to do.

EdgeOS v2 uses systemd instead of init.d for startup.

sudo cp /config/user-data/cloudflared/config.yml /etc/cloudflared/yml
sudo /config/user-data/cloudflared/cloudflared service install
sudo vi /etc/systemd/system/multi-user.target.wants/cloudflared.service  

Modify line to include pid info (not sure if we need this with systemd)

ExecStart=/config/user-data/cloudflared/cloudflared --config /etc/cloudflared/config.yml --origincert /etc/cloudflared/cert.pem --pidfile /var/run/$name.pid --no-autoupdate 
sudo systemctl enable cloudflared.service
sudo systemctl start cloudflared.service
systemctl status cloudflared.service  

Also /usr/sbin wasn’t in my path, so I had to call tcpdump directly.
/usr/sbin/tcpdump -nXi eth0 port 443 and dst host 1.1.1.1

After an upgrade I should only need to do re-run a few of the steps above.

Causal Inference Resources

I was inspired by the post “Why you should stop worrying about deep learning and deepen your understanding of causality instead” to write up some of the resources I’ve used over the past year as I myself have tried to learn more about causality.
The field of Causal Inference has become much more rich and interesting over the past 20 years as a number of new statistical tools were created to help improve the bias inherent in model dependent statistical inference. I find it’s best to start with understanding the split between prediction and causal inference that has been in the field for quite a while. Each of the following three references goes into much more detail about how many of the same tools are used between causal inference and prediction, but the meaning assigned to the model, and in particular how you evaluate the model for appropriateness is very different depending on what you’re trying to do.
 
Statistical Modeling: The Two Cultures : http://projecteuclid.org/download/pdf_1/euclid.ss/1009213726
 
My team and I spent a lot of time dealing with observational data. Therefore much of my focus has been about how to make better decisions when dealing with observational data and quasiexperimental study design. There’s been a lot of research in this area because so many medical studies are based on observational data. The Evidence Based Medicine movement came out of a desire to improve clinical decision-making outcomes and provides many ideas that can be reused within my own field. One of the pieces that is fantastic for decision-making in general, is the hierarchy of evidence. This provides a framework within which to base your decision making and understand how biased your study could possibly be.
 
One of the articles I really enjoyed coming across was by Rubin: “For objective causal inference, design trumps analysis”. In it he briefly covers the counterfactual framework, and reworks an observational study through the lens of experimental design, using the appropriate tools to approximate a true experiment to the best of his ability. It definitely gave me a much better understanding about the role of treatment assignment and how it participates and causal inference.
 
And now onto books!
 
The first book is particularly awesome and mathy. I find that it hops right in and covers the key concepts you need to understand about modern causal inference theory. That is both a strength, and weakness. If you’re not up to date on reading mathematical notation, it can be a little challenging.

“Counterfactuals and Causal Inference” by Morgan and Winship

This was the first book I got. I actually had the first edition, and upgraded to the second edition when it came out, definitely worth it. I found many of the topics more approachable in this book than the previous book, but they restrict the set of tools they give you. Therefore I found it a great place to start and become comfortable with counterfactual theory and causal diagrams, but I eventually had to upgrade to the book out of the Harvard school of public health.
 
Many papers you encounter will refer back to the work in this book, which is largely a compendium of the research done by Rubin. I found it an additional perspective to many of the concepts covered in the previous two books. So probably not required, but nice to round things out.
 
This book showed me how little I really knew. It was the last one I purchased and I still haven’t finished it. I really need to sit down and compare the contents of this textbook against the second half (Model Dependent Causal Inference) of the Causal Inference book out of Harvard.
 
OK. This book hasn’t shipped, and I haven’t read it. But I’m very excited by it. Judea Pearl’s other book: “Causality: Models, Reasoning and Inference” is well-regarded, but also known to be very difficult as it connects together causal reasoning in several different fields into one overarching framework. He also has a blog we can stay up-to-date on some of the latest books and research in this area: http://causality.cs.ucla.edu/blog/index.php/2016/02/12/winter-greeting-from-the-ucla-causality-blog-2/ .
 
Lastly, one of the early papers I encountered that I felt did a good job in this area: Sekhon, J. S. (2011). Multivariate and propensity score matching software with automated balance optimization: The Matching package for R. Journal of Statistical Software 42(7). http://www.jstatsoft.org/v42/i07 . I found his package rather straightforward to use and high enough performance to work against the large data sets I deal with on a regular basis.
 
If you’re ever in the Seattle area and want to chat about these things, I would love to do coffee.
 
–chris