Featured

New CCTV System

I decided to buy the CCTV equipment. I bought a Reolink 5MP Pan Tilt Zoom Camera for the Driveway and a Reolink 5MP with Audio Turret Camera for the Lanai. My Boss let me buy a Hikvision Door Bell at cost and it was on sale from the distributor for $98.00. It’s the only one I can find that has ONVIF currently. I also have a couple of Hikvision IP Cameras I will use for Indoor use.

For now I plan to use MicroSD Cards for recording and push it to Shinobi that is running on the Home Assistant Server. For now I will use a TP-Link 5 Port PoE Switch. I really don’t see adding anymore Cameras since the placements I have chosen should cover everything. Except one area that has the A/C unit.

I am a bit worried since I heard A/C unit thefts are on arise in my area but I got that covered. I traded a A/C Tech 25ft of Coax for 25ft of outdoor rated cable used for A/C systems so I can make a dummy line that connects to the Alarm Panel so when someone cuts it the Alarm goes off, I have it programmed as a Duress so the Central Station sends out the Cops without Verification. Also used longer Tapcons to attach the unit into the Cement Pad. I also stripped out the Nut Driver portion of the Tapcons so the only way to get them out is with a Flat Head or a Cutting Wheel. Besides the Driveway Camera and Lanai Camera would catch anyone going to the side of the House anyway.

Anyway, back on topic here. I will probably run the Cabling to the Master Closet or Garage and then run a Single Line to the Living Room since the TV stand is getting full. Since the pfSense box has one more open port I can dedicate that to the CCTV and give access to Home Assistant.

I already got a friend that wants to buy my old Analog DVR and I will probably give the Ring to my Mother.

Featured

Lost art of Cable Management – Cable Lacing

Used in Telcom, NASA and Avionics a almost lost art of Cable Management called Cable Lacing. Instead of using Zip Ties or Tape a Waxed Coated Cotton String is used for the whole length of a Wire Rack or Wire Harness/Bundle.

In my honest opinion this looks a lot cleaner and better then a hundred Zip Ties and doesn’t leave a sticky residue like Tape does. It’s also pretty darn cheap, just don’t buy the “Electronics Grade” stuff. The 1mm size that is used for Jewelry is cheaper and it is the exact same stuff. You can also use thinner stuff but you’ll have to double wrap the bundle.

I found a little Video on YouTube that covers how to do it. The man in the Video has a terrible accent but you just to need to watch rather then listen.

A few Tips I have with this Method. Have the knots closer then what I have in the example photo. If the Cabling is running flat then you can get away with knots further away but when you go into turns and twists you want the knots closer or it will look like this.

Just like anything new you will be slow and it will look like crap but with practice it will look better and you’ll get much faster.

Featured

Fresh install Debian 10 Linux

When I install Linux I end up spending a lot of time tweaking it the way I like it. No matter the Distribution I end up doing stuff like this. Mostly because Out of the Box is for the novice user. Most end Linux users do the same thing.

I typically start with just the base install to make sure all of my hardware is in working order such as Chipset, CPU Microcode, Networking and USB. Easier to catch the issues when it’s a plain Command Line Interface. Also much easier to redo the install to Unstable if the Kernel is too old to see brand new hardware. Unstable isn’t really Unstable, it’s just newer Software that is still experimental. For a example Ubuntu uses a mixture of Unstable and LTR (Long Term Release).

When partitioning I keep things simple and use a single Partition for everything. Now if I am doing this to a system that has Multiple Hard Drives I’ll move things around such as putting the /home directory onto a different drive. Back in the day I use to toss in a old drive just to be used for SWAP but these days I see no performance gains. A EXT4 Partition is just find and no need to go into the world of ZFS and GPT since ZFS eats RAM and GPT will bite you in the ass in the end.

After I verify everything is working I’ll edit the APT sources file and add the contrib and non-free entries, update the mirrors and upgrade. Install Xorg and whatever Window Manager I want. Currently I am giving KDE Plasma a spin and it has a few nice features but I like using the Awesome WM.

Before anything else I once again verify my Video and Audio is working correctly. I’ll run the glxgears program or just look at the OpenGL Information. To test Audio I’ll just load something up in YouTube, a few times in the past the Audio would work fine within the Window Manager but YouTube, Steam and VLC would be deaf. So if YouTube works then there shouldn’t be issues with anything else.

