Inhoudsopgave:

https://github.com/PA3EFR?tab=repositories

Cluster warnings. Sound with CMD window.

    • pip install playsound

import socket
import re
import winsound  # Voor Windows; gebruik 'playsound' voor andere systemen.

# Configuratie: pas deze waarden aan
HOST = "www.db0erf.de"  # Vervang door de host-IP van het DXCluster van lijst https://www.dxcluster.info/telnet/dxcluster_up.htm
PORT = 41113                    # Vervang door de poort van het DXCluster
CALLSIGN = "PA3EFR"     # Vervang door je callsign of gebruikersnaam
patterns = [r"B/", r"WWFF", r"POTA", r"COTA", r"SOTA", r"BOTA"]

def play_alarm():
    """Speelt een alarmsignaal af met vijf tonen."""
    frequencies = [1500, 1600, 1700, 1800, 1900, 2000, 2200, 2400, 2600, 2800]  # Frequenties in Hertz
    duration = 100  # Duur van elke toon in milliseconden

    for frequency in frequencies:
        winsound.Beep(frequency, duration)

def main():
    # Maak verbinding met het DXCluster
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        print(f"Verbinden met {HOST}:{PORT}...")
        s.connect((HOST, PORT))
        print("Verbonden. Verstuur login...")

        # Verstuur logincommando
        login_command = f"{CALLSIGN}\n"  # Vaak is het gewoon de callsign gevolgd door een newline
        s.sendall(login_command.encode("utf-8"))
        print(f"Ingelogd als: {CALLSIGN}")
        printnr = 0
        try:
            while True:
                # Ontvang data van de socket
                data = s.recv(1024).decode("utf-8", errors="replace")
                data = data.upper()
                if not data:
                    break  # Verbinding is gesloten door de server

                # Toon ontvangen data (optioneel)
                #print(data)


                # Controleer op "B/" in de ontvangen tekst
                for pattern in patterns:
                    if re.search(pattern, data):
                        print(f"Alarm: '{pattern}'")
                        print (data)
                        play_alarm()

                #if re.search(r"\bSOTA\b", data):
                #    print("Alarm: 'B/' gevonden!")
                #    play_alarm()

        except KeyboardInterrupt:
            print("Script gestopt door gebruiker.")
        except Exception as e:
            print(f"Fout opgetreden: {e}")

if __name__ == "__main__":
    main()

 

Omdat de Thin Client zijn HRI-200 als audio sturing voor de WIRES-X gebruikt moeten voor dit cluster warning systeem de ingebouwde loudspeaker selecteren. Die is bekend als device 15. Je kunt een lijst laten printen bij aanvang van het programma door een paar # weg te halen.

  • pip install playsound
  • pip install pyaudio
  • pip install numpy

import socket
import re
import winsound  # Voor Windows; gebruik 'playsound' voor andere systemen.

# Configuratie: pas deze waarden aan
HOST = "www.db0erf.de"  # Vervang door de host-IP van het DXCluster van lijst https://www.dxcluster.info/telnet/dxcluster_up.htm
PORT = 41113                    # Vervang door de poort van het DXCluster
CALLSIGN = "PA3EFR"     # Vervang door je callsign of gebruikersnaam
patterns = [r"B/", r"WWFF", r"POTA", r"COTA", r"SOTA", r"BOTA"]

import pyaudio
import numpy as np

# Initialiseer PyAudio
p = pyaudio.PyAudio()

# Lijst van apparaten
#print("Beschikbare apparaten:")                                     # Deze 4 regels activeren om een lijst van devices te zien
#for i in range(p.get_device_count()):
#    info = p.get_device_info_by_index(i)
#    print(f"{i}: {info['name']}")

# Specificeer apparaat-ID van ingebouwde luidsprekers
default_device_id = 15  # Pas dit aan op basis van bovenstaande lijst


def play_alarm():
    """Speelt een toon af als alarmgeluid."""
    fs = 44100  # Samplefrequentie
    duration = 3  # Duur van de toon in seconden
    frequency = 440.0  # Frequentie van de toon in Hertz

    # Genereer een sinusgolf
    t = np.linspace(0, duration, int(fs * duration), endpoint=False)
    tone = (np.sin(2 * np.pi * frequency * t) * 0.5).astype(np.float32)

    # Initialiseer PyAudio
    p = pyaudio.PyAudio()

    try:
        # Start een audio-stream op het opgegeven apparaat
        stream = p.open(format=pyaudio.paFloat32,
                        channels=1,
                        rate=fs,
                        output=True,
                        output_device_index= default_device_id)

        # Speel de toon af
        stream.write(tone.tobytes())
        stream.stop_stream()
        stream.close()
    finally:
        p.terminate()

def main():
    # Maak verbinding met het DXCluster
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        print(f"Verbinden met {HOST}:{PORT}...")
        s.connect((HOST, PORT))
        print("Verbonden. Verstuur login...")

        # Verstuur logincommando
        login_command = f"{CALLSIGN}\n"  # Vaak is het gewoon de callsign gevolgd door een newline
        s.sendall(login_command.encode("utf-8"))
        print(f"Ingelogd als: {CALLSIGN}")
        printnr = 0
        try:
            while True:
                # Ontvang data van de socket
                data = s.recv(1024).decode("utf-8", errors="replace")
                data = data.upper()
                if not data:
                    break  # Verbinding is gesloten door de server

                # Toon ontvangen data (optioneel)
                #print(data)


                # Controleer op pattern in de ontvangen tekst
                for pattern in patterns:
                    if re.search(pattern, data):
                        print(f"Alarm: '{pattern}'")
                        print (data)
                        play_alarm()

        except KeyboardInterrupt:
            print("Script gestopt door gebruiker.")
        except Exception as e:
            print(f"Fout opgetreden: {e}")

if __name__ == "__main__":
    main()

 

Voor het toplicht gebruiken we een Arduino. Hierbij de stappen van het instellen van deze Arduino naar een andere call.

  1. Installeer de Arduino IDE op je PC/laptop (dit is een applicatie om Arduino's te kunnen programmeren).
  2. Installeer Digispark (Default - 16.5 MHz) van https://raw.githubusercontent.com/digistump/arduino-boards-index/refs/heads/master/package_digistump_index.json (Preference verwijzing)
  3. Zet de schakelaar achterop de rotor klok in de middenstand en sluit alleen de USB-A to USB-A kabel aan de rotorklok aan. Steek deze nog niet in de laptop.
  4. Start Arduino en pas de Sketch.ino (zie hieronder) aan naar de nieuwe call (regel 134, bold highlight)
  5. Druk linksboven in de IDE op het pijltje naar rechts (upload) en wacht tot onderin het scherm de melding komt om "binnen 60 seconden het device aan te sluiten". Druk binnen deze 60 seconden de USB-A to USB-A kabel in de laptop.
  6. Na 4 seconden is de INO-file geupload en klaar voor gebruik. USB-A to USB-A kabel mag nu verwijderd worden.
  7. Check met de schakelaar naar beneden of de call juist wordt geseind. 

//
// Simple Arduino Morse Beacon
// Written by Mark VandeWettering K6HX
// Email: This email address is being protected from spambots. You need JavaScript enabled to view it.
// 
// This code is so trivial that I'm releasing it completely without 
// restrictions.  If you find it useful, it would be nice if you dropped
// me an email, maybe plugged my blog @ https://brainwagon.org or included
// a brief acknowledgement in whatever derivative you create, but that's
// just a courtesy.  Feel free to do whatever.
//


struct t_mtab { char c, pat; } ;

struct t_mtab morsetab[] = {
    {'.', 106},
  {',', 115},
  {'?', 76},
  {'/', 41},
  {'A', 6},
  {'B', 17},
  {'C', 21},
  {'D', 9},
  {'E', 2},
  {'F', 20},
  {'G', 11},
  {'H', 16},
  {'I', 4},
  {'J', 30},
  {'K', 13},
  {'L', 18},
  {'M', 7},
  {'N', 5},
  {'O', 15},
  {'P', 22},
  {'Q', 27},
  {'R', 10},
  {'S', 8},
  {'T', 3},
  {'U', 12},
  {'V', 24},
  {'W', 14},
  {'X', 25},
  {'Y', 29},
  {'Z', 19},
  {'1', 62},
  {'2', 60},
  {'3', 56},
  {'4', 48},
  {'5', 32},
  {'6', 33},
  {'7', 35},
  {'8', 39},
  {'9', 47},
  {'0', 63}
} ;

#define N_MORSE  (sizeof(morsetab)/sizeof(morsetab[0]))

#define SPEED  (8)
#define DOTLEN  (1200/SPEED)
#define DASHLEN  (3*(1200/SPEED))

const int LEDpin = 3;    // the pin that the LED is attached to


void
dash()
{
  digitalWrite(LEDpin, HIGH) ;
  delay(DASHLEN);
  digitalWrite(LEDpin, LOW) ;
  delay(DOTLEN) ;
}

void
dit()
{
  digitalWrite(LEDpin, HIGH) ;
  delay(DOTLEN);
  digitalWrite(LEDpin, LOW) ;
  delay(DOTLEN);
}

void
send(char c)
{
  int i ;
  if (c == ' ') {
    Serial.print(c) ;
    delay(7*DOTLEN) ;
    return ;
  }
  for (i=0; i<N_MORSE; i++) {
    if (morsetab[i].c == c) {
      unsigned char p = morsetab[i].pat ;
      Serial.print(morsetab[i].c) ;

      while (p != 1) {
          if (p & 1)
            dash() ;
          else
            dit() ;
          p = p / 2 ;
      }
      delay(4*DOTLEN) ;
      return ;
    }
  }
  /* if we drop off the end, then we send a space */
  Serial.print("?") ;
}

void
sendmsg(char *str)
{
  while (*str)
    send(*str++) ;
  Serial.println("");
}

void setup() {
  pinMode(LEDpin, OUTPUT) ;
  digitalWrite(LEDpin, LOW) ;
  Serial.begin(9600) ;
  Serial.println("Simple Arduino Morse Beacon v0.0") ;
  Serial.println("Written by Mark VandeWettering <This email address is being protected from spambots. You need JavaScript enabled to view it.>") ;
  Serial.println("Check out my blog @ https://brainwagon.org") ;
  Serial.println("") ;
}

void loop() {
  sendmsg("PA3EFR/J") ;
  delay(3000) ;
}