Category Archives: nerdstuff

The X6200, initial thoughts.

The Xiegu X6200 arrived this morning, a few days earlier than was projected when it shipped.  So far I like it.  I’ve made a couple of contacts to POTA stations this afternoon over my lunch break, both at 5W and 8W, using the built in microphone and using the handheld one.  Except for band conditions being rather bad, I had no issues.

After the work day ended, I grabbed the 9:1 end fed “random” wire antenna, the 10m mast, some feedline, and headed to the back yard.

The internal tuner had no issues with the 9:1 from 40 to 10m.  Even with the display brightness turned down as far as it could go, the screen was readable in direct sunlight.

I have a sneaky suspicion that this is going to turn into my default POTA rig.  We’ll see.  I may even try to activate a park tomorrow night…

docker-compose.org

This docker-compose.org file lives at /opt/docker-compose.org and is used to generate the /opt/docker-compose.yaml file that spins up all of the services here.

Heading

The :tangle has to be defined here, NOT in the header of the org file.

#+begin_src yaml :tangle "docker-compose.yaml" :noweb yes

If you try to set it in the header, you will get a broken yaml file. ( emacs versions 28 and 29 and the org-mode that comes with them )

Each begin_src has a :noweb-ref NAME definition that is referenced here.

So a simple way to remove a service is to just remove the reference to it from this block.

---
# this file is generated from docker-compose.org
# DO NOT EDIT and expect changes to persist
version: '3.3'
networks:
  <<networking>>
secrets:
  <<secrets>>
services:
  <<nextcloud>>
  <<gitea>>
  <<jellyfin>>
  <<portainer>>
  <<homeassistant>>
  <<pihole>>
  <<mosquitto>>
  <<zigbee2mqtt>>
  <<esphome>>

Networking

brygge_macvlan:
  name: dockervlan
  driver: macvlan
  driver_opts:
    parent: enp1s0
    macvlan_mode: bridge
  ipam:
    config:
      - subnet: 172.27.1.0/24
        gateway: 172.27.1.1
        ip_range: 172.27.1.64/27

macvlan.sh

This is a script that allows for docker containers on a macvlan to be able to communicate with each other and the docker host.

brygge is the hostname for this particular system, and enp1s0 is the ethernet interface.

#!/bin/sh

# https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/


# called by /etc/systemd/system/macvlan.service
# [Service]
# Type=simple
# ExecStart=/bin/sh /opt/macvlan.sh

# [Install]
# WantedBy=multi-user.target


# systemctl enable macvlan

PATH=/bin:/usr/bin:/sbin:/usr/sbin

ip link add brygge_macvlan link enp1s0 type macvlan mode bridge
ip addr add 172.27.1.64/24 dev brygge_macvlan
ip link set brygge_macvlan up
ip route add 172.27.1.64/27 dev brygge_macvlan

macvlan.service

To enable on system start systemctl enable macvlan

[Service]
Type=simple
ExecStart=/bin/sh /opt/macvlan.sh

[Install]
WantedBy=multi-user.target

Secrets

Keep secrets in these local files, not great, but better than in the docker-compose.yaml file! These files have JUST the super secret information in them, nothing else.

We reference them later by setting the secrets entry in the needed service. Notice the _FILE added to the end of the environment entry.

nextcloud_db_pass:
  file: ./nextcloud_db_pass.txt
gitea_db_pass:
  file: ./gitea_db_pass.txt
pihole_web_pass:
  file: ./pihole_web_pass.txt

Nextcloud

nextcloud:
  image: nextcloud
  container_name: nextcloud
  restart: always
  ports:
    - "80:80"
  volumes:
    - /opt/nextcloud/html:/var/www/html
  secrets:
    - nextcloud_db_pass
  environment:
    - USER_UID=33
    - USER_GID=33
    - MYSQL_PASSWORD_FILE=/run/secrets/nextcloud_db_pass
    - MYSQL_DATABASE=nextcloud
    - MYSQL_USER=nextcloud
    - MYSQL_HOST=172.27.1.19:3306
  networks:
    brygge_macvlan:
      ipv4_address: 172.27.1.69

gitea

gitea:
  image: gitea/gitea:latest
  container_name: gitea
  secrets:
    - gitea_db_pass
  environment:
    - USER_UID=1001
    - USER_GID=1001
    - GITEA__database__DB_TYPE=mysql
    - GITEA__database__HOST=172.27.1.19:3306
    - GITEA__database__NAME=gitea
    - GITEA__database__USER=gitea
    - GITEA__database__PASSWD_FILE=/run/secrets/gitea_db_pass
  restart: always
  networks:
    brygge_macvlan:
      ipv4_address: 172.27.1.68
  volumes:
    - /opt/gitea/data:/data
    - /etc/timezone:/etc/timezone:ro
    - /etc/localtime:/etc/localtime:ro
  ports:
    - "3000:3000"
    - "22:22"

