18 Feb 2022

Download the Apothecary MicroLab Plans

Download the Apothecary MicroLab Plans, a bioreactor to make your own medecine to thwart Big Pharma’s price-gouging.

18 Jan 2022

Automatically Start/Stop Motion Activated Camera When Cellphone Not On Local Network

Automatically Start/Stop Motion Activated Camera When Cellphone Not On Local Network

Note: This Systemd service will detect if your mobile phone is on the local network using ping, therefore, it should have a static IP address when it connects to your Wi-Fi network.

  1. ~/.config/systemd/user/surveillance-system.service

     [Unit]
     Description=Automatically Start/Stop Surveillance System if phone not on local network
     Wants=surveillance-system.timer
    
     [Service]
     Type=simple
     ExecStart=/home/USERNAME/.config/systemd/user/start-motion-detection.sh
    
     [Install]
     WantedBy=multi-user.target
    
  2. ~/.config/systemd/user/surveillance-system.timer (check for mobile phone presence every minute)

     [Unit]
     Description=Automatically Start/Stop Surveillance System if phone not on local network
    
     [Timer]
     OnCalendar=*:0/1
    
     [Install]
     WantedBy=timers.target
    
  3. ~/.config/systemd/user/start-motion-detection.sh

     #!/bin/bash
     XDG_RUNTIME_DIR=/run/user/$(id -u)
     DBUS_SESSION_BUS_ADDRESS=unix:path=${XDG_RUNTIME_DIR}/bus
     export DBUS_SESSION_BUS_ADDRESS XDG_RUNTIME_DIR
    
     ping -W 1 -c 1 192.168.0.20 > /dev/null
     if [ $? -ne 0 ]; then # Host is down, start motion
       echo "Host is down..."
         if pgrep -x "motion" >/dev/null
         then
           echo "Motion already running..."
         else
           echo "Motion is not running, sarting it..."
           motion
         fi
    
     else # Host is up, stop processes
       echo "Host is up..."
       if pgrep -x "motion" >/dev/null
       then
         echo "Stopping Motion..."
         killall motion
       else
         echo "Motion is not running."
       fi
     fi
    
  4. Commands to start the service and check its status:

     systemctl --user enable surveillance-system.timer --now
     systemctl --user start surveillance-system.timer --now
     systemctl --user list-timers
     systemctl --user status surveillance-system
    
  5. I hade issues where the phone would not connect to Wi-Fi fast enought when I was in range of the router, and it helped when I did this:

    In LineageOS 18.1 > Network & internet > Wi-Fi > Wi-Fi preferences > toggle On: Turn on Wi-Fi automatically: “Wi-Fi will turn back on near high-quality saved networks, like your home network”. (unfortunately, this requires location to be turned ON, also)

18 Jan 2022

Motion Activated Security Camera With Audio Backed Up To VPS

Motion Activated Security Camera With Audio Automatically Backed Up To VPS