Now I can start adding my custom tweaks and such.

I add my user to the sudoers file and make sure the hostname for the system is final. Also install ntp if Xorg’s install didn’t include it.

su
apt install binutiles sudo ntp ufw fish vlc
nano /etc/sudoers


under root’s entry add
[username] ALL=(ALL:ALL) ALL
Save and exit.

exit

I start by changing the Command Line Shell. Debian uses a modified version of BASH called DASH. Works alright but after you start playing with other types of Shells you end up staying away from it. I use to use Zsh but I converted to FISH. After installing fish I then issue chsh -s /usr/bin/fish then launch it. From there I go into ~/.config/fish and edit the config.fish file and add my alias entries.

alias ls="ls -lahp"
alias dir="ls -lahp"
alias shutdown="sudo shutdown now"
alias reboot="sudo reboot"
alias update="sudo apt update"
alias upgrade="sudo apt upgrade"
alias purge="sudo apt autoremove"
alias edit="nano"
alias G="grep"
alias S="sudo"

After tweaking commands to my liking I’ll add more software I attend to use such as Htop, Bleachbit, Guake, and KDE Connect.

Over time I end up installing neofetch, screen, Arduino IDE, Sublime Text and GCC, Firefox and vBox.

Once in a blue moon I’ll screw up and spend a good few hours fixing it or just end up reinstalling everything.

Featured

Limit Unwanted Network Connections

I’m slowly putting together a Network Administration suite for the Raspberry Pi. Came across a little jewel called Evil Limiter. It’s a Python 3 Script that can do a ARP scan of a Network and give you a IP Address on the Network that you know shouldn’t be there or you have a User sucking up too much Bandwidth. So instead of Deauthing the user you can Throttle or even Block the User. For a example you can Limit a User to 100Kbit/sec or even totally block them.

This could be handy for enforcing say the Kids Internet usage during the Spring/Summer Break or even at work when Steve should be working on a report but is too busy watching Netflix or YouTube.

Now this tool is considered a DoS (Denial of Service) Attack so be careful how you use it and deploy it.

Featured

Building a Z80 Computer

Every hardcore Electronics Engineer and Computer Nerd has a bucket list and there is a Homebrew Retro Computer on that list. I could cheat and buy a RC2014 kit but building it from total scratch is even better.

Now you just don’t order/buy/find the parts and slap it all together. You have to study up on the subject. There is a PDF floating around called “Build your own Z80 Computer” by Steve Ciarcia. Then you have Grant Searle’s Website that is loaded with tons of Schematics and ideas for a minimal chip count Z80 running BASIC and CP/M.

To start off the build I am going to build a curd version of the Zeta256 and branch off of that by adding memory, UART, ROM and so forth.

Honeywell Vista Home Assistant Integration – Complete

After modifying the Code and my sillyself forgetting to disable the lrrSupervisor option since my Panel has a GSM I had made a lot of progress with one issue that was still lurking. The Message Log kept saying 0: Unknown Zone 0 There is no Zone Zero. I went to GitHub and submitted a issue and within an hour Dilbert66 came to the rescue. He modified the vista.h file and it cleared the error.

I was now confident enough to trust it so I added the Keypad Card to control the System.

I added this in the Configuration.yaml file, be sure to change the code on the last line. Keep in mind if you ever change your four digit code you need to change it in the configuration.yaml file or you might end up getting locked out of the Alarm System.

alarm_control_panel:
   - platform: template
     panels:
       safe_alarm_panel:
         name: "Alarm Panel"
         value_template: "{{states('sensor.vistaalarm_system_status')}}"
         code_arm_required: false
         arm_away:
           - service: esphome.vistaalarm_alarm_arm_away
         arm_home:
           - service: esphome.vistaalarm_alarm_arm_home
         disarm:
           - service: esphome.vistaalarm_alarm_disarm
             data_template:
               code: '1234'

After that has been added to the Configuration.yaml file you need to restart Home Assistant then create a new Alarm Panel card and it should already populate with the info. If not then select alarm_control_panel.safe_alarm_panel as the entity.

Here is the raw yaml code for the Alarm Panel Card.

type: alarm-panel
states:
  - arm_home
  - arm_away
entity: alarm_control_panel.safe_alarm_panel 

