add functions

This commit is contained in:
F4HTB 2020-09-26 01:46:56 +01:00
parent 3638927333
commit 6d63fa1ff0
15 changed files with 794 additions and 0 deletions

224
UHRR Executable file
View File

@ -0,0 +1,224 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.websocket
import alsaaudio
import threading
import time
import numpy
import gc
import Hamlib
############ Global variables ##################################
CTRX=None
############ websocket for send RX audio from TRX ##############
flagWavstart = False
AudioRXHandlerClients = []
class loadWavdata(threading.Thread):
def __init__(self):
global flagWavstart
threading.Thread.__init__(self)
device = 'plughw:CARD=U0x41e0x30d3,DEV=0'
self.inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, channels=1, rate=8000, format=alsaaudio.PCM_FORMAT_FLOAT_LE, periodsize=256, device=device)
print('recording...')
def run(self):
global Wavframes, flagWavstart
ret=b''
while True:
while not flagWavstart:
time.sleep(0.5)
l, ret = self.inp.read()
if l > 0:
for c in AudioRXHandlerClients:
c.Wavframes.append(ret)
else:
print("overrun")
class AudioRXHandler(tornado.websocket.WebSocketHandler):
def open(self):
self.set_nodelay(True)
global flagWavstart
if self not in AudioRXHandlerClients:
AudioRXHandlerClients.append(self)
self.Wavframes = []
print('new connection on AudioRXHandler socket.')
flagWavstart = True
self.tailstream()
@tornado.gen.coroutine
def tailstream(self):
while flagWavstart:
while len(self.Wavframes)==0:
yield tornado.gen.sleep(0.1)
yield self.write_message(self.Wavframes[0],binary=True)
del self.Wavframes[0]
def on_close(self):
if self in AudioRXHandlerClients:
AudioRXHandlerClients.remove(self)
global flagWavstart
print('connection closed for audioRX')
if len(AudioRXHandlerClients)<=0:
flagWavstart = False
self.Wavframes = []
gc.collect()
############ websocket for control TRX ##############
ControlTRXHandlerClients = []
class TRXRIG:
def __init__(self):
self.infos = {}
self.serialport = Hamlib.hamlib_port_parm_serial
self.serialport.rate=38400
try:
self.rig_model = "RIG_MODEL_FT817"
self.rig_pathname = "/dev/ttyUSB0"
self.rig = Hamlib.Rig(Hamlib.__dict__[self.rig_model]) # Look up the model's numerical index in Hamlib's symbol dictionary.
self.rig.set_conf("rig_pathname", self.rig_pathname)
self.rig.set_conf("retry", "5")
self.rig.open()
except:
logging.error("Could not open a communication channel to the rig via Hamlib!")
self.getvfo()
self.getFreq()
self.getMode()
def getvfo(self):
try:
self.infos["VFO"] = (self.rig.get_vfo())
except:
logging.error("Could not obtain the current VFO via Hamlib!")
return self.infos["VFO"]
def setFreq(self,frequency):
try:
self.rig.set_freq(Hamlib.RIG_VFO_CURR, float(frequency))
self.getFreq()
except:
logging.error("Could not set the frequency via Hamlib!")
return self.infos["FREQ"]
def getFreq(self):
try:
self.infos["FREQ"] = (int(self.rig.get_freq()))
except:
logging.error("Could not obtain the current frequency via Hamlib!")
return self.infos["FREQ"]
def setMode(self,MODE):
try:
self.rig.set_mode(Hamlib.rig_parse_mode(MODE))
self.getMode()
except:
logging.error("Could not set the mode via Hamlib!")
return self.infos["MODE"]
def setPTT(self,status):
try:
if status:
self.rig.set_ptt(Hamlib.RIG_VFO_CURR,Hamlib.RIG_PTT_ON)
self.infos["PTT"]="PTT_OFF"
else:
self.rig.set_ptt(Hamlib.RIG_VFO_CURR,Hamlib.RIG_PTT_OFF)
self.infos["PTT"]="PTT_ON"
except:
logging.error("Could not set the mode via Hamlib!")
return self.infos["PTT"]
def getMode(self):
try:
(mode, width) = self.rig.get_mode()
self.infos["MODE"] = Hamlib.rig_strrmode(mode).upper()
self.infos["WIDTH"] = width
except:
logging.error("Could not obtain the current Mode via Hamlib!")
return self.infos["MODE"]
def getStrgLVL(self):
try:
self.infos["StrgLVL"] = self.rig.get_level_i(Hamlib.RIG_LEVEL_STRENGTH)
except:
logging.error("Could not obtain the current Strength signal RX level via Hamlib!")
return self.infos["StrgLVL"]
def setPower(self,status=1):
try:
if status:
self.rig.set_powerstat(Hamlib.RIG_POWER_ON)
else:
self.rig.set_powerstat(Hamlib.RIG_POWER_OFF)
self.infos["powerstat"] = status
except:
logging.error("Could not set power status via Hamlib!")
return self.infos["powerstat"]
class ControlTRX(tornado.websocket.WebSocketHandler):
def open(self):
if self not in ControlTRXHandlerClients:
ControlTRXHandlerClients.append(self)
print('new connection on ControlTRX socket.')
@tornado.gen.coroutine
def on_message(self, data) :
print(data)
try:
(action, datato) = data.split(':')
except ValueError:
action = data
pass
if(action == "PING"):
self.write_message("PONG")
elif(action == "getFreq"):
yield self.write_message("getFreq:"+str(CTRX.getFreq())) #CTRX()[data]()
elif(action == "setFreq"):
yield self.write_message("getFreq:"+str(CTRX.setFreq(datato)))
def on_close(self):
if self in ControlTRXHandlerClients:
ControlTRXHandlerClients.remove(self)
gc.collect()
############ Main ##############
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.application.settings.get("compiled_template_cache", False)
self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
self.render("www/index.html")
if __name__ == "__main__":
threadloadWavdata = loadWavdata()
threadloadWavdata.start()
CTRX = TRXRIG()
CTRX.setPower(1)
app = tornado.web.Application([
(r'/CTRX', ControlTRX),
(r'/audioRX', AudioRXHandler),
(r'/', MainHandler),
(r'/(.*)', tornado.web.StaticFileHandler, { 'path' : './www' })
],debug=True)
http_server = tornado.httpserver.HTTPServer(app, ssl_options={
"certfile": os.path.join("selfsign.crt"),
"keyfile": os.path.join("selfsign.key"),
})
http_server.listen(8888)
print('http server started')
tornado.ioloop.IOLoop.instance().start()