This will be achieved using the great softwares motion and ffmpeg.

  1. Create ~/.motion/motion.conf (at least the camera resolution and USERNAME in paths should be edited and possibly the sensitivy of the motion detection)

     # Rename this distribution example file to motion.conf
     #
     # This config file was generated by motion 4.4.0
     # Documentation:  /usr/share/doc/motion/motion_guide.html
     #
     # This file contains only the basic configuration options to get a
     # system working.  There are many more options available.  Please
     # consult the documentation for the complete list of all options.
     #
    
     ############################################################
     # System control configuration parameters
     ############################################################
    
     # Start in daemon (background) mode and release terminal.
     daemon off
    
     # Start in Setup-Mode, daemon disabled.
     setup_mode off
    
     # File to store the process ID.
     ; pid_file value
    
     # File to write logs messages into.  If not defined stderr and syslog is used.
     ; log_file value
    
     # Level of log messages [1..9] (EMG, ALR, CRT, ERR, WRN, NTC, INF, DBG, ALL).
     log_level 6
    
     # Target directory for pictures, snapshots and movies
     target_dir /home/USERNAME/motion
    
     # Video device (e.g. /dev/video0) to be used for capturing.
     video_device /dev/video0
    
     # Parameters to control video device.  See motion_guide.html
     ; vid_control_params value
    
     # The full URL of the network camera stream.
     ; netcam_url value
    
     # Name of mmal camera (e.g. vc.ril.camera for pi camera).
     ; mmalcam_name value
    
     # Camera control parameters (see raspivid/raspistill tool documentation)
     ; mmalcam_control_params value
    
     ############################################################
     # Image Processing configuration parameters
     ############################################################
    
     # Image width in pixels.
     width 1920
    
     # Image height in pixels.
     height 1080
    
     # Maximum number of frames to be captured per second.
     framerate 15
    
     # Text to be overlayed in the lower left corner of images
     text_left CAMERA1
    
     # Text to be overlayed in the lower right corner of images.
     text_right %Y-%m-%d\n%T-%q
    
     ############################################################
     # Motion detection configuration parameters
     ############################################################
    
     # Always save pictures and movies even if there was no motion.
     emulate_motion off
    
     # Threshold for number of changed pixels that triggers motion.
     threshold 11000
    
     # Noise threshold for the motion detection.
    
     noise_level 32
    
     # Despeckle the image using (E/e)rode or (D/d)ilate or (l)abel.
     despeckle_filter EedDl
    
     # Number of images that must contain motion to trigger an event.
     minimum_motion_frames 1
    
     # Gap in seconds of no motion detected that triggers the end of an event.
     event_gap 1
    
     # The number of pre-captured (buffered) pictures from before motion.
     pre_capture 0
    
     # Number of frames to capture after motion is no longer detected.
     post_capture 20
    
     ############################################################
     # Script execution configuration parameters
     ############################################################
    
    
     # save microphone straight to vps: ffmpeg -nostdin -f alsa -i pulse -c:a libmp3lame -ar 44100 -b:a 128k -ac 1 -f mp3 - | ssh -C vps "cat - > /var/www/cams/output-$(date '+%s').mp3"
     on_event_start ffmpeg -nostdin -f alsa -i pulse -c:a libmp3lame -ar 44100 -b:a 128k -ac 1 -f mp3 /home/USERNAME/motion/%Y%m%d%H%M%S.mp3 &
    
     # merge video and audio : ffmpeg -i 20220105202755.mkv -i 20220105202755.mp3 -c:v copy -c:a aac output.mkv
     # on_event_end  pkill -f ffmpeg ; /usr/bin/rsync -av --delete --progress /home/USERNAME/motion/ vps:/var/www/motion/ #USE SCRIPT BELOW INSTEAD
     on_event_end /home/USERNAME/.motion/event_end.sh
    
    
     # Command to be executed when a movie file is closed.
     ; on_movie_end value
    
     ############################################################
     # Picture output configuration parameters:
     ############################################################
    
     # Output pictures when motion is detected
     picture_output off
    
     # File name(without extension) for pictures relative to target directory
     picture_filename %Y%m%d%_H%M%S-%q
    
     ############################################################
     # Movie output configuration parameters
     ############################################################
    
     # Create movies of motion events.
     movie_output on
    
     # Maximum length of movie in seconds.
     movie_max_time 60
    
     # The encoding quality of the movie. (0=use bitrate. 1=worst quality, 100=best)
     movie_quality 0
    
     # Container/Codec to used for the movie. See motion_guide.html
     movie_codec mkv
    
     # File name(without extension) for movies relative to target directory
     movie_filename %Y%m%d%_H%M%S
    
     ############################################################
     # Webcontrol configuration parameters
     ############################################################
    
     # Port number used for the webcontrol.
     webcontrol_port 8080
    
     # Restrict webcontrol connections to the localhost.
     webcontrol_localhost on
    
     # Type of configuration options to allow via the webcontrol.
     webcontrol_parms 0
    
     ############################################################
     # Live stream configuration parameters
     ############################################################
    
     # The port number for the live stream.
     stream_port 8081
    
     # Restrict stream connections to the localhost.
     stream_localhost on
    
     ##############################################################
     # Camera config files - One for each camera.
     ##############################################################
     ; camera /usr/etc/motion/camera1.conf
     ; camera /usr/etc/motion/camera2.conf
     ; camera /usr/etc/motion/camera3.conf
     ; camera /usr/etc/motion/camera4.conf
    
     ##############################################################
     # Directory to read '.conf' files for cameras.
     ##############################################################
     ; camera_dir /usr/etc/motion/conf.d
    
  2. Create ~/.motion/event_end.sh and make it executable

     #!/bin/bash
    
     echo "Killing ffmpeg... (stop audio recording)"
     pkill -2 ffmpeg
     echo "Copying files to VPS..."
     /usr/bin/rsync -av --delete --progress /home/USERNAME/motion/ vps:/var/www/motion/
    

18 Jan 2022

Photos - Mexican Masks Portray Covid/Corona Virus

Photos - Mexican Masks

PHOTOS: Mexican Masks Portray COVID As A Tiger, A Devil, A Blue-Eyed Man

mexican corona mask

23 Aug 2021

Flite Test FT Dart Letter Size

Flite Test FT Dart Letter Size PDF

Print at 100% scale on letter paper and double check the scale on first page (Original A4 File).

02 Apr 2021

Combine WAV files using FFmpeg

Combine WAV files using FFmpeg

ffmpeg -i input1.wav -i input2.wav -i input3.wav \
-filter_complex '[0:0][1:0][2:0]concat=n=4:v=0:a=1[out]' \
-map '[out]' output.wav

02 Apr 2021

Create video from WAV file and use an image as the background using FFmpeg

Create video from WAV file and use an image as the background using FFmpeg

ffmpeg -loop 1 -y -i image.png -i input.wav -shortest -acodec copy -vcodec mjpeg result.avi

05 Jun 2019

Bash Script to Automatically Restart and Resume Failed rsync Transfers

Bash Script to Automatically Restart and Resume Failed rsync Transfers

#!/bin/bash
# automatically restart and resume rsync transfer on failure
 
while [ 1 ]
do
    rsync --progress --partial-dir=.rsync-partial rsync://site.onion/dir/Inventory1.rar ./
    if [ "$?" = "0" ] ; then
        echo "rsync completed normally"
        exit
    else
        echo "rsync failure. Retrying soon..."
        sleep 30
    fi
done

05 Apr 2019

Setup password-store on multiple computers using gitlab for synchronizing password repository

Setup pass on multiple computers