Pretty darn simple when it’s all said and done. If you want to make your own Adapter board that uses a D1 Mini then feel free to use my PCB Gerber Files.

Honeywell Vista Home Assistant Integration – Update

The Wife likes to open Windows when it’s nice out and since she has three open currently I opened up Home Assistant and I can see the Sensors are flipping out.

For a example she has the Sliding Glass Door open, Dining Room Window Open and the Living Room Window. Home Assistant will see Dining Room Window as open then after a second or two it changes to closed then randomly goes to Living Room Window open. It’s kinda odd. I know it’s not a hardware issue. It seems to be a software limitation.

This is the original yaml file.

substitutions:
  systemName: "vistaalarm"
  accessCode: !secret access_code
  keypadAddr: "16"

  expanderAddr1: "0"
  expanderAddr2: "0"

  relayAddr1: "0"
  relayAddr2: "0"
  relayAddr3: "0"
  relayAddr4: "0"

  TTL: "30000"

  quickArm: "false"

  lrrSupervisor: "true"

globals:
     - id: zoneStates
       type: int
       restore_value: yes
     - id: zoneAlarms
       type: int
       restore_value: yes
     - id: zoneBypass
       type: int
       restore_value: yes
     - id: zoneChecks
       type: int
       restore_value: yes      
     - id: lrrCode
       type: int
       restore_value: yes      
esphome:
  name: $systemName
  platform: ESP8266
  board: nodemcuv2
  includes:
    - vistaEcpInterface/
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "$systemName"
    password: !secret wifi_password
logger:
  baud_rate: 115200
  level: DEBUG
api:
   password: !secret api_password  
ota:
   password: !secret ota_password
   safe_mode: True
status_led:
  pin:
    number: D4
    inverted: yes
custom_component:
- lambda: |-
    auto VistaECP = new vistaECPHome($keypadAddr);
    VistaECP->accessCode="$accessCode";
    VistaECP->quickArm=$quickArm;
    VistaECP->expanderAddr1=$expanderAddr1; //zone expander
    VistaECP->expanderAddr2=$expanderAddr2;
    VistaECP->relayAddr1=$relayAddr1; //relay module 
    VistaECP->relayAddr2=$relayAddr2;
    VistaECP->relayAddr3=$relayAddr3; 
    VistaECP->relayAddr4=$relayAddr4;     
    VistaECP->lrrSupervisor=$lrrSupervisor;
    VistaECP->TTL=$TTL;
    VistaECP->debug=1;
    VistaECP->onSystemStatusChange([&](std::string statusCode) {
       id(system_status).publish_state(statusCode);
    });
    VistaECP->onLrrMsgChange([&](std::string msg) {
        id(m1).publish_state(msg); 
    });    
    VistaECP->onStatusChange([&](sysState led,bool open) {
      switch(led) {
        case sfire: id(fire).publish_state(open);break;
        case salarm: id(alarm).publish_state(open);break;
        case strouble: id(trouble).publish_state(open);break;
        case sarmedstay: id(stay).publish_state(open);break;
        case sarmedaway: id(away).publish_state(open);break;
        case sinstant: id(instant).publish_state(open);break; 
        case sready: id(ready).publish_state(open);break; 
        case sac: id(ac).publish_state(open);break;          
        case sbypass: id(bypass).publish_state(open);break;  
        case schime: id(chime).publish_state(open);break;
        case sbat: id(bat).publish_state(open);break;
        case scheck: id(check).publish_state(open);break;
        case sarmednight: id(night).publish_state(open);break;       
        default: break;
        }
    });
    VistaECP->onZoneStatusChange([&](uint8_t zone, std::string open) {
      switch (zone) {
        case 1: id(z1).publish_state(open); break;
        case 2: id(z2).publish_state(open); break;
        case 3: id(z3).publish_state(open); break;
        case 4: id(z4).publish_state(open); break;
        case 5: id(z5).publish_state(open); break;
        case 6: id(z6).publish_state(open); break;
        case 7: id(z7).publish_state(open); break;
        case 8: id(z8).publish_state(open); break;
        case 17: id(z17).publish_state(open); break;
      }
    });
    VistaECP->onRelayStatusChange([&](uint8_t addr,uint8_t zone,bool open) {
     switch(addr) {
     case 12: switch (zone) {
                case 1: id(r1).publish_state(open); break;
                case 2: id(r2).publish_state(open); break;
              }
              break;
      case 13: break;
      }
    });     
    return {VistaECP};