21
selfsign.crt Normal file
View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUFZazUUKBBIYvF+HJuDNOXN1FQewwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA1MjAxODA2MjhaFw0yMDA2
MTkxODA2MjhaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCcydQ7PQ2q9mh0RxiQ7D0xYpLmUrsWq6J1oEMzT1Q0
Cglib2cRkwE4gWx67tHmL+IqA0HdYyZQkvc81T4z8DFgchQY997uhCFZvmtEvJln
KvJIS8wPXuZqQCJAKSfmyGGS+WBiMb7l1nrM0kDVGgllWFxleTWkjn+dKJHlcTQs
ankV2SmPKSBbp96tid5oLF9Po9l3A7HoCTGSiV+CnNPsr0ptAx7wYjx+FXZiwBx3
zBfiprtCyfja0bQZLkCZOkRjNn6Px5g8vuN8O/NO6UdEKJdoNwfn40nQ+ledOwca
/TgcbHwzFvZD1cMXceScZDQxhzaVlOYUxxEKgxlxOXSzAgMBAAGjUzBRMB0GA1Ud
DgQWBBRFcsDAW0GZCgiFES0Yfr8ITkCtnjAfBgNVHSMEGDAWgBRFcsDAW0GZCgiF
ES0Yfr8ITkCtnjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBb
F1Lq/K8MYtQ8co9QY4C/sRiFpxh+gSZan4N7wdpCupqlphsN58G0zw/YxjrqLu8k
wdmv4nV95zFqzpBH+eit3dIrGSRdO3rln+fMLiNMhvK23v1BsfWbwgqd513RTTlQ
mUloWsPIca2S6PiMcfTnZRTyyZOg6ciVsKv1b+NyMfnFDHc90+WNz6dZG2TjgdCJ
mC5oV52KG+Ju3sQYnv/1a8zUsAeB6uG/gjFbbg/ANPdWh7jvmY8wXSd22jYVzWxZ
YTkPLIBf+GegWvWLkNTbydmDdmAROzlJVLVhfMaOQuvAnrdKpd0oFqDs+uNiPMgB
b7H5eusoH7uXuOD8NQNK
-----END CERTIFICATE-----