Instructions:

  1. Create GPG Key

     gpg --full-generate-key
     gpg -k
     gpg --export-secret-key 6002450973C62F2FD9F8353101C4ECCB53ACCE05 > key-gpg-pws.private
    

    Note: Copy the private key to all of your devices.

  2. Initialize git repository on first computer and gitlab (create new project on gitlab first)

     pass init 6002450973C62F2FD9F8353101C4ECCB53ACCE05
     pass git init
     pass git remote add origin ssh://git@gitlab.com/username/pws
     pass insert email/gmail.com
     pass insert forum/reddit.com
     pass git push origin master
    
  3. Setup additional computer

     gpg --import 6002450973C62F2FD9F8353101C4ECCB53ACCE05
     git clone ssh://git@gitlab.com/username/pws ~/.password-store
    

Compatible client list can be found at: https://www.passwordstore.org/ (including ones for Android and iOS)

Note: I will probably go with Bitwarden or KeepassXC instead because this one would not encrypt the paths to the passwords…

03 Jul 2018

Door Alarm Using ESP8266, MicroPython and a Reed Switch (Email Alerts)

Get email alerts when a door is opened or closed.

Requirements: ESP8266 compatible board, a Reed switch, a magnet, some wires and a USB cable (and a computer).

Schematic: One side of the reed switch connected to the ground and the other side to Pin D1 of the D1-Mini board (Pin 5 for ESP8266) and a 10k Ohm pull-up resistor. Schematic, D1-Mini/Reed Switch

Instructions:

  1. Install MicroPython on your ESP8266 board:

    • Connect board to your computer using a USB cable

    • Download MicroPython’s current firmware:

    • Install esptool:

        pip install --user esptool
      
    • Install ampy (Fedora):

        sudo dnf install ampy
      
    • Erase board’s flash:

        esptool.py --port /dev/ttyUSB0 erase_flash
      
    • Install new firmware:

        esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-20xxxxxx-vx.x.x.bin
      
  2. Setup webrpl

     picocom /dev/ttyUSB0 -b115200 -t "$(echo -ne '\r\nimport webrepl_setup\r\n')"
     press <e> and set your_password
     press <y> to reboot
    
  3. Install alarm code (the code can be found below):

    • Setup the board to act as a Wi-Fi client at boot time (change SSID and wifi_password before uploading):

        ampy --port /dev/ttyUSB0 put boot.py
      
    • Install alarm code (change email and email_password):

        ampy --port /dev/ttyUSB0 put main.py
      
    • Reboot board to make changes effective:

        picocom /dev/ttyUSB0 -b115200 -t "$(echo -ne '\r\nimport machine\r\nmachine.reset()\r\n')"
      

boot.py (setup webrepl and Wi-Fi):

import gc
import webrepl
import network

# change the value of the 2 variables below
ssid = "your_SSID"
pwd  = "wifi_password"

webrepl.start()
gc.collect()
sta_if = network.WLAN(network.STA_IF)
ap_if  = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
  print('Connecting to WiFi...')
  sta_if.active(True)
  sta_if.connect(ssid, pwd)
  while not sta_if.isconnected():
    pass$