binary_sensor:
  - platform: template
    id: trouble
    name: "$systemName Trouble"
  - platform: template
    id: bypass
    name: "$systemName Bypass"
  - platform: template
    id: away
    name: "$systemName Away"
  - platform: template
    id: stay
    name: "$systemName Stay"
  - platform: template
    id: instant
    name: "$systemName Instant"
  - platform: template
    id: night
    name: "$systemName Night"
  - platform: template
    id: ac
    name: "$systemName AC"
    device_class: plug  
  - platform: template
    id: chime
    name: "$systemName Chime"
  - platform: template
    id: check
    name: "$systemName Check"
    device_class: problem  
  - platform: template
    id: alarm
    name: "$systemName Alarm"
  - platform: template
    id: bat
    name: "$systemName Battery"
    device_class: problem
  - platform: template
    id: fire
    device_class: smoke
    name: "$systemName Fire"
  - platform: template
    id: ready
    name: "$systemName Ready"
    id: r1
    name: "$systemName Relay1"
  - platform: template
    id: r2
    name: "$systemName Relay2"   
text_sensor:
    #zone definitions
  - platform: template
    id: z1
    name: "$systemName Front door"
  - platform: template
    id: z2
    name: "$systemName Garage door"
  - platform: template
    id: z3
    name: "$systemName Back door"
  - platform: template
    id: z4
    name: "$systemName Living room window"
  - platform: template
    id: z5
    name: "$systemName Dining room window"
  - platform: template
    id: z6
    name: "$systemName Family room window LF"
  - platform: template
    id: z7
    name: "$systemName Family room window RF"
  - platform: template
    id: z8
    name: "$systemName Basement windows"
  - platform: template
    id: z17
    name: "$systemName zone 17"
  - platform: template
    id: system_status
    name: "$systemName System Status"
    icon: "mdi:shield"
  - platform: template
    id: m1
    name: "$systemName Lrr Msg"
    icon: "mdi:alert-box"
switch:
  - platform: template
    name: "$systemName Connection"
    id: connection_status_switch
    lambda: |-
      return vista.keybusConnected;
    icon: "mdi:shield-link-variant"
    turn_on_action:
      - switch.toggle: restart_switch
    turn_off_action:
      - lambda: |-
          disconnectVista();
  - platform: restart
    id: restart_switch

My Modified code that fits 90% of Vista Panel I deploy.

substitutions:
  systemName: "alarmsystem"
  accessCode: !secret access_code
  keypadAddr: "17"
  TTL: "30000"
  quickArm: "true"
  lrrSupervisor: "true"

globals:
     - id: zoneStates
       type: int
       restore_value: yes
     - id: zoneAlarms
       type: int
       restore_value: yes
     - id: zoneBypass
       type: int
       restore_value: yes
     - id: zoneChecks
       type: int
       restore_value: yes      
     - id: lrrCode
       type: int
       restore_value: yes      
esphome:
  name: $systemName
  platform: ESP8266
  board: d1_mini
  includes:
    - vistaEcpInterface/
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "$systemName"
    password: !secret wifi_password
logger:
  baud_rate: 115200
  level: DEBUG
api:
   password: !secret api_password  
ota:
   password: !secret ota_password
   safe_mode: True
status_led:
  pin:
    number: D4
    inverted: yes