Jellyfin

jellyfin:
  image: jellyfin/jellyfin
  container_name: jellyfin
  user: 1000:1000
  volumes:
    - /opt/jellyfin/config:/config
    - /opt/jellyfin/cache:/cache
    - /storage/Media:/media
  ports:
    - 8096:8096
    - 8920:8920
    - 7359:7359/udp
    - 1900:1900/udp
  networks:
    brygge_macvlan:
      ipv4_address: 172.27.1.67
  restart: unless-stopped

Portainer

portainer:
  container_name: portainer
  image: portainer/portainer-ce
  restart: always
  ports:
    - "9000:9000/tcp"
  environment:
    - TZ=America/Chicago
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - /opt/portainer:/data

HomeAssistant

homeassistant:
  container_name: homeassistant
  image: "ghcr.io/home-assistant/home-assistant:stable"
  volumes:
    - /opt/homeassistant/config:/config
    - /etc/localtime:/etc/localtime:ro
  restart: unless-stopped
  privileged: true
  network_mode: host

Pi-Hole

pihole:
  container_name: pihole
  image: pihole/pihole:latest
  ports:
    - "53:53/tcp"
    - "53:53/udp"
    - "80:80/tcp"
  environment:
    TZ: 'America/Chicago'
    WEBPASSWORD_FILE: /run/secrets/pihole_web_pass.txt
  volumes:
    - /opt/pihole/config/etc:/etc/pihole
    - /opt/pihole/config/dnsmasq.d:/etc/dnsmasq.d
    - /opt/pihole/config/resolv.conf:/etc/resolv.conf
  networks:
    brygge_macvlan:
      ipv4_address: 172.27.1.65
  restart: unless-stopped

Mosquitto

mosquitto:
  image: eclipse-mosquitto
  container_name: mosquitto
  volumes:
    - /opt/mosquitto:/mosquitto
    - /opt/mosquitto/data:/mosquitto/data
    - /opt/mosquitto/log:/mosquitto/log
  ports:
    - 1883:1883
    - 9001:9001

zigbee2mqtt

zigbee2mqtt:
  container_name: zigbee2mqtt
  image: koenkk/zigbee2mqtt
  restart: unless-stopped
  volumes:
    - /opt/zigbee2mqtt/data:/app/data
    - /run/udev:/run/udev:ro
  ports:
    - 8080:8080
  environment:
    - TZ=America/Chicago
  devices:
    - /dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2599684-if00:/dev/ttyACM0
  depends_on:
    - mosquitto

ESPHome

esphome:
  container_name: esphome
  image: ghcr.io/esphome/esphome
  volumes:
    - /opt/esphome/config:/config
    - /etc/localtime:/etc/localtime:ro
  restart: unless-stopped
  networks:
    brygge_macvlan:
      ipv4_address: 172.27.1.66

My thanks to Adam Jackson for pointing me at this stackoverflow article as a solution to the issues I was having with tangling yaml content in orgmode.

The Pico Pedal

One of the projects that I have been meaning to work on for a while is a foot pedal to use with discord, which for those that are not aware is a text and voice communications application. Most of the time when I am using discord for voice communications, I don’t really want to be using a push-to-talk key to be able to talk to people, mostly because I’m usually busy pushing other keys on the keyboard. My original plan was to use an arduino, but then I found out about the RaspberryPi Pico.

The appealing thing to me about the Pico is that it can run python code. So I ordered a couple of Picos, snagged a generic footswitch off of amazon, and waited for the parts to arrive.

Since I don’t have anything to use as a case currently, I soldered the two wires directly to the board, and then used some string through the mounting holes to secure the board to the end of the cord from the pedal.

picopedal_resize.jpg

The code was pretty simple after reading the documentation for the adafruit_hid library. Whenever I use the footswitch, it sends the keypress for the menu, or application, key.

EDIT 2021-09-29: Discord wouldn’t let me use the Keycode.APPLICATION anymore, so after some trial and error I was able to use Keycode.F24 instead.

import time
import digitalio
import board
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard import Keycode

keyboard = Keyboard(usb_hid.devices)
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT

led.value = False

foot_switch = digitalio.DigitalInOut(board.GP0)
foot_switch.direction = digitalio.Direction.INPUT
foot_switch.pull = digitalio.Pull.DOWN

while True:
    if foot_switch.value:
    led.value = True
    # keyboard.press(Keycode.APPLICATION)
    keyboard.press(Keycode.F24)
else:
    # keyboard.release(Keycode.APPLICATION)
    keyboard.release(Keycode.F24)
    led.value = False
time.sleep(0.1)