27
selfsign.key Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAnMnUOz0NqvZodEcYkOw9MWKS5lK7FquidaBDM09UNAoJYm9n
EZMBOIFseu7R5i/iKgNB3WMmUJL3PNU+M/AxYHIUGPfe7oQhWb5rRLyZZyrySEvM
D17makAiQCkn5shhkvlgYjG+5dZ6zNJA1RoJZVhcZXk1pI5/nSiR5XE0LGp5Fdkp
jykgW6ferYneaCxfT6PZdwOx6AkxkolfgpzT7K9KbQMe8GI8fhV2YsAcd8wX4qa7
Qsn42tG0GS5AmTpEYzZ+j8eYPL7jfDvzTulHRCiXaDcH5+NJ0PpXnTsHGv04HGx8
Mxb2Q9XDF3HknGQ0MYc2lZTmFMcRCoMZcTl0swIDAQABAoIBAHD+Z6x1mKcQREEg
h8zR5Fv1/YZuMxTohwGciTGuRzHl1dOSE8avmh6d7489FBp/gc/jXxFtBkzlTbcS
u2x0+zDVpjREVu6wXNSvjeEQxsF6SvfdYGfnbck/BTAWOQJygReKD3NVBI3hn8iC
8mRiCkl2f8hFrWo1pDSf611e00n6JRg2YPlH/gBqV2T0mDJL7CXTP6Tggaa6jInQ
Ux7OgPz8djEvk5jFm0lGVxHzo/kbTGfBTLbKfJv/NTxiHH7Qt8NeaFzzJo7sH1eM
E8JT8sZZdCiBtlEmmgp/vX+r9M1gqi2i/evOzJxayx6J+CaGiS/j/VuXC5sQJB8L
jaorwikCgYEAyc1YZ0uxWoCy2M6fYG3ClJ9P3n2rfwdBwzhXaPm6B8EI7UCPR/0/
EcckGe34QGc2XmtwgxHIJ+hiidzLTn5hMDHYO82JOKa8cQppIKdGGnRwGhyiZhaf
tRyUD5ySPEFL8GR+Mau19NYy5bic5mDrFmSiCtgsxf3kzgAPmxF/BZcCgYEAxuWe
yRsLX5XZHZJRdrGt6lrSnr0BosKIjNxJDwh9VUVh49bzWa1Kvp7u+XMlN48A335I
Aukicujtoe0gIGS9btFOPX5seBs+lReWFpVn0Xa0OJQby7oX3Fp1XDTsbvtrcDHV
vXsZLNv3ip0OGKRh1p1va/idTpajeqPRDB5HBUUCgYACu/2OqL/mcgf6WBJgxBv2
15HFef5w4jBJ7OGCUp/qqvrr/Av09cF9BC3BDDBo7v0Vmm8T15HWuJddNtiqX5wB
gyti5A4P7nJvNazm/F0+zoUWVXz91SCk25ZF/+EbX+cfgr0S/zif8KcP5ch6dqW4
z/RCIVu58w6+m9GaUEpgUQKBgQCX7E60GBdA5MnZn6jf++n3B3a3z3EPbH428hBQ
DlEFsCCMkuSAjDB6mBW7rmswG+gzzlac+ozYrvjMZb7TX3+exPt5VzbtKwpLgZ+g
EnEhewU/7kmo/LU7GFFqo/Yw85RmN3qm5/8b180mML7SrcUZ1FmGZHlrzP6EL9r+
4aWn7QKBgFXxU/vI5RVpvG35dt5BwomBMIx0W2UtXIG+/u8j7S9GBUXFXUyUVr9W
rPsI1TpIZKR9r95RIaj8B25DyUApJVlH7jf2DDoASqr5dR77fmQVaANrrDhgMjNl
QmPd4kw52/wr5KLJukLK9dg8kmwDIMGvHy9rBGo5uoKk4+daUjTW
-----END RSA PRIVATE KEY-----