custom_component:
- lambda: |-
    auto VistaECP = new vistaECPHome($keypadAddr);
    VistaECP->accessCode="$accessCode";
    VistaECP->quickArm=$quickArm;
    VistaECP->lrrSupervisor=$lrrSupervisor;
    VistaECP->TTL=$TTL;
    VistaECP->debug=1;
    VistaECP->onSystemStatusChange([&](std::string statusCode) {
       id(system_status).publish_state(statusCode);
    });
    VistaECP->onLrrMsgChange([&](std::string msg) {
        id(m1).publish_state(msg); 
    });    
    VistaECP->onStatusChange([&](sysState led,bool open) {
      switch(led) {
        case sfire: id(fire).publish_state(open);break;
        case salarm: id(alarm).publish_state(open);break;
        case strouble: id(trouble).publish_state(open);break;
        case sarmedstay: id(stay).publish_state(open);break;
        case sarmedaway: id(away).publish_state(open);break;
        case sinstant: id(instant).publish_state(open);break; 
        case sready: id(ready).publish_state(open);break; 
        case sac: id(ac).publish_state(open);break;          
        case sbypass: id(bypass).publish_state(open);break;  
        case schime: id(chime).publish_state(open);break;
        case sbat: id(bat).publish_state(open);break;
        case scheck: id(check).publish_state(open);break;
        default: break;
        }
    });
    VistaECP->onZoneStatusChange([&](uint8_t zone, std::string open) {
      switch (zone) {
        case 1: id(z1).publish_state(open); break;
        case 6: id(z6).publish_state(open); break;
        case 9: id(z9).publish_state(open); break;
        case 10: id(z10).publish_state(open); break;
        case 11: id(z11).publish_state(open); break;
        case 12: id(z12).publish_state(open); break;
        case 13: id(z13).publish_state(open); break;
        case 14: id(z14).publish_state(open); break;
        case 15: id(z15).publish_state(open); break;
        case 16: id(z16).publish_state(open); break;
        case 95: id(z95).publish_state(open); break;
        case 96: id(z96).publish_state(open); break;
        case 99: id(z99).publish_state(open); break;
      }
    });
    return {VistaECP};

binary_sensor:
  - platform: template
    id: trouble
    name: "$systemName Trouble"
  - platform: template
    id: bypass
    name: "$systemName Bypass"
  - platform: template
    id: away
    name: "$systemName Away"
  - platform: template
    id: stay
    name: "$systemName Stay"
  - platform: template
    id: instant
    name: "$systemName Instant"
  - platform: template
    id: ac
    name: "$systemName AC"
    device_class: plug  
  - platform: template
    id: chime
    name: "$systemName Chime"
  - platform: template
    id: check
    name: "$systemName Check"
    device_class: problem  
  - platform: template
    id: alarm
    name: "$systemName Alarm"
  - platform: template
    id: bat
    name: "$systemName Battery"
    device_class: problem
  - platform: template
    id: ready
    name: "$systemName Ready" 
text_sensor:
    #zone definitions
  - platform: template
    id: z1
    name: "$systemName Zone1"
  - platform: template
    id: z6
    name: "$systemName Zone6"
  - platform: template
    id: z9
    name: "$systemName Zone9"
  - platform: template
    id: z10
    name: "$systemName Zone10"
  - platform: template
    id: z11
    name: "$systemName Zone11"
  - platform: template
    id: z12
    name: "$systemName Zone12"
  - platform: template
    id: z13
    name: "$systemName Zone13"
  - platform: template
    id: z14
    name: "$systemName Zone14"
  - platform: template
    id: z15
    name: "$systemName Zone15"
  - platform: template
    id: z16
    name: "$systemName Zone16"
  - platform: template
    id: z95
    name: "$systemName Fire"
  - platform: template
    id: z96
    name: "$systemName Police"
  - platform: template
    id: z99
    name: "$systemName Medical"
  - platform: template
    id: system_status
    name: "$systemName System Status"
    icon: "mdi:shield"
  - platform: template
    id: m1
    name: "$systemName Lrr Msg"
    icon: "mdi:alert-box"
switch:
  - platform: template
    name: "$systemName Connection"
    id: connection_status_switch
    lambda: |-
      return vista.keybusConnected;
    icon: "mdi:shield-link-variant"
    turn_on_action:
      - switch.toggle: restart_switch
    turn_off_action:
      - lambda: |-
          disconnectVista();
  - platform: restart
    id: restart_switch

When I was testing it yesterday I ran into an issue when I sent a Medical Alarm so after adding the A, B, C buttons as their proper Zones in the code this fixed it since after all on the Panel those buttons are treated as Zones. Also with the Zone Expanders and Relays in the code even when they were turned off I was plagued with a Zone 0 issue so deleting that out of the code fixed that.

I might have to go deeper in the C code to see what is up.

A Dream “Makers” Computer