print('network config:', sta_if.ifconfig()

main.py (credit):

import machine
from time import sleep
# Micropython
try:
  import usocket as socket
  import ussl as ssl

# Python3
except:
  import socket
  import ssl

try:
    switch = machine.Pin(5, machine.Pin.IN) # D1/GPIO5
except:
    print("s:e")
    switch = 0 # open

prevValue      = 0
doorOpenTimer  = 0
email_user     = "user@gmail.com"
email_pwd      = "my_password"
email_user_b64 = "xxxxxxxxxxxxxxxxxxxxxx=" # base64 encoded email    (echo -n 'user@gmail.com' | base64)
email_pwd_b64  = "xxxxxxxxxxxxxxxxxxxxxx=" # base64 encoded password (echo -n 'my_password' | base64)

def send_email(username, subject, body):
    msg = """To: {0}\r\nSubject: {1}

    {2}
    """
    msg = msg.format(username,subject,body)

    endmsg = "\r\n.\r\n"

    mailserver = "smtp.gmail.com"
    port = 587

    # Create socket called clientSocket and establish a TCP connection with mailserver
    clientSocket = socket.socket()
    clientSocket.connect(socket.getaddrinfo(mailserver, port)[0][-1])
    recv = clientSocket.recv(1024)
    print(recv)
    print(recv[:3])
    if recv[:3] != b'220':
        print('220 reply not received from server.')

    # Send HELO command and print server response.
    heloCommand = 'EHLO Alice\r\n'
    clientSocket.send(heloCommand.encode())
    recv1 = clientSocket.recv(1024)
    recvCount=recv1.decode().count('\n')
    print(recv1)
    if recv1[:3] != b'250':
        print('250 reply not received from server.')

    # Request an encrypted connection
    startTlsCommand = 'STARTTLS\r\n'
    clientSocket.send(startTlsCommand.encode())
    tls_recv = clientSocket.recv(1024)
    print(tls_recv)
    if tls_recv[:3] != b'220':
        print('220 reply not received from server')

    # Encrypt the socket
    ssl_clientSocket = ssl.wrap_socket(clientSocket)
    print("Secure socket created")

    heloCommand = 'EHLO Alice\r\n'
    ssl_clientSocket.write(heloCommand.encode())
    recv1=''
    for index in range(0,recvCount):
      recv1 = recv1+ssl_clientSocket.readline().decode()
    print(recv1)

    # Send the AUTH LOGIN command and print server response.
    authCommand = 'AUTH LOGIN\r\n'
    ssl_clientSocket.write(authCommand.encode())
    auth_recv = ssl_clientSocket.readline()
    print(auth_recv)
    if auth_recv[:3] != b'334':
        print('334 reply not received from server')

    print("Sending username / password")
    # Send username and print server response.
    uname = email_user_b64 # base64 encoded email
    pword = email_pwd_b64  # base64 encoded password
    print(str(uname))
    ssl_clientSocket.write(uname)
    ssl_clientSocket.write('\r\n'.encode())
    uname_recv = ssl_clientSocket.readline()
    print(uname_recv)
    if uname_recv[:3] != b'334':
        print('334 reply not received from server')
    print(str(pword))
    ssl_clientSocket.write(pword)
    ssl_clientSocket.write('\r\n'.encode())
    pword_recv = ssl_clientSocket.readline()

    print(pword_recv)
    if pword_recv[:3] != b'235':
        print('235 reply not received from server')

    # Send MAIL FROM command and print server response.
    mailFromCommand = 'MAIL FROM: <' + username + '>\r\n'
    ssl_clientSocket.write(mailFromCommand.encode())
    recv2 = ssl_clientSocket.readline()
    print(recv2)
    if recv2[:3] != b'250':
        print('250 reply not received from server.')

    # Send RCPT TO command and print server response.
    rcptToCommand = 'RCPT TO: <' + username + '>\r\n'
    ssl_clientSocket.write(rcptToCommand.encode())
    recv3 = ssl_clientSocket.readline()
    print(recv3)
    if recv3[:3] != b'250':
        print('250 reply not received from server.')

    # Send DATA command and print server response.
    dataCommand = 'DATA\r\n'
    ssl_clientSocket.write(dataCommand.encode())
    recv4 = ssl_clientSocket.readline()
    print(recv4)
    if recv4[:3] != b'354':
        print('354 reply not received from server.')

    # Send message data.
    ssl_clientSocket.write(msg.encode())

    # Message ends with a single period.
    ssl_clientSocket.write(endmsg.encode())
    recv5 = ssl_clientSocket.readline()
    print(recv5)
    if recv5[:3] != b'250':
        print('250 reply not received from server.')

    # Send QUIT command and get server response.
    quitCommand = 'QUIT\r\n'
    ssl_clientSocket.write(quitCommand.encode())
    recv6 = ssl_clientSocket.readline()
    print(recv6)
    if recv6[:3] != b'221':
        print('221 reply not received from server.')

    clientSocket.close()

while True:
    sleep(1)
    print("s.v.: " + str( switch.value() ) )
    if prevValue != switch.value():
        if switch.value() == 0: # door opened
            send_email(email_user, "Door Opened", prevValue)
        if switch.value() == 1: # door closed
            send_email(email_user, "Door Closed", prevValue)
        try:
            prevValue = switch.value()
        except:
            prevValue = -1

25 May 2017

Fedora 25: Fix iptables rules after replacing the firewalld service with iptables.service

If the internet is not working in your Gnome Boxes/qemu virtual machine guest after replacing the firewalld service with the iptables.service in the host OS, it might be because the iptables rules relating to the virbr0 interface and the 192.168.122.0/24 network are missing.

Edit /etc/sysconfig/iptables

:~$ sudo vim /etc/sysconfig/iptables

Add the following lines before the line : -A INPUT -j REJECT –reject-with icmp-host-prohibited

-A INPUT -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A FORWARD -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A FORWARD -i virbr0 -o virbr0 -j ACCEPT
-A FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
-A FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A POSTROUTING -o virbr0 -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
-A POSTROUTING -s 192.168.122.0/24 -d 224.0.0.0/24 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 -d 255.255.255.255/32 -j RETURN
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p tcp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -p udp -j MASQUERADE --to-ports 1024-65535
-A POSTROUTING -s 192.168.122.0/24 ! -d 192.168.122.0/24 -j MASQUERADE

Restart the iptables service

 :~$ sudo /bin/systemctl restart  iptables.service

16 Apr 2017

RaspberryPi Infrared Remote Control, Controlled Using a Web Server

DRAFT

TV Remote

  1. Setup electronic; 1x 200ohm resistor, 1x 10k ohm resistor, 1x transistor (any NPN should work) and 1 Infrared LED (http://www.raspberry-pi-geek.com/Archive/2015/10/Raspberry-Pi-IR-remote)

    Fig 1 Fig 2

  2. Install and configure lirc

    sudo apt-get install lirc

    sudo nano /etc/modules

     # /etc/modules: kernel modules to load at boot time.
     #
     # This file contains the names of kernel modules that should be loaded
     # at boot time, one per line. Lines beginning with "#" are ignored.
    
     lirc_dev
     lirc_rpi gpio_out_pin=22
    

    sudo nano /etc/lirc/hardware.conf

     # /etc/lirc/hardware.conf
     #
     # Arguments which will be used when launching lircd
     LIRCD_ARGS="--uinput"
    
     #Don't start lircmd even if there seems to be a good config file
     #START_LIRCMD=false
    
     #Don't start irexec, even if a good config file seems to exist.
     #START_IREXEC=false
    
     #Try to load appropriate kernel modules
     LOAD_MODULES=true
    
     # Run "lircd --driver=help" for a list of supported drivers.
     DRIVER="default"
     # usually /dev/lirc0 is the correct setting for systems using udev
     DEVICE="/dev/lirc0"
     MODULES="lirc_rpi"
    
     # Default configuration files for your hardware if any
     LIRCD_CONF=""
     LIRCMD_CONF=""
    

    Create a configuration file for your remote (http://lirc-remotes.sourceforge.net/remotes-table.html). Here’s mine for a Sharp Aquos TV:

     # brand:                       Sharp
     # model no. of remote control: GA840WJSA
     # devices being controlled by this remote: Sharp Aquos LED TV
     #
    
     begin remote
    
         name  Sharp
         bits           15
         flags SPACE_ENC|CONST_LENGTH
         eps            30
         aeps          100
    
         one           320  1750
         zero          320   700
         ptrail        321
         gap          64241
         toggle_bit_mask 0x0
         toggle_mask    0x3FF
         min_repeat    2
    
         begin codes
             KEY_POWER                0x41A2
             KEY_DISPLAY              0x4362
             KEY_POWER_SOURCE         0x460E
             KEY_REWIND               0x448E
             KEY_PLAY                 0x450E
             KEY_FASTFORWARD          0x468E
             KEY_PAUSE                0x46CE
             KEY_PREV_CHAPTER         0x44CE
             KEY_STOP                 0x470E
             KEY_NEXT_CHAPTER         0x474E
             KEY_RECORD               0x458E
             KEY_OPTION               0x444E
             KEY_SLEEP                0x4162
             KEY_POWER_SAVING         0x47B2
             KEY_REC_STOP             0x478E
             KEY_1                    0x4202
             KEY_2                    0x4102
             KEY_3                    0x4302
             KEY_4                    0x4082
             KEY_5                    0x4282
             KEY_6                    0x4182
             KEY_7                    0x4382
             KEY_8                    0x4042
             KEY_9                    0x4242
             KEY_DOT                  0x4572
             KEY_0                    0x4142
             KEY_ENT                  0x4342
             KEY_CC                   0x40B2
             KEY_AV_MODE              0x407E
             KEY_VIEW_MODE            0x4016
             KEY_FLASHBACK            0x43D2
             KEY_MUTE                 0x43A2
             KEY_VOLUMEUP             0x40A2
             KEY_VOLUMEDOWN           0x42A2
             KEY_CHANNELUP            0x4222
             KEY_CHANNELDOWN          0x4122
             KEY_INPUT                0x4322
             KEY_AQUOS_NET            0x4726
             KEY_MENU                 0x4012
             KEY_DOCK                 0x475A
             KEY_UP                   0x43AA
             KEY_LEFT                 0x42BE
             KEY_ENTER                0x43BE
             KEY_RIGHT                0x41BE
             KEY_DOWN                 0x406A
             KEY_EXIT                 0x433E
             KEY_RETURN               0x40BE
             KEY_FAVORITE             0x47C6
             KEY_SURROUND             0x41DA
             KEY_AUDIO                0x4062
             KEY_FREEZE               0x432A
             KEY_RED                  0x4236
             KEY_GREEN                0x42C9
             KEY_YELLOW               0x4336
             KEY_BLUE                 0x40B6
    
         end codes
    
     end remote
    
  3. Reboot and start lircd

     sudo reboot
     sudo lircd --device /dev/lirc0
    
  4. Test lircd, send number 1

     irsend SEND_ONCE Sharp key_1
    
  5. Setup uwsgi server (https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uwsgi-and-nginx-on-ubuntu-14-04)

     sudo apt-get update
     sudo apt-get install python-pip python-dev
     sudo pip install virtualenv
     mkdir ~/tvremote
     cd ~/tvremote
     virtualenv tvremoteenv
     source tvremoteenv/bin/activate
     pip install uwsgi flask
    
  6. Install Static files

    extract this archive into your home directory ~/tvremote.

  7. Create and start uwsgi service (https://blog.frd.mn/how-to-set-up-proper-startstop-services-ubuntu-debian-mac-windows/)

     sudo cp ~/tvremote/uwsgi /etc/init.d/
     sudo update-rc.d uwsgi defaults
     sudo service uwsgi start
    
  8. Ready to test, point browser to your RPi’s IP address

     http://192.168.2.51:8080/index.html
    

Remote control screenshot

09 Jan 2017

Essential knots

19 Jul 2016

Stream Youtube to RaspberryPi From Remote Computer Using Omxplayer

Stream Youtube to RaspberryPi From Remote Computer Using Omxplayer

~/$ omxplayer -b `/usr/local/bin/youtube-dl -g https://www.youtube.com/watch?v=ID`

13 Jan 2016

Motion detection security system using a Linux computer and old Android phone(s)
  • Install and setup IP Webcam on Android phone(s), change settings, start server and turn off the screen to help prevent overheating (removing the back cover also helps) and for conserving power, even if it is plugged in.

  • Install motion software on the Linux computer (sudo apt-get install motion if using Ubuntu) and set it up (edit /etc/motion/motion.conf)

    • ffmpeg_cap_new off # to only capture images
    • netcam_url http://phone-ip-address:8080/video
    • netcam_userpass login:password # if any
  • Install and setup mutt for sending emails from Linux computer

  • Install inotify-tools on the Linux computer (for monitoring the creation of new image files)

  • Create a Bash script for monitoring motion’s temporary directory for new files (You should change my@email.com for your email but the default MONITORDIR directory should be fine)

      #!/bin/sh
      MONITORDIR="/tmp/motion/"
      inotifywait -m -r -e create --format '%w%f' "${MONITORDIR}" | while read NEWFILE
    
      timestamp() {
        date +"%T"
      }
    
      do
      echo "File ${NEWFILE} is attached.\r\n" | mutt -s "Motion detected @ $(timestamp)" my@email.com -a ${NEWFILE}
      done
    
  • Start motion software on Linux computer

  • Start the Bash script on the Linux computer for monitoring for new image files in /tmp/motion/ and automatically emailing them to you.

You should now be getting 1 email per image captured when motion is detected.

I changed the camera resolution to 1280x720 and the motion config setting “treshold” to 750, to increase sensitivity.

20 Dec 2015

Linux Count Video Frames

Count video frames using melt:

~/$ melt video.mp4 -consumer xml | grep length

20 Dec 2015

Linux Stabilize/Deshake Video Fix

Using transcode:

transcode -J stabilize –mplayer_probe -i yourmovie.avi
transcode -J transform –mplayer_probe -i yourmovie.ext -y raw -o yourstabilizedmovie.ext

05 Dec 2015

Germinating (Queen) Palm Seeds
  1. Microwave humidified dirt mix to sterilize it and let it cool down
  2. Using a sharpie, identify Ziplock bags with palm type, date, etc…
  3. Add humid dirt to Ziploc bags (not too wet or the seeds will rot)
  4. Add seeds to bags
    • For queen palm seeds, I have had better luck so far with orange seeds that just fell off the tree (as opposed to green seeds that I cut off the tree).
  5. Set the bags on a shelf at room temperature (they don’t need light)
  6. Wait from 1 to 6 months (no need to add water if you keep Ziplock bags sealed)
  7. Transplant germinated seeds to pots

The sprouted seeds should look similar to this: queen-pal-sprouted-seed

Source: Germinating Palm Seeds

19 Oct 2015

Combine PDFs using ghostscript in Linux

Using Ghostscript to combine PDF files

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress -sOutputFile=out.pdf in1.pdf in2.pdf in3*.pdf

The prepress option is used to preserve higher quality (high quality, color preserving, 300 dpi imgs).

12 Sep 2015

Internet (web) without Google (aka Block Google IP addresses)

Block Google, completely

  1. Find Google IP addresses ranges

    Go to https://whois.arin.net/ui/advanced.jsp and Search for “Google LLC”, by Organization… Click each organization found and then select “Related Networks”.

  2. It gave me this list:

     GOOGLE-CLOUD (NET-104-154-0-0-1) 	104.154.0.0 - 104.155.255.255
     GOOGLE-CLOUD (NET-35-208-0-0-1) 	35.208.0.0 - 35.247.255.255
     GOOGLE-CLOUD (NET-35-192-0-0-1) 	35.192.0.0 - 35.207.255.255
     MEEBO (NET6-2620-84-1) 	2620:84:: - 2620:84:1:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-CLOUD (NET-173-255-112-0-1) 	173.255.112.0 - 173.255.127.255
     GOOGLE-CLOUD (NET-104-196-0-0-1) 	104.196.0.0 - 104.199.255.255
     GOOGLE-CLOUD (NET-192-158-28-0-1) 	192.158.28.0 - 192.158.31.255
     GOOGLE-CLOUD (NET-199-192-112-0-1) 	199.192.112.0 - 199.192.115.255
     GOOGLE-CLOUD (NET6-2600-1900-1) 	2600:1900:: - 2600:190F:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-CLOUD (NET-162-222-176-0-1) 	162.222.176.0 - 162.222.183.255
     GOOGLE-CLOUD (NET-107-167-160-0-1) 	107.167.160.0 - 107.167.191.255
     GOOGLE-CLOUD (NET-107-178-192-0-1) 	107.178.192.0 - 107.178.255.255
     GOOGLE-CLOUD (NET-108-59-80-0-1) 	108.59.80.0 - 108.59.95.255
     GOOGLE-CLOUD (NET-130-211-0-0-1) 	130.211.0.0 - 130.211.255.255
     GOOGLE-CLOUD (NET-146-148-0-0-1) 	146.148.0.0 - 146.148.127.255
     GOOGLE-CLOUD (NET-162-216-148-0-1) 	162.216.148.0 - 162.216.151.255
     GOOGLE-CLOUD (NET-199-223-232-0-1) 	199.223.232.0 - 199.223.239.255
     GOOGLE-CLOUD (NET-23-251-128-0-1) 	23.251.128.0 - 23.251.159.255
     GOOGLE-CLOUD (NET-23-236-48-0-1) 	23.236.48.0 - 23.236.63.255
     LVLT-GOOGL-2-8-35-200 (NET-8-35-200-0-1) 	8.35.200.0 - 8.35.207.255
     LVLT-GOOGL-2-8-34-216 (NET-8-34-216-0-1) 	8.34.216.0 - 8.34.223.255
     LVLT-GOOGL-2-8-34-208 (NET-8-34-208-0-1) 	8.34.208.0 - 8.34.215.255
     LVLT-GOOGL-2-8-35-192 (NET-8-35-192-0-1) 	8.35.192.0 - 8.35.199.255
     GOOGLE-CLOUD (NET-35-184-0-0-1) 	35.184.0.0 - 35.191.255.255
     GOOGLE-CLOUD (NET6-2602-FF11-1) 	2602:FF11:: - 2602:FF11:FFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-CLOUD (NET6-2600-2D00-1) 	2600:2D00:: - 2600:2D0F:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-CORP-74-125-116-0 (NET-74-125-116-0-1) 	74.125.116.0 - 74.125.119.255
     GOOGLE-CORP-74-125-120-0 (NET-74-125-120-0-1) 	74.125.120.0 - 74.125.123.255
     GOOGLE-CORP-216-239-35-0 (NET-216-239-35-0-1) 	216.239.35.0 - 216.239.35.255
     GOOGLE-CORP (NET-104-132-0-0-1) 	104.132.0.0 - 104.135.255.255
     GOOGLE-CORP-74-125-56-0 (NET-74-125-56-0-1) 	74.125.56.0 - 74.125.63.255
     GOOGLE-CORP-72-14-224-0 (NET-72-14-224-0-1) 	72.14.224.0 - 72.14.231.255
     GOOGLE-CORP-66-249-86-0 (NET-66-249-86-0-1) 	66.249.86.0 - 66.249.87.255
     GOOGLE-CORP-66-102-14-0 (NET-66-102-14-0-1) 	66.102.14.0 - 66.102.14.255
     GOOGLE-CORP-216-239-39-0 (NET-216-239-39-0-1) 	216.239.39.0 - 216.239.39.255
     GOOGLE-CORP-216-239-44-0 (NET-216-239-44-0-1) 	216.239.44.0 - 216.239.45.255
     GOOGLE-CORP-216-239-33-0 (NET-216-239-33-0-1) 	216.239.33.0 - 216.239.33.255
     GOOGLE-CORP-216-239-55-0 (NET-216-239-55-0-1) 	216.239.55.0 - 216.239.55.255
     GOOGLE-CORP-72-14-241-0 (NET-72-14-241-0-1) 	72.14.241.0 - 72.14.241.255
     GOOGLE-CORP-V6 (NET6-2620-15C-1) 	2620:15C:: - 2620:15C:FFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-IT-IPV6 (NET6-2620-1000-1) 	2620:0:1000:: - 2620:0:10FF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-TATAC (NET-63-243-224-0-1) 	63.243.224.0 - 63.243.224.63
     GOOGLE-TATAC (NET6-2001-5A0-4400-1) 	2001:5A0:4400:: - 2001:5A0:4400:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-VPN (NET-172-102-8-0-1) 	172.102.8.0 - 172.102.15.255
     GOOGLE-VPN (NET6-2605-EF80-1) 	2605:EF80:: - 2605:EF80:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-VPN (NET-192-104-160-0-1) 	192.104.160.0 - 192.104.161.255
     GOOGLE-VPN (NET-216-252-220-0-1) 	216.252.220.0 - 216.252.223.255
     GOOGLE-VPN (NET-209-107-176-0-1) 	209.107.176.0 - 209.107.191.255
     UU-65-216-183 (NET-65-216-183-0-1) 	65.216.183.0 - 65.216.183.255
     UU-63-88-22 (NET-63-88-22-0-1) 	63.88.22.0 - 63.88.23.255
     UU-65-220-13 (NET-65-220-13-0-1) 	65.220.13.0 - 65.220.13.255
     UU-65-202-192 (NET-65-202-192-0-1) 	65.202.192.0 - 65.202.192.255
     UU-65-196-120 (NET-65-196-120-0-1) 	65.196.120.0 - 65.196.121.255
     GOOGLE (NET-199-89-220-0-1) 	199.89.220.0 - 199.89.220.255
     GOOGLE (NET6-2620-E7-C000-1) 	2620:E7:C000:: - 2620:E7:C000:FFFF:FFFF:FFFF:FFFF:FFFF
     Q1208-63-226-245-56 (NET-63-226-245-56-1) 	63.226.245.56 - 63.226.245.63
     GOOGLE (NET6-2620-E7-4000-1) 	2620:E7:4000:: - 2620:E7:4000:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE (NET-199-88-130-0-1) 	199.88.130.0 - 199.88.130.255
     SAVV-S232078-3 (NET-209-185-108-128-1) 	209.185.108.128 - 209.185.108.255
     Q0702-63-158-137-224 (NET-63-158-137-224-1) 	63.158.137.224 - 63.158.137.231
     Q0708-63-237-119-112 (NET-63-237-119-112-1) 	63.237.119.112 - 63.237.119.119
     Q0708-208-46-199-160 (NET-208-46-199-160-1) 	208.46.199.160 - 208.46.199.167
     Q0807-67-148-177-136 (NET-67-148-177-136-1) 	67.148.177.136 - 67.148.177.143
     GOOGLE (NET-216-239-32-0-1) 	216.239.32.0 - 216.239.63.255
     EC12-1-GOOGLE (NET-64-68-80-0-1) 	64.68.80.0 - 64.68.87.255
     GOOGLE (NET-66-102-0-0-1) 	66.102.0.0 - 66.102.15.255
     GOOGLE (NET-108-177-0-0-1) 	108.177.0.0 - 108.177.127.255
     MICH-6184 (NET-198-108-100-192-1) 	198.108.100.192 - 198.108.100.207
     SAVV-S232078-1 (NET-216-33-229-144-1) 	216.33.229.144 - 216.33.229.151
     SAVV-S232078-2 (NET-216-33-229-160-1) 	216.33.229.160 - 216.33.229.167
     SAVV-S232078-26 (NET-64-68-88-0-1) 	64.68.88.0 - 64.68.95.255
     SAVV-S232078-11 (NET-216-109-75-80-1) 	216.109.75.80 - 216.109.75.95
     SAVV-S232078-24 (NET-64-68-64-64-1) 	64.68.64.64 - 64.68.64.127
     SAVV-S232078-21 (NET-64-41-221-192-1) 	64.41.221.192 - 64.41.221.207
     MEEBO (NET-199-36-152-0-1) 	199.36.152.0 - 199.36.159.255
     GOOGLE (NET-142-250-0-0-1) 	142.250.0.0 - 142.251.255.255
     GOOGLE-I83-80 (NET-12-216-80-0-1) 	12.216.80.0 - 12.216.80.255
     GOOGLE (NET-216-58-192-0-1) 	216.58.192.0 - 216.58.223.255
     GOOGLE (NET-172-217-0-0-1) 	172.217.0.0 - 172.217.255.255
     Q0312-2001-0428-6402-0204-0000-0000-0000-0000 (NET6-2001-428-6402-204-1) 	2001:428:6402:204:: - 2001:428:6402:204:FFFF:FFFF:FFFF:FFFF
     LVLT-GOGL-8-8-4 (NET-8-8-4-0-1) 	8.8.4.0 - 8.8.4.255
     LVLT-GOGL-4-3-2 (NET-4-3-2-0-1) 	4.3.2.0 - 4.3.2.255
     LVLT-GOGL-8-8-8 (NET-8-8-8-0-1) 	8.8.8.0 - 8.8.8.255
     MEEBO1 (NET-208-81-188-0-1) 	208.81.188.0 - 208.81.191.255
     GOOGLE (NET-74-114-24-0-1) 	74.114.24.0 - 74.114.31.255
     NET-209-141-120-128-GOOGLE-26 (NET-209-141-120-128-1) 	209.141.120.128 - 209.141.120.191
     NET-2605-5800-0-9-DC-64 (NET6-2605-5800-0-9-1) 	2605:5800:0:9:: - 2605:5800:0:9:FFFF:FFFF:FFFF:FFFF
     GOOGLE-IPV6 (NET6-2001-4860-1) 	2001:4860:: - 2001:4860:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE-IPV6 (NET6-2607-F8B0-1) 	2607:F8B0:: - 2607:F8B0:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GOOGLE (NET-108-170-192-0-1) 	108.170.192.0 - 108.170.255.255
     GOOGLE (NET-172-253-0-0-1) 	172.253.0.0 - 172.253.255.255
     GOOGLE (NET-173-194-0-0-1) 	173.194.0.0 - 173.194.255.255
     GOOGLE (NET-192-178-0-0-1) 	192.178.0.0 - 192.179.255.255
     GOOGLE (NET-207-223-160-0-1) 	207.223.160.0 - 207.223.175.255
     GOOGLE (NET-209-85-128-0-1) 	209.85.128.0 - 209.85.255.255
     GOOGLE (NET-64-233-160-0-1) 	64.233.160.0 - 64.233.191.255
     GOOGLE (NET-66-249-64-0-1) 	66.249.64.0 - 66.249.95.255
     GOOGLE (NET-70-32-128-0-1) 	70.32.128.0 - 70.32.159.255
     GOOGLE (NET-72-14-192-0-1) 	72.14.192.0 - 72.14.255.255
     GOOGLE (NET-74-125-0-0-1) 	74.125.0.0 - 74.125.255.255
     METAWEB-001 (NET-208-68-108-0-1) 	208.68.108.0 - 208.68.111.255
     NET-209-141-121-192-GOOGLE-26 (NET-209-141-121-192-1) 	209.141.121.192 - 209.141.121.255
     NET-209-141-121-128-GOOGLE-26 (NET-209-141-121-128-1) 	209.141.121.128 - 209.141.121.191
     NET-2605-5800-0-20-64 (NET6-2605-5800-0-20-1) 	2605:5800:0:20:: - 2605:5800:0:20:FFFF:FFFF:FFFF:FFFF
     NET-2605-5800-0-21-64 (NET6-2605-5800-0-21-1) 	2605:5800:0:21:: - 2605:5800:0:21:FFFF:FFFF:FFFF:FFFF
     GOOGLE-IPV6 (NET6-2604-31C0-1) 	2604:31C0:: - 2604:31C0:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
     GL-654 (NET-136-22-6-0-1) 	136.22.6.0 - 136.22.7.255
    
  3. Next create an iptables/ip6tables script similar to this but with all the IP ranges from above:

     #!/bin/sh  
     # /etc/init.d/firewall
    
     IPT="/sbin/iptables"  
     IPT6="/sbin/ip6tables"  
    
     # Block Google
     $IPT -A INPUT -s 64.233.160.0/19 -j DROP  
     $IPT -A OUTPUT -d 64.233.160.0/19 -j DROP
     $IPT -A INPUT -s 2c0f:fb50:4000::/36 -j DROP
     $IPT -A OUTPUT -d 2c0f:fb50:4000::/36 -j DROP