271
www/controls.js vendored Normal file
View File

@ -0,0 +1,271 @@
//Extra Generals///////////////////////////////////////////////////////////////////////////
//document.addEventListener('contextmenu', event => event.preventDefault());
function bodyload(){
disableScroll();
}
function disableScroll() {
// Get the current page scroll position
scrollTop = window.pageYOffset || document.documentElement.scrollTop;
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
// if any scroll is attempted, set this to the previous value
window.onscroll = function() {
window.scrollTo(scrollLeft, scrollTop);
};
}
//Generals routines///////////////////////////////////////////////////////////////////////////
poweron = false;
function powertogle()
{
if(event.srcElement.src.replace(/^.*[\\\/]/, '')=="poweroff.png"){
event.srcElement.src="img/poweron.png";
document.getElementById("ombre-body").style.display = "block";
document.getElementById("pop-upspinner").style.display = "block";
check_connected();
AudioRX_start();
ControlTRX_start();
checklatency();
poweron = true;
}
else{
event.srcElement.src="img/poweroff.png";
AudioRX_stop();
ControlTRX_stop();
poweron = false;
}
}
function check_connected() {
setTimeout(function () {
if (wsAudioRX.readyState === WebSocket.OPEN && wsControlTRX.readyState === WebSocket.OPEN){document.getElementById("ombre-body").style.display = "none";document.getElementById("pop-upspinner").style.display = "none";}
else{check_connected();}
}, 1000);
}
//RX Audio routines///////////////////////////////////////////////////////////////////////////
var wsAudioRX = "";
var AudioRX_context = "";
var AudioRX_source_node = "";
var audiobufferready = false;
function AudioRX_start(){
document.getElementById("indwsAudioRX").innerHTML='<img src="img/critsgrey.png">wsRX';
var audiobuffer = [];var lenglitchbuf = 2;
wsAudioRX = new WebSocket( 'wss://' + window.location.href.split( '/' )[2] + '/audioRX' );
wsAudioRX.binaryType = 'arraybuffer';
wsAudioRX.onmessage = appendwsAudioRX;
wsAudioRX.onopen = wsAudioRXopen;
wsAudioRX.onclose = wsAudioRXclose;
wsAudioRX.onerror = wsAudioRXerror;
function appendwsAudioRX( msg ){
var buffer = new Float32Array(msg.data);
audiobuffer.push(buffer);
if(audiobuffer.length>lenglitchbuf){audiobufferready= true;}
//console.log(audiobuffer.length);
}
var BUFF_SIZE = 256; // spec allows, yet do not go below 1024
AudioRX_context = new AudioContext({latencyHint: "interactive",sampleRate: 8000});
var AudioRX_gain_node = AudioRX_context.createGain();
AudioRX_gain_node.connect( AudioRX_context.destination );
AudioRX_source_node = AudioRX_context.createScriptProcessor(BUFF_SIZE, 1, 1);
AudioRX_source_node.onaudioprocess = (function() {
return function(event) {
var synth_buff = event.outputBuffer.getChannelData(0); // mono for now
if(audiobufferready){
for (var i = 0, buff_size = synth_buff.length; i < buff_size; i++) {
synth_buff[i] = audiobuffer[0][i];
}
if(audiobuffer.length > 1){audiobuffer.shift();}
}
};
}());
AudioRX_source_node.connect(AudioRX_gain_node);
}
function wsAudioRXopen(){
document.getElementById("indwsAudioRX").innerHTML='<img src="img/critsgreen.png">wsRX';
}
function wsAudioRXclose(){
document.getElementById("indwsAudioRX").innerHTML='<img src="img/critsred.png">wsRX';
AudioRX_stop();
}
function wsAudioRXerror(err){
document.getElementById("indwsAudioRX").innerHTML='<img src="img/critsred.png">wsRX';
AudioRX_stop();
}
function AudioRX_stop()
{
audiobufferready = false;
wsAudioRX.close();
AudioRX_source_node.onaudioprocess = null
AudioRX_context.close();
}
//ControlTRX routines///////////////////////////////////////////////////////////////////////////
var wsControlTRX = "";
function ControlTRX_start(){
document.getElementById("indwsControlTRX").innerHTML='<img src="img/critsgrey.png">wsCtrl';
wsControlTRX = new WebSocket( 'wss://' + window.location.href.split( '/' )[2] + '/CTRX' );
wsControlTRX.onopen = wsControlTRXopen;
wsControlTRX.onclose = wsControlTRXclose;
wsControlTRX.onerror = wsControlTRXerror;
wsControlTRX.onmessage = wsControlTRXcrtol;
}
function wsControlTRXcrtol( msg ){
console.log(String(msg.data));
words = String(msg.data).split(':');
if(words[0] == "PONG"){showlatency();}
else if(words[0] == "getFreq"){showfreq(words[1]);}
}
function ControlTRX_stop()
{
wsControlTRX.close();
}
function wsControlTRXopen(){
document.getElementById("indwsControlTRX").innerHTML='<img src="img/critsgreen.png">wsCtrl';
wsControlTRX.send("getFreq:");
}
function wsControlTRXclose(){
document.getElementById("indwsControlTRX").innerHTML='<img src="img/critsred.png">wsCtrl';
}
function wsControlTRXerror(err){
wsControlTRX.close();
document.getElementById("indwsControlTRX").innerHTML='<img src="img/critsred.png">wsCtrl';
ControlTRX_start();
}
var startTime;
function checklatency() {
setTimeout(function () {
startTime = Date.now();
if (wsControlTRX.readyState === WebSocket.OPEN) {wsControlTRX.send("PING");}
if(poweron == true){checklatency();}
}, 5000);
}
function showlatency(){
latency = Date.now() - startTime;
document.getElementById("div-latencymeter").innerHTML="latency:"+latency+"ms";
}
function get_digit_freq(){
return parseInt(
document.getElementById("cmhz").innerHTML+
document.getElementById("dmhz").innerHTML+
document.getElementById("umhz").innerHTML+
document.getElementById("ckhz").innerHTML+
document.getElementById("dkhz").innerHTML+
document.getElementById("ukhz").innerHTML+
document.getElementById("chz").innerHTML+
document.getElementById("dhz").innerHTML+
document.getElementById("uhz").innerHTML
);
}
freq_digit_selected="";
function freq_digit_scroll() {
if (poweron) {
if(event.deltaY>0){toadd=-1;}else{toadd=1;}
freq=get_digit_freq()+(freq_digit_selected.getAttribute('v')*toadd);
if(freq>0){showfreq(freq);sendTRXfreq();}
}
}
function select_digit() {
freq_digit_selected=event.srcElement;
}
function clear_select_digit() {
freq_digit_selected="";
}
function rotatefreq(){
if (poweron) {
freq=get_digit_freq()+parseInt(event.srcElement.getAttribute('v'));
if(freq>0){showfreq(freq);sendTRXfreq();}
}
}
function showfreq(freq){
freq=freq.toString();
while (freq.length < 9){freq="0"+freq;}
document.getElementById("cmhz").innerHTML=freq.substring(0, 1);
document.getElementById("dmhz").innerHTML=freq.substring(1, 2);
document.getElementById("umhz").innerHTML=freq.substring(2, 3);
document.getElementById("ckhz").innerHTML=freq.substring(3, 4);
document.getElementById("dkhz").innerHTML=freq.substring(4, 5);
document.getElementById("ukhz").innerHTML=freq.substring(5, 6);
document.getElementById("chz").innerHTML=freq.substring(6, 7);
document.getElementById("dhz").innerHTML=freq.substring(7, 8);
document.getElementById("uhz").innerHTML=freq.substring(8, 9);
}
function sendTRXfreq(){
if (wsControlTRX.readyState === WebSocket.OPEN) {wsControlTRX.send("setFreq:"+get_digit_freq());}
}
//Cosmetics
function button_pressed(item)
{
if(!item){item=event.srcElement;}
item.classList.remove('button_unpressed');
item.classList.add('button_pressed');
button_light(item);
}
function button_unpressed(item)
{
if(!item){item=event.srcElement;}
item.classList.remove('button_green');
item.classList.remove('button_pressed');
item.classList.add('button_unpressed');
}
function button_light(item,color="G")
{
if(!item){item=event.srcElement;}
if(color=="G"){
if(poweron){item.classList.add('button_green');}
else{item.classList.remove('button_green');}
}
else if(color=="R"){
if(poweron){item.classList.add('button_red');}
else{item.classList.remove('button_red');}
}
else if(color=="Z"){
item.classList.remove('button_red');
}
}

BIN
www/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
www/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
www/img/critsgreen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

BIN
www/img/critsgrey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
www/img/critsred.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
www/img/critsyellow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
www/img/poweroff.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
www/img/poweron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
www/img/spinner.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

73
www/index.html Normal file
View File

@ -0,0 +1,73 @@
<html>
<head>
<meta charset="UTF-8">
<title>Universal Hamradio Remote by F4HTB</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="controls.js"></script>
</head>
</head>
<body onload="bodyload();">
<a href="#fermer" id="ombre-body"></a>
<div id="pop-upspinner">
<img alt="" src="img/spinner.gif">
<p id="socketsate"><center>Wait For connection....</center></p>
</div>
<div id="div-princ">
<img onclick="powertogle();" id="button_power" src="img/poweroff.png">
<div id="div-freq">
<ul id="freq_but">
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="cmhz" v=100000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dmhz" v=10000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="umhz" v=1000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();"> </li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="ckhz" v=100000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dkhz" v=10000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="ukhz" v=1000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();"> </li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="chz" v=100></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dhz" v=10></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="uhz" v=1></li>
</ul>
<ul id="freq_disp" onwheel="freq_digit_scroll()">
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="cmhz" v=100000000>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="dmhz" v=10000000>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="umhz" v=1000000>0</li>
<li class="freq_digit">.</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="ckhz" v=100000>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="dkhz" v=10000>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="ukhz" v=1000>0</li>
<li class="freq_digit">.</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="chz" v=100>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="dhz" v=10>0</li>
<li class="freq_digit" onmouseenter="select_digit();" onmouseleave="clear_select_digit();" id="uhz" v=1>0</li>
</ul>
<ul id="freq_but">
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="cmhz" v=-100000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dmhz" v=-10000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="umhz" v=-1000000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();"> </li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="ckhz" v=-100000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dkhz" v=-10000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="ukhz" v=-1000></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" > </li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="chz" v=-100></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="dhz" v=-10></li>
<li onmousedown="button_pressed();rotatefreq();" onmouseup="button_unpressed();" class="button_unpressed" digit="uhz" v=-1></li>
</ul>
</div>
<div id="div-scoketscontrols">
<p id="indcwsTX"><img src="img/critsred.png">wsTX</p>
<p id="indwsAudioRX"><img src="img/critsred.png">wsRX</p>
<p id="indwsControlTRX"><img src="img/critsred.png">wsCtrl</p>
<p id="indcwsFFT"><img src="img/critsred.png">wsFFT</p>
</div>
<div id="div-latencymeter">latency:∞</div>
</div>
</body>
</html>

178
www/style.css Normal file
View File

@ -0,0 +1,178 @@
body {
color: white;
font:normal bold 14px tahoma;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#ombre-body{
display: none;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.7);
z-index: 1000;
cursor: default;
}
#pop-upspinner{
display: none;
position: fixed;
left: calc(50% - 100px);
top: 50%;
z-index: 2000;
cursor: default;
overflow: hidden;
}
#div-princ {
margin: 20px auto;
width: 1800px;
height: 860px;
background-color:#171717;
box-shadow:5px 5px 5px 5px rgba(0, 0, 0, 0.5),0px 0px 0px 0px rgba(255, 255, 255, 0.5) inset;
border-radius: 30px 30px 30px 30px ;
position:relative
}
#button_power
{
position:absolute;
left:100px;
top:100px;
width:100px;
height:100px;
}
.button_mode{
width:60px;
height: 40px;
}
.button_pressed{
box-shadow:0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,0px 2px 2px 0px rgba(255, 255, 255, 0.5);
}
.button_unpressed{
box-shadow:0px 2px 2px 0px rgba(0, 0, 0, 0.5),0px 2px 2px 0px rgba(255, 255, 255, 0.5) inset;
}
.button_white{
color: #e0e0e0;
background: #a5cd4e;
}
.button_green {
color: #7FFF00;
text-shadow: 0 0 10px #6a6767, 0 0 20px #444, 0 0 30px #515151, 0 0 40px #FFFAFC, 0 0 70px #3AFF11, 0 0 80px #45FF11, 0 0 100px #4F4F4F, 0 0 150px #18FF11;
}
.button_red {
color: #ff3a3a;
background: #a5cd4e;
}
.button_blue {
color: #176fff;
background: #70c9e3;
}
#div-freq
{
position:absolute;
left: 400px;
top:100px;
height: 200px;
width:1000px;
}
#div-freq > ul > li {
display: inline-block;
font:normal bold 20px tahoma;
text-align:center;
width:87px;
}
#freq_disp{
border-radius: 5px 5px 5px 5px ;
box-shadow:0px 2px 2px 0px rgba(0, 0, 0, 0.5) inset,0px 2px 2px 0px rgba(255, 255, 255, 0.5);
background-color: black;
width:1000px;
padding-top:5px;
padding-left:5px;
margin-top:10px;
margin-bottom:10px;
height: 30px;
}
#freq_disp > ul > li {
display: inline-block;
font:normal bold 14px tahoma;
text-align:center;
}
#freq_disp > ul > li:before{
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
}
#freq_but{
width:1000px;
margin:0;
padding-left:5px;
}
#freq_but > ul > li {
display: inline-block;
font:normal bold 14px tahoma;
text-align:center;
margin-top:5px;
margin-bottom:5px;
}
#freq_but > ul > li:before{
content: '';
display: inline-block;
vertical-align: middle;
height: 100%;
margin-top:5px;
margin-bottom:5px;
}
#div-scoketscontrols
{
position:absolute;
left: 1350px;
top:825px;
width: 280px;
}
#div-scoketscontrols > p
{
display: inline-block;
font:normal bold 14px tahoma;
text-align:center;
margin-right:10px;
}
#div-scoketscontrols > p > img
{
margin-right:5px;
width:10px;
height:10px;
}
#div-latencymeter
{
position:absolute;
left:1680px;
top:840px;
}