At a time these Single Board Computers we love to play with were for the Industrial sector for controlling machinery and niche devices. Since the Raspberry Pi Foundation and every other company trying to hitch a ride on the Single Board Computer craze it got me thinking.
Why not create a Computer board that is the size of a Micro ATX with the same form-factor as a ATX Motherboard and have options to use older parts people like me attend to have laying around such as RAM, ATX Power Supply, Sata Hard Drives and a LVDS port to use old Laptop Screens. With the extra space on the board there could be a foot print to use either a AMD or Intel PC CPU Heatsink and Fan.

I know a lot of Computer Guys have a shoe box or two loaded with DDR2 and DDR3 RAM Modules. Have true RS-232 to play with old Serial hardware. A true Parallel Port so we can hook up old Printers and such.

But how can I access all of the GPIO pins!
I would think having two or three rows of GPIO pins in a parallel configuration so you can attach a Riser board to extend the height to access a row of GPIO leaving two free rows open for Pi compatible Hats that connect via 40pin Ribbon Cables. The Pi Hats can be mounted on brackets that screw into a PC case’s existing Card Slots.

The old 5.25 Drive bays can house simple test equipment such as a Power Supply, Drawers to hold parts and cables, Memory Card Reader and maybe a 16×2 LCD.

Now I’m not saying this would be sold as one product, it could be sold as a whole product but I bet the price would be insane, but sell it piece by piece or as kits that come with the Mainboard and Riser Card. The case, Power Supply and RAM would be BYO.

If that is asking too much then heck make the Compute Module 4 IO Board ATX compatible and have the options described above.

Honeywell Vista Home Assistant Integration – Success

A while back I found a Project on Github that uses ESPHome to talk to a Vista Series Alarm Panel. I talked to the project founder and he assured me it works so I had some PCBs done and I finally got around to putting one together and Programming it.

I had to edit the Code to reflect for my Zones and Sensors. I got it to use my Main Admin Code but I ran into an issue. Since the Panel was installed by me and it is Monitored and I put the system on test and turned off the GSM Radio to make sure things didn’t go insane and call the Cops. I had it hooked up and turned the GSM back on. After a minute or two I sent a Medical Alert signal and the App I use at work assured me it was on test but it took five minutes to get the Signal. I went to clear the Keypad and got a WRONG CODE error and it locked me out of the system for 15 minutes.

I unpluged the Adapter and regained access to the Panel. I looked at the code and did some tweaks and now both Keypad backlights are on constant. I wonder if the Adapter is “pushing buttons”.

However for the quirks it has it works fine in Home Assistant.

Maybe I should put my 6160RF on Address 17 and the Adapter on 16 on the ECP BUS.

Linear Power Supply Building Tips

I like building Power Supplies for my Projects and I like to use the old Linear Power Supply. For one they’re quite and stable as heck. The downside is they’re a bit power hungry.

The basics of a Linear Power Supply is a Step down Transformer, Rectifier and a Smoothing Capacitor. These days it’s better to use a Full Bridge Rectifier and Smoothing Caps that are much higher the Voltage Rating so if you’re building a Power Supply that just needs to power 12 Volts then use 50 Volt Rated Caps.

AC Line Protection
It’s better to use the all-in-one IEC connector that has a built in Fuse and EMI Filter. You also want to add a Safety Cap across the Line and from Neutral to Ground. Make sure it is fused and to kill the power to both Live and Neutral.

Typical Schematic for non-regulated power supply, I labeled the Safety Caps kinda funky, use X2 and Y2 rated Caps.

From left to right we have the following components.
AC Mains coming in passes through a EMI Filter that passes through some Safety Caps that goes Across the Line and from Neutral to Chassis Ground. A SPST Switch that switches the Live and Neutral ON/OFF and with a Fuse on the Live Wire. From there it goes into a Stepdown Transformer that turns 110 Mains into a Low Voltage Secondary and shown above is also Isolated from the AC Mains Primary (IE: Floating Ground) that then feeds into a Full Bridge Rectifier and finally into a Smoothing Cap.

Grounding
When grounding the Mains you want to use toothed lock washers when attaching it to a metal chassis. You want it to bite into the Metal so Vibrations can’t loosen it and also in most cases can get through the Paint into bare metal. If anything sand off to bare metal for your Chassis Ground. Best practice is to use the correct wiring color scheme.

Wiring
Typical North American wiring standards use 18 to 16 gauge copper wire. Polarized Two Prong cable are is Black for Live and White for Neutral. Three Prong is the same but the third wire is Green that is Earth Ground. Try and keep the wire short as possible inside of the Chassis and it is good Practice to twist the Live and Neutral together to stop transient EMI. Rule of thumb is to twist it 6 times per foot.
If you happen to use an old Computer IEC cable and you see Blue, Brown and Green with a yellow stripe it’s using the European Color Code.
Brown = Live
Blue = Neutral
Green with Yellow = Earth

In all you can find IEC Filters that already have built in safety caps and power switches but chances are the switch only switches the Live leg. Keep the Low Voltage stuff away from the High Voltage as much as possible and keep the high voltage lines short as possible. Be sure to double up on the Heatshrink. and if you’re using a Transformer with open air taps be sure to use electrical grade plastics to isolate it from Metal.

3D Printed parts and Cabinet equals trouble

So, I had printed out a Adapter to convert my Ender3 to Direct Drive. I used PETG since I know PLA overtime will warp. The Printer is in my Cabinet and it honestly gets plenty of airflow and I kept the Door open but when I woke up this morning after leaving the Printer on overnight printing a case for my Mini Power Supply the Adapter melted from the Hotend and was flopped over and the Print was halfway done.

Since it’s Black Friday and Amazon has had their Cyber Sell going on for a while I saw a Direct Drive kit for ten bucks. Comes with a Aluminum plate and Capricorn Tube.

Control Panel – Software Configuration part 1

We need to make Home Assistant able to access a Computer to launch BASH Scripts using the command_line integration.

Since I am running Home Assistant Core on Docker I don’t have the Supervisor options so I have to ssh into the Server running Docker and drop into the Home Assistant Container Shell. So here is a example.

ssh user@10.10.10.10
user@10.10.10.10's password: XXXXXX
docker ps | grep homeassistant
81b764f18c58        homeassistant/home-assistant:stable   "/init"                  4 days ago          Up 3 days                                                  homeassistant

docker exec -it 81b764f18c58 bash
bash-5.0#

What I did here was log into my Server running Docker then ran the docker ps command that will list all of my Containers but I piped it into Grep to only list Home Assistant so I can see the Container ID 81b764f18c58. I then ran docker exec -it 81b764f18c58 bash to drop into a Shell inside the Container.
Keep in mind this logs you in as Root in the container and Home Assistant uses Root.

Now we need to create a SSH Key to be able to access the PC we want without needing to use a password for each time it connects to it.

Just run ssh-keygen and just follow the defaults and leave the passphrase empty. Now we need to copy the Key. To do this issue something like this, be sure to change the User and IP address to match your layout/setup.

ssh-copy-id -i $HOME/.ssh/id_rsa.pub user@10.10.10.20

Enter your User’s password and you should see this.

Number of key(s) added: 1

Do a test by logging in and it shouldn’t ask you for a password.

On the PC we want to control we need to make sure xdotool is installed. Since I use Debian it uses APT as the Package Manager.

apt install xdotool

Now some Keyboard Macros need to be created on the PC we want to Control. For a example with KDE Plasma I used the Custom Shortcuts menu and right clicked then selected New > then Global Shortcut > then Command/URL. For this example we will do Terminator Shell. So label it as Terminal. Under Trigger I selected CTRL+1 and under Action I just entered terminator. Hit Apply and test it by hitting CTRL 1

Now the easy part. In the Home Assistant Configuration.yaml file we need to create a Switch.

switch:
  - platform: command_line
    switches:
      terminal_launch:
        command_on: ssh -X user@10.10.10.20 "DISPLAY=:0 xdotool key ctrl+1"
        command_off: exit
  - platform: command_line
    switches:
      terminal_close:
       command_on: ssh -X user@10.10.10.20 "DISPLAY=:0 pkill terminator"
       command_off: exit 

The command_on: statements is having HA login with SSH with Xforwarding and we are telling it run the command xdotool key ctrl+1. Since this is doing it remotely we need to tell it to do this to the main screen of the PC and that is when DISPLAY=:0 comes in.
As you can see there are two switches, one to Launch Terminator and one to Close Terminator. There are many ways to make Terminator to close but pkill seems the easiest but beware if you have two or more terminator processes running pkill will close them all.

After creating the two switches you need to restart Home Assistant.

Since the Control Panel running Room-Assistant is just forcing the GPIO to switch high or low with the toggle switches they’re programmed as Binary Switches.

Example Room-Assistant local.yml file

global:
   instanceName: controlpanel
   integrations:
     - homeAssistant
     - gpio
 homeAssistant:
   mqttUrl: 'mqtt://10.10.10.10:1883'
   mqttOptions:
     username: user
     password: password
 gpio:
   binarySensors:
     - name: controlswitch1
       pin: 4
     - name: controlswitch2
       pin: 17

So in Home Assistant it sees it as binary_sensor.controlswitch1 and binary_sensor.controlswitch2.

In Home Assistant we need to create two Automations. You can do it the graphical way but I’m hardcore and use the Command Line and Nano.

alias: Terminal Launch
 description: 'Terminal Launch'
 trigger:
 platform: state
 entity_id: binary_sensor.controlswitch2
 from: 'off'
 to: 'on'
 condition: []
 action:
 service: switch.toggle
 data: {}
 entity_id: switch.terminal_launch
 mode: single

alias: Terminal Close
 description: 'Terminal Close'
 trigger:
 platform: state
 entity_id: binary_sensor.controlswitch1
 from: 'off'
 to: 'on'
 condition: []
 action:
 service: switch.toggle
 data: {}
 entity_id: switch.terminal_close
 mode: single 

After saving the file you can either restart Home Assistant again or just tell it to reload the Automations.

If you want to control other things that is already in Home Assistant you just create a Automation and call a service to switch.turn_on switch.turn_off or switch.toggle.
For a example controlling the Garage Lights.

alias: controlpanel_garage_light_on
 description: ''
 trigger:
 platform: state
 entity_id: binary_sensor.controlswitch14
 from: 'off'
 to: 'on'
 condition: []
 action:
 service: switch.turn_on
 data: {}
 entity_id: switch.garage_light
 mode: single

alias: controlpanel_garage_light_off
 description: ''
 trigger:
 platform: state
 entity_id: binary_sensor.controlswitch15
 from: 'off'
 to: 'on'
 condition: []
 action:
 service: switch.turn_off
 data: {}
 entity_id: switch.garage_light
 mode: single 

Now that is pretty darn cool if you ask me.

Later on I will refine the code and show other things this simple Control Panel can do.

Control Panel – Oops

So when I tested the Control Panel last night it was working great. Since I had the Pi connected to my Main Desktop’s USB Port it was powered down over night. Came home and powered up the PC then went to show one of the Kids the progress and the Pins are floating. So now I should of listened to myself in the beginning and use Pull Down Resistors.

Not to worry, I can easily make a “Pi Hat” with some 10K resistors and some Headers and I’ll be good to go.

Control Panel – Hardware Done

I found some Rainbow Ribbon Cable and made a wire harness for the Pi.

When I tested it by having Home Assistant open and showing the ControlSwitch Entities a few switches were not registering. I did a Continuity test and it all tests fine. My guess some of the GPIO pins are already set High.

Here is the finished semi finished product all Soldered together.

I plan to use either use double sided tape to secure the Pi in or use standoffs. The case isn’t going to have a back on it. I plan to keep the Control Panel on the right side of the Desk.

To be funny I might add a Red LED in the middle second row as a Power Indicator.

If you ever seen IT Crowd you’ll get the joke.

Fun part during Thanksgiving is programming everything.

Control Panel – Build

I found a old RadioShack Project Box and decided to use it for now.

I wired up a Power Bus Bar to the switches that have 3.3v from the Pi Zero.

Before continuing I wanted to test things and I found out I don’t need the Resistors. Just apply the 3.3V directly to the GPIO Pin. I also found out the Room-Assistant uses the actual GPIO Pin numbers rather then the Pin placement numbers.

Test
Project Box

Down the road I plan to make the Control Panel look like the front end of a Mits Altair 8800 but with a twist.

I ran into a few issues programming Room-Assistant. I spent time in two Discord Home Assistant chat rooms that had over 4940 users and for thirty minutes no answer let alone anyone talking in there. I got fed up and told off one of the chat rooms that quickly had the mods in there ranting at me. Not my fault there chat rooms are nothing but Bots and people AFK. Last time I use Discord for help.

Anyway, I figured it out and now Home Assistant sees the Pi and all of my Binary Sensors.

Now I just need to wire up some Dupont Cables and the Hardware portion will be complete for now.