some power control buttons implemented
seven-segment post codes added to webui other optimizations
This commit is contained in:
parent
89e8785265
commit
f548353fa6
esp32/src
webui
ipkvm
serial_test.py@ -11,6 +11,7 @@ void loop() {}
|
|||||||
#include <USB.h>
|
#include <USB.h>
|
||||||
#include <USBHIDMouse.h>
|
#include <USBHIDMouse.h>
|
||||||
#include <USBHIDKeyboard.h>
|
#include <USBHIDKeyboard.h>
|
||||||
|
#include <USBHIDSystemControl.h>
|
||||||
|
|
||||||
USBHIDAbsoluteMouse Mouse;
|
USBHIDAbsoluteMouse Mouse;
|
||||||
USBHIDKeyboard Keyboard;
|
USBHIDKeyboard Keyboard;
|
||||||
@ -19,11 +20,15 @@ HardwareSerial &host_serial = Serial;
|
|||||||
HardwareSerial &mobo_serial = Serial1;
|
HardwareSerial &mobo_serial = Serial1;
|
||||||
|
|
||||||
JsonDocument mkb_input;
|
JsonDocument mkb_input;
|
||||||
|
JsonDocument post_codes;
|
||||||
|
JsonDocument power_status;
|
||||||
|
|
||||||
// put function declarations here:
|
// put function declarations here:
|
||||||
int myFunction(int, int);
|
int myFunction(int, int);
|
||||||
|
|
||||||
char buffer[100];
|
const int8_t pwr_button = 3;
|
||||||
|
const int8_t cmos_button = 46;
|
||||||
|
const int8_t pwr_detect = 8;
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
@ -32,15 +37,42 @@ void setup()
|
|||||||
Mouse.begin();
|
Mouse.begin();
|
||||||
Keyboard.begin();
|
Keyboard.begin();
|
||||||
USB.begin();
|
USB.begin();
|
||||||
|
pinMode(pwr_button, OUTPUT);
|
||||||
|
pinMode(cmos_button, OUTPUT);
|
||||||
|
pinMode(pwr_detect, INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
|
static volatile int64_t cur_loop_timestamp = esp_timer_get_time();
|
||||||
|
cur_loop_timestamp = esp_timer_get_time();
|
||||||
|
// Immediately check power status!
|
||||||
|
static volatile int64_t check_power_status_timestamp = -200000;
|
||||||
|
|
||||||
|
if (cur_loop_timestamp - check_power_status_timestamp >= 100000)
|
||||||
|
{
|
||||||
|
if (analogRead(pwr_detect) > 1000)
|
||||||
|
{
|
||||||
|
power_status["pwr"] = "on";
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
power_status["pwr"] = "off";
|
||||||
|
}
|
||||||
|
|
||||||
|
serializeJson(power_status, host_serial);
|
||||||
|
host_serial.write('\n');
|
||||||
|
check_power_status_timestamp = esp_timer_get_time();
|
||||||
|
}
|
||||||
|
|
||||||
while (mobo_serial.available())
|
while (mobo_serial.available())
|
||||||
{
|
{
|
||||||
char c = mobo_serial.read();
|
post_codes["post_code"] = mobo_serial.read();
|
||||||
host_serial.write(c);
|
serializeJson(post_codes, host_serial);
|
||||||
|
host_serial.write('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host_serial.available())
|
if (host_serial.available())
|
||||||
{
|
{
|
||||||
DeserializationError error = deserializeJson(mkb_input, host_serial);
|
DeserializationError error = deserializeJson(mkb_input, host_serial);
|
||||||
@ -54,23 +86,6 @@ void loop()
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//JsonArray key_down = mkb_input["key_down"];
|
|
||||||
//JsonArray key_up = mkb_input["key_up"];
|
|
||||||
////host_serial.println("Hej!");
|
|
||||||
////serializeJsonPretty(key_down, host_serial);
|
|
||||||
////serializeJsonPretty(key_up, host_serial);
|
|
||||||
////host_serial.println("Hej2!");
|
|
||||||
//for (JsonVariant key : key_down)
|
|
||||||
//{
|
|
||||||
// Keyboard.pressRaw(key.as<u8_t>());
|
|
||||||
// //host_serial.println(key.as<u8_t>());
|
|
||||||
//}
|
|
||||||
//for (JsonVariant key : key_up)
|
|
||||||
//{
|
|
||||||
// Keyboard.releaseRaw(key.as<u8_t>());
|
|
||||||
// //host_serial.println(key.as<u8_t>());
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (mkb_input["key_down"].is<JsonVariant>())
|
if (mkb_input["key_down"].is<JsonVariant>())
|
||||||
{
|
{
|
||||||
Keyboard.pressRaw(mkb_input["key_down"].as<uint8_t>());
|
Keyboard.pressRaw(mkb_input["key_down"].as<uint8_t>());
|
||||||
@ -95,6 +110,16 @@ void loop()
|
|||||||
{
|
{
|
||||||
Mouse.release(mkb_input["mouse_up"].as<uint8_t>());
|
Mouse.release(mkb_input["mouse_up"].as<uint8_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (mkb_input["pwr"].is<JsonVariant>())
|
||||||
|
{
|
||||||
|
digitalWrite(pwr_button, mkb_input["pwr"].as<uint8_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (mkb_input["cmos"].is<JsonVariant>())
|
||||||
|
{
|
||||||
|
digitalWrite(cmos_button, mkb_input["cmos"].as<uint8_t>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,4 +100,4 @@ from ipkvm.util.mkb import Esp32Serial
|
|||||||
frame_buffer = feed.FrameBuffer()
|
frame_buffer = feed.FrameBuffer()
|
||||||
esp32_serial = Esp32Serial()
|
esp32_serial = Esp32Serial()
|
||||||
|
|
||||||
from ipkvm import routes
|
from ipkvm import routes, events
|
||||||
|
96
webui/ipkvm/events.py
Normal file
96
webui/ipkvm/events.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
from ipkvm import ui
|
||||||
|
from ipkvm import esp32_serial
|
||||||
|
from ipkvm.util.mkb import HIDKeyCode, HIDMouseScanCodes, GPIO
|
||||||
|
import time
|
||||||
|
|
||||||
|
def power_switch(delay: float):
|
||||||
|
msg = {
|
||||||
|
"pwr": GPIO.HIGH.value
|
||||||
|
}
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
time.sleep(delay)
|
||||||
|
msg = {
|
||||||
|
"pwr": GPIO.LOW.value
|
||||||
|
}
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
|
||||||
|
@ui.on("power_on")
|
||||||
|
def handle_poweron():
|
||||||
|
if esp32_serial.power_status == "off":
|
||||||
|
power_switch(0.2)
|
||||||
|
|
||||||
|
@ui.on("soft_power_off")
|
||||||
|
def handle_soft_poweroff():
|
||||||
|
if esp32_serial.power_status == "on":
|
||||||
|
power_switch(0.2)
|
||||||
|
|
||||||
|
@ui.on("hard_power_off")
|
||||||
|
def handle_hard_poweroff():
|
||||||
|
if esp32_serial.power_status == "on":
|
||||||
|
power_switch(0.5)
|
||||||
|
|
||||||
|
@ui.on("reboot_into_bios")
|
||||||
|
def handle_reboot_bios():
|
||||||
|
if esp32_serial.power_status == "on": # and OS state = offline
|
||||||
|
power_switch(5)
|
||||||
|
time.sleep(2)
|
||||||
|
power_switch(0.2)
|
||||||
|
|
||||||
|
else:
|
||||||
|
power_switch(0.2)
|
||||||
|
|
||||||
|
while time.time() - esp32_serial.bios_timer <= 5 or time.time() - esp32_serial.bios_timer >= 6:
|
||||||
|
print(time.time() - esp32_serial.bios_timer)
|
||||||
|
msg = {
|
||||||
|
"key_down": HIDKeyCode.Delete.value
|
||||||
|
}
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
time.sleep(0.1)
|
||||||
|
msg = {
|
||||||
|
"key_up": HIDKeyCode.Delete.value
|
||||||
|
}
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
@ui.on('key_down')
|
||||||
|
def handle_keydown(data: str):
|
||||||
|
msg = {
|
||||||
|
"key_down": HIDKeyCode[data].value
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
|
||||||
|
@ui.on('key_up')
|
||||||
|
def handle_keyup(data: str):
|
||||||
|
msg = {
|
||||||
|
"key_up": HIDKeyCode[data].value
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
|
||||||
|
@ui.on("mouse_move")
|
||||||
|
def handle_mousemove(data: list[int]):
|
||||||
|
msg = {
|
||||||
|
"mouse_coord": {
|
||||||
|
"x": data[0],
|
||||||
|
"y": data[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
|
||||||
|
@ui.on('mouse_down')
|
||||||
|
def handle_mousedown(data: int):
|
||||||
|
msg = {
|
||||||
|
"mouse_down": HIDMouseScanCodes[data]
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
||||||
|
|
||||||
|
@ui.on('mouse_up')
|
||||||
|
def handle_mouseup(data: int):
|
||||||
|
msg = {
|
||||||
|
"mouse_up": HIDMouseScanCodes[data]
|
||||||
|
}
|
||||||
|
|
||||||
|
esp32_serial.mkb_queue.put(msg)
|
@ -6,6 +6,8 @@ from ipkvm import profile
|
|||||||
from ipkvm.util import video
|
from ipkvm.util import video
|
||||||
from ipkvm import logger
|
from ipkvm import logger
|
||||||
import time
|
import time
|
||||||
|
from PIL import Image
|
||||||
|
import io
|
||||||
|
|
||||||
class FrameBuffer(threading.Thread):
|
class FrameBuffer(threading.Thread):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -35,8 +37,20 @@ class FrameBuffer(threading.Thread):
|
|||||||
if not success:
|
if not success:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
ret, buffer = cv2.imencode('.jpg', frame)
|
# ret, buffer = cv2.imencode('.jpg', frame)
|
||||||
self.cur_frame = buffer.tobytes()
|
# self.cur_frame = buffer.tobytes()
|
||||||
|
# Convert BGR (OpenCV) to RGB (PIL)
|
||||||
|
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
|
||||||
|
|
||||||
|
# Convert to PIL Image
|
||||||
|
img = Image.fromarray(frame_rgb)
|
||||||
|
|
||||||
|
# Save to a bytes buffer (for in-memory use)
|
||||||
|
buffer = io.BytesIO()
|
||||||
|
img.save(buffer, format="JPEG")
|
||||||
|
jpeg_bytes = buffer.getvalue() # This contains the JPEG image as bytes
|
||||||
|
self.cur_frame = jpeg_bytes
|
||||||
|
|
||||||
self.new_frame.set()
|
self.new_frame.set()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from ipkvm import app, ui
|
from ipkvm import app
|
||||||
from ipkvm import frame_buffer, esp32_serial
|
from ipkvm import frame_buffer
|
||||||
from flask import Response, render_template
|
from flask import Response, render_template
|
||||||
from ipkvm.util.mkb import HIDKeyCode, HIDMouseScanCodes
|
|
||||||
|
|
||||||
def generate_frames():
|
def generate_frames():
|
||||||
while True:
|
while True:
|
||||||
@ -9,49 +9,6 @@ def generate_frames():
|
|||||||
frame_buffer.new_frame.clear()
|
frame_buffer.new_frame.clear()
|
||||||
yield (b'--frame\r\n'
|
yield (b'--frame\r\n'
|
||||||
b'Content-Type: image/jpeg\r\n\r\n' + frame_buffer.cur_frame + b'\r\n')
|
b'Content-Type: image/jpeg\r\n\r\n' + frame_buffer.cur_frame + b'\r\n')
|
||||||
|
|
||||||
@ui.on('key_down')
|
|
||||||
def handle_keydown(data: str):
|
|
||||||
msg = {
|
|
||||||
"key_down": HIDKeyCode[data].value
|
|
||||||
}
|
|
||||||
|
|
||||||
esp32_serial.mkb_queue.put(msg)
|
|
||||||
|
|
||||||
@ui.on('key_up')
|
|
||||||
def handle_keyup(data: str):
|
|
||||||
msg = {
|
|
||||||
"key_up": HIDKeyCode[data].value
|
|
||||||
}
|
|
||||||
|
|
||||||
esp32_serial.mkb_queue.put(msg)
|
|
||||||
|
|
||||||
@ui.on("mouse_move")
|
|
||||||
def handle_mousemove(data: list[int]):
|
|
||||||
msg = {
|
|
||||||
"mouse_coord": {
|
|
||||||
"x": data[0],
|
|
||||||
"y": data[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
esp32_serial.mkb_queue.put(msg)
|
|
||||||
|
|
||||||
@ui.on('mouse_down')
|
|
||||||
def handle_mousedown(data: int):
|
|
||||||
msg = {
|
|
||||||
"mouse_down": HIDMouseScanCodes[data]
|
|
||||||
}
|
|
||||||
|
|
||||||
esp32_serial.mkb_queue.put(msg)
|
|
||||||
|
|
||||||
@ui.on('mouse_up')
|
|
||||||
def handle_mouseup(data: int):
|
|
||||||
msg = {
|
|
||||||
"mouse_up": HIDMouseScanCodes[data]
|
|
||||||
}
|
|
||||||
|
|
||||||
esp32_serial.mkb_queue.put(msg)
|
|
||||||
|
|
||||||
@app.route('/video_feed')
|
@app.route('/video_feed')
|
||||||
def video_feed():
|
def video_feed():
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
const streamview = document.getElementById('streamview');
|
|
||||||
var last_mouse_update = Date.now()
|
var last_mouse_update = Date.now()
|
||||||
|
|
||||||
var socket = io();
|
var socket = io();
|
||||||
|
|
||||||
|
function mkbhandler_load()
|
||||||
|
{
|
||||||
|
const streamview = document.getElementById('streamview');
|
||||||
|
|
||||||
|
streamview.addEventListener("mouseenter", enable_listener);
|
||||||
|
streamview.addEventListener("mouseleave", disable_listener);
|
||||||
|
}
|
||||||
|
|
||||||
function keydown_handler(event)
|
function keydown_handler(event)
|
||||||
{
|
{
|
||||||
socket.emit('key_down', event.code);
|
socket.emit('key_down', event.code);
|
||||||
@ -73,5 +80,4 @@ function disable_listener()
|
|||||||
document.removeEventListener('contextmenu', prevent_right_click);
|
document.removeEventListener('contextmenu', prevent_right_click);
|
||||||
}
|
}
|
||||||
|
|
||||||
streamview.addEventListener("mouseenter", enable_listener);
|
window.addEventListener("load", mkbhandler_load);
|
||||||
streamview.addEventListener("mouseleave", disable_listener);
|
|
28
webui/ipkvm/static/js/seven_segment.js
Normal file
28
webui/ipkvm/static/js/seven_segment.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
var display = new SegmentDisplay("display");
|
||||||
|
|
||||||
|
function sevensegment_load()
|
||||||
|
{
|
||||||
|
display.pattern = "##";
|
||||||
|
display.displayAngle = 10;
|
||||||
|
display.digitHeight = 20;
|
||||||
|
display.digitWidth = 14;
|
||||||
|
display.digitDistance = 2.5;
|
||||||
|
display.segmentWidth = 2;
|
||||||
|
display.segmentDistance = 0.3;
|
||||||
|
display.segmentCount = 7;
|
||||||
|
display.cornerType = 0;
|
||||||
|
display.colorOn = "#ff0000";
|
||||||
|
display.colorOff = "#4b1e05";
|
||||||
|
display.setValue("00");
|
||||||
|
display.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_seven_segment(data)
|
||||||
|
{
|
||||||
|
console.log(data);
|
||||||
|
display.setValue(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.on("update_seven_segment", update_seven_segment);
|
||||||
|
|
||||||
|
window.addEventListener("load", sevensegment_load);
|
558
webui/ipkvm/static/js/vendor/SegmentDisplay/segment-display.js
vendored
Normal file
558
webui/ipkvm/static/js/vendor/SegmentDisplay/segment-display.js
vendored
Normal file
@ -0,0 +1,558 @@
|
|||||||
|
/*!
|
||||||
|
* segment-display.js
|
||||||
|
*
|
||||||
|
* Copyright 2012, Rüdiger Appel
|
||||||
|
* http://www.3quarks.com
|
||||||
|
* Published under Creative Commons 3.0 License.
|
||||||
|
*
|
||||||
|
* Date: 2012-02-14
|
||||||
|
* Version: 1.0.0
|
||||||
|
*
|
||||||
|
* Dokumentation: http://www.3quarks.com/de/Segmentanzeige
|
||||||
|
* Documentation: http://www.3quarks.com/en/SegmentDisplay
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Segment display types
|
||||||
|
SegmentDisplay.SevenSegment = 7;
|
||||||
|
SegmentDisplay.FourteenSegment = 14;
|
||||||
|
SegmentDisplay.SixteenSegment = 16;
|
||||||
|
|
||||||
|
// Segment corner types
|
||||||
|
SegmentDisplay.SymmetricCorner = 0;
|
||||||
|
SegmentDisplay.SquaredCorner = 1;
|
||||||
|
SegmentDisplay.RoundedCorner = 2;
|
||||||
|
|
||||||
|
|
||||||
|
function SegmentDisplay(displayId) {
|
||||||
|
this.displayId = displayId;
|
||||||
|
this.pattern = '##:##:##';
|
||||||
|
this.value = '12:34:56';
|
||||||
|
this.digitHeight = 20;
|
||||||
|
this.digitWidth = 10;
|
||||||
|
this.digitDistance = 2.5;
|
||||||
|
this.displayAngle = 12;
|
||||||
|
this.segmentWidth = 2.5;
|
||||||
|
this.segmentDistance = 0.2;
|
||||||
|
this.segmentCount = SegmentDisplay.SevenSegment;
|
||||||
|
this.cornerType = SegmentDisplay.RoundedCorner;
|
||||||
|
this.colorOn = 'rgb(233, 93, 15)';
|
||||||
|
this.colorOff = 'rgb(75, 30, 5)';
|
||||||
|
};
|
||||||
|
|
||||||
|
SegmentDisplay.prototype.setValue = function(value) {
|
||||||
|
this.value = value;
|
||||||
|
this.draw();
|
||||||
|
};
|
||||||
|
|
||||||
|
SegmentDisplay.prototype.draw = function() {
|
||||||
|
var display = document.getElementById(this.displayId);
|
||||||
|
if (display) {
|
||||||
|
var context = display.getContext('2d');
|
||||||
|
if (context) {
|
||||||
|
// clear canvas
|
||||||
|
context.clearRect(0, 0, display.width, display.height);
|
||||||
|
|
||||||
|
// compute and check display width
|
||||||
|
var width = 0;
|
||||||
|
var first = true;
|
||||||
|
if (this.pattern) {
|
||||||
|
for (var i = 0; i < this.pattern.length; i++) {
|
||||||
|
var c = this.pattern.charAt(i).toLowerCase();
|
||||||
|
if (c == '#') {
|
||||||
|
width += this.digitWidth;
|
||||||
|
} else if (c == '.' || c == ':') {
|
||||||
|
width += this.segmentWidth;
|
||||||
|
} else if (c != ' ') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
width += first ? 0 : this.digitDistance;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (width <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute skew factor
|
||||||
|
var angle = -1.0 * Math.max(-45.0, Math.min(45.0, this.displayAngle));
|
||||||
|
var skew = Math.tan((angle * Math.PI) / 180.0);
|
||||||
|
|
||||||
|
// compute scale factor
|
||||||
|
var scale = Math.min(display.width / (width + Math.abs(skew * this.digitHeight)), display.height / this.digitHeight);
|
||||||
|
|
||||||
|
// compute display offset
|
||||||
|
var offsetX = (display.width - (width + skew * this.digitHeight) * scale) / 2.0;
|
||||||
|
var offsetY = (display.height - this.digitHeight * scale) / 2.0;
|
||||||
|
|
||||||
|
// context transformation
|
||||||
|
context.save();
|
||||||
|
context.translate(offsetX, offsetY);
|
||||||
|
context.scale(scale, scale);
|
||||||
|
context.transform(1, 0, skew, 1, 0, 0);
|
||||||
|
|
||||||
|
// draw segments
|
||||||
|
var xPos = 0;
|
||||||
|
var size = (this.value) ? this.value.length : 0;
|
||||||
|
for (var i = 0; i < this.pattern.length; i++) {
|
||||||
|
var mask = this.pattern.charAt(i);
|
||||||
|
var value = (i < size) ? this.value.charAt(i).toLowerCase() : ' ';
|
||||||
|
xPos += this.drawDigit(context, xPos, mask, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// finish drawing
|
||||||
|
context.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SegmentDisplay.prototype.drawDigit = function(context, xPos, mask, c) {
|
||||||
|
switch (mask) {
|
||||||
|
case '#':
|
||||||
|
var r = Math.sqrt(this.segmentWidth * this.segmentWidth / 2.0);
|
||||||
|
var d = Math.sqrt(this.segmentDistance * this.segmentDistance / 2.0);
|
||||||
|
var e = d / 2.0;
|
||||||
|
var f = (this.segmentWidth - d) * Math.sin((45.0 * Math.PI) / 180.0);
|
||||||
|
var g = f / 2.0;
|
||||||
|
var h = (this.digitHeight - 3.0 * this.segmentWidth) / 2.0;
|
||||||
|
var w = (this.digitWidth - 3.0 * this.segmentWidth) / 2.0;
|
||||||
|
var s = this.segmentWidth / 2.0;
|
||||||
|
var t = this.digitWidth / 2.0;
|
||||||
|
|
||||||
|
// draw segment a (a1 and a2 for 16 segments)
|
||||||
|
if (this.segmentCount == 16) {
|
||||||
|
var x = xPos;
|
||||||
|
var y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@%');
|
||||||
|
context.beginPath();
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.moveTo(x + s + d, y + s);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.moveTo(x + s + e, y + s - e);
|
||||||
|
context.lineTo(x + this.segmentWidth, y);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
|
||||||
|
}
|
||||||
|
context.lineTo(x + t - d - s, y);
|
||||||
|
context.lineTo(x + t - d, y + s);
|
||||||
|
context.lineTo(x + t - d - s, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
var x = xPos;
|
||||||
|
var y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '02356789abcdefgiopqrstz@');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + t + d + s, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + t + d, y + s);
|
||||||
|
context.lineTo(x + t + d + s, y);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - e, y + s - e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
|
||||||
|
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
var x = xPos;
|
||||||
|
var y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '02356789acefp', '02356789abcdefgiopqrstz@');
|
||||||
|
context.beginPath();
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.moveTo(x + s + d, y + s);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.moveTo(x + s + e, y + s - e);
|
||||||
|
context.lineTo(x + this.segmentWidth, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - e, y + s - e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.moveTo(x + this.segmentWidth - f, y + this.segmentWidth - f - d);
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth - g, y, x + this.segmentWidth, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y);
|
||||||
|
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y, x + this.digitWidth - this.segmentWidth + f, y + this.segmentWidth - f - d);
|
||||||
|
}
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw segment b
|
||||||
|
x = xPos + this.digitWidth - this.segmentWidth;
|
||||||
|
y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '01234789adhpy', '01234789abdhjmnopqruwy');
|
||||||
|
context.beginPath();
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.moveTo(x + s, y + s + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.moveTo(x + s + e, y + s + e);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.moveTo(x + f + d, y + this.segmentWidth - f);
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth, y + this.segmentWidth - g, x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
}
|
||||||
|
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
|
||||||
|
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
context.lineTo(x, y + this.segmentWidth + d);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment c
|
||||||
|
x = xPos + this.digitWidth - this.segmentWidth;
|
||||||
|
y = h + this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '013456789abdhnouy', '01346789abdghjmnoqsuw@', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + s, y + s + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + s + e, y + h + this.segmentWidth + s - e);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth, y + h + this.segmentWidth + g, x + f + d, y + h + this.segmentWidth + f); //
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment d (d1 and d2 for 16 segments)
|
||||||
|
if (this.segmentCount == 16) {
|
||||||
|
x = xPos;
|
||||||
|
y = this.digitHeight - this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.segmentWidth + d, y);
|
||||||
|
context.lineTo(x + t - d - s, y);
|
||||||
|
context.lineTo(x + t - d, y + s);
|
||||||
|
context.lineTo(x + t - d - s, y + this.segmentWidth);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + s + d, y + s);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + s + e, y + s + e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
|
||||||
|
context.lineTo(x + this.segmentWidth - f, y + f + d);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
x = xPos;
|
||||||
|
y = this.digitHeight - this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '0235689bcdegijloqsuz_=@', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + t + d + s, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + t + d, y + s);
|
||||||
|
context.lineTo(x + t + d + s, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - s - e, y + s + e);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
|
||||||
|
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
x = xPos;
|
||||||
|
y = this.digitHeight - this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '0235689bcdelotuy_', '0235689bcdegijloqsuz_=@');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.segmentWidth + d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + s + d, y + s);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + this.digitWidth - s - e, y + s + e);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + s + e, y + s + e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth + f, y + f + d);
|
||||||
|
context.quadraticCurveTo(x + this.digitWidth - this.segmentWidth + g, y + this.segmentWidth, x + this.digitWidth - this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth);
|
||||||
|
context.quadraticCurveTo(x + this.segmentWidth - g, y + this.segmentWidth, x + this.segmentWidth - f, y + f + d);
|
||||||
|
context.lineTo(x + this.segmentWidth - f, y + f + d);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw segment e
|
||||||
|
x = xPos;
|
||||||
|
y = h + this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '0268abcdefhlnoprtu', '0268acefghjklmnopqruvw@');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + s, y + s + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x + s - e, y + h + this.segmentWidth + s - d + e);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x + this.segmentWidth - f - d, y + h + this.segmentWidth + f);
|
||||||
|
context.quadraticCurveTo(x, y + h + this.segmentWidth + g, x, y + h + this.segmentWidth);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment f
|
||||||
|
x = xPos;
|
||||||
|
y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '045689abcefhlpty', '045689acefghklmnopqrsuvwy@', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.segmentWidth, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
|
||||||
|
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
switch (this.cornerType) {
|
||||||
|
case SegmentDisplay.SymmetricCorner:
|
||||||
|
context.lineTo(x, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + s, y + s + d);
|
||||||
|
break;
|
||||||
|
case SegmentDisplay.SquaredCorner:
|
||||||
|
context.lineTo(x, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + s - e, y + s + e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context.lineTo(x, y + this.segmentWidth);
|
||||||
|
context.quadraticCurveTo(x, y + this.segmentWidth - g, x + this.segmentWidth - f - d, y + this.segmentWidth - f);
|
||||||
|
context.lineTo(x + this.segmentWidth - f - d, y + this.segmentWidth - f);
|
||||||
|
}
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment g for 7 segments
|
||||||
|
if (this.segmentCount == 7) {
|
||||||
|
x = xPos;
|
||||||
|
y = (this.digitHeight - this.segmentWidth) / 2.0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, '2345689abdefhnoprty-=');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + s + d, y + s);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw inner segments for the fourteen- and sixteen-segment-display
|
||||||
|
if (this.segmentCount != 7) {
|
||||||
|
// draw segment g1
|
||||||
|
x = xPos;
|
||||||
|
y = (this.digitHeight - this.segmentWidth) / 2.0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '2345689aefhkprsy-+*=', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + s + d, y + s);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y);
|
||||||
|
context.lineTo(x + t - d - s, y);
|
||||||
|
context.lineTo(x + t - d, y + s);
|
||||||
|
context.lineTo(x + t - d - s, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + this.segmentWidth + d, y + this.segmentWidth);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment g2
|
||||||
|
x = xPos;
|
||||||
|
y = (this.digitHeight - this.segmentWidth) / 2.0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '234689abefghprsy-+*=@', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + t + d, y + s);
|
||||||
|
context.lineTo(x + t + d + s, y);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y);
|
||||||
|
context.lineTo(x + this.digitWidth - s - d, y + s);
|
||||||
|
context.lineTo(x + this.digitWidth - this.segmentWidth - d, y + this.segmentWidth);
|
||||||
|
context.lineTo(x + t + d + s, y + this.segmentWidth);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment j
|
||||||
|
x = xPos + t - s;
|
||||||
|
y = 0;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, 'bdit+*', '%');
|
||||||
|
context.beginPath();
|
||||||
|
if (this.segmentCount == 14) {
|
||||||
|
context.moveTo(x, y + this.segmentWidth + this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + this.segmentDistance);
|
||||||
|
} else {
|
||||||
|
context.moveTo(x, y + this.segmentWidth + d);
|
||||||
|
context.lineTo(x + s, y + s + d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y + this.segmentWidth + d);
|
||||||
|
}
|
||||||
|
context.lineTo(x + this.segmentWidth, y + h + this.segmentWidth - d);
|
||||||
|
context.lineTo(x + s, y + h + this.segmentWidth + s - d);
|
||||||
|
context.lineTo(x, y + h + this.segmentWidth - d);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment m
|
||||||
|
x = xPos + t - s;
|
||||||
|
y = this.digitHeight;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, 'bdity+*@', '%');
|
||||||
|
context.beginPath();
|
||||||
|
if (this.segmentCount == 14) {
|
||||||
|
context.moveTo(x, y - this.segmentWidth - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentWidth, y - this.segmentWidth - this.segmentDistance);
|
||||||
|
} else {
|
||||||
|
context.moveTo(x, y - this.segmentWidth - d);
|
||||||
|
context.lineTo(x + s, y - s - d);
|
||||||
|
context.lineTo(x + this.segmentWidth, y - this.segmentWidth - d);
|
||||||
|
}
|
||||||
|
context.lineTo(x + this.segmentWidth, y - h - this.segmentWidth + d);
|
||||||
|
context.lineTo(x + s, y - h - this.segmentWidth - s + d);
|
||||||
|
context.lineTo(x, y - h - this.segmentWidth + d);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment h
|
||||||
|
x = xPos + this.segmentWidth;
|
||||||
|
y = this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, 'mnx\\*');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
|
||||||
|
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment k
|
||||||
|
x = xPos + w + 2.0 * this.segmentWidth;
|
||||||
|
y = this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '0kmvxz/*', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
|
||||||
|
context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
|
||||||
|
context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment l
|
||||||
|
x = xPos + w + 2.0 * this.segmentWidth;
|
||||||
|
y = h + 2.0 * this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '5knqrwx\\*');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + this.segmentDistance, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance + r, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance - r);
|
||||||
|
context.lineTo(x + w - this.segmentDistance , y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance - r , y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + this.segmentDistance + r);
|
||||||
|
context.fill();
|
||||||
|
|
||||||
|
// draw segment n
|
||||||
|
x = xPos + this.segmentWidth;
|
||||||
|
y = h + 2.0 * this.segmentWidth;
|
||||||
|
context.fillStyle = this.getSegmentColor(c, null, '0vwxz/*', '%');
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x + w - this.segmentDistance, y + this.segmentDistance);
|
||||||
|
context.lineTo(x + w - this.segmentDistance, y + this.segmentDistance + r);
|
||||||
|
context.lineTo(x + this.segmentDistance + r, y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance);
|
||||||
|
context.lineTo(x + this.segmentDistance, y + h - this.segmentDistance - r);
|
||||||
|
context.lineTo(x + w - this.segmentDistance - r, y + this.segmentDistance);
|
||||||
|
context.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.digitDistance + this.digitWidth;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
context.fillStyle = (c == '#') || (c == '.') ? this.colorOn : this.colorOff;
|
||||||
|
this.drawPoint(context, xPos, this.digitHeight - this.segmentWidth, this.segmentWidth);
|
||||||
|
return this.digitDistance + this.segmentWidth;
|
||||||
|
|
||||||
|
case ':':
|
||||||
|
context.fillStyle = (c == '#') || (c == ':') ? this.colorOn : this.colorOff;
|
||||||
|
var y = (this.digitHeight - this.segmentWidth) / 2.0 - this.segmentWidth;
|
||||||
|
this.drawPoint(context, xPos, y, this.segmentWidth);
|
||||||
|
this.drawPoint(context, xPos, y + 2.0 * this.segmentWidth, this.segmentWidth);
|
||||||
|
return this.digitDistance + this.segmentWidth;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return this.digitDistance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SegmentDisplay.prototype.drawPoint = function(context, x1, y1, size) {
|
||||||
|
var x2 = x1 + size;
|
||||||
|
var y2 = y1 + size;
|
||||||
|
var d = size / 4.0;
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.moveTo(x2 - d, y1);
|
||||||
|
context.quadraticCurveTo(x2, y1, x2, y1 + d);
|
||||||
|
context.lineTo(x2, y2 - d);
|
||||||
|
context.quadraticCurveTo(x2, y2, x2 - d, y2);
|
||||||
|
context.lineTo(x1 + d, y2);
|
||||||
|
context.quadraticCurveTo(x1, y2, x1, y2 - d);
|
||||||
|
context.lineTo(x1, y1 + d);
|
||||||
|
context.quadraticCurveTo(x1, y1, x1 + d, y1);
|
||||||
|
context.fill();
|
||||||
|
};
|
||||||
|
|
||||||
|
SegmentDisplay.prototype.getSegmentColor = function(c, charSet7, charSet14, charSet16) {
|
||||||
|
if (c == '#') {
|
||||||
|
return this.colorOn;
|
||||||
|
} else {
|
||||||
|
switch (this.segmentCount) {
|
||||||
|
case 7: return (charSet7.indexOf(c) == -1) ? this.colorOff : this.colorOn;
|
||||||
|
case 14: return (charSet14.indexOf(c) == -1) ? this.colorOff : this.colorOn;
|
||||||
|
case 16: var pattern = charSet14 + (charSet16 === undefined ? '' : charSet16);
|
||||||
|
return (pattern.indexOf(c) == -1) ? this.colorOff : this.colorOn;
|
||||||
|
default: return this.colorOff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
0
webui/ipkvm/static/vendor/socket.io.min.js → webui/ipkvm/static/js/vendor/socketio/socket.io.min.js
vendored
0
webui/ipkvm/static/vendor/socket.io.min.js → webui/ipkvm/static/js/vendor/socketio/socket.io.min.js
vendored
1
webui/ipkvm/static/js/vendor/socketio/socket.io.min.js.map
vendored
Normal file
1
webui/ipkvm/static/js/vendor/socketio/socket.io.min.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,14 +1,30 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
<script src="{{ url_for('static', filename='vendor/socket.io.min.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/vendor/socketio/socket.io.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/vendor/SegmentDisplay/segment-display.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/mkb_handler.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/seven_segment.js') }}"></script>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>IP KVM & OC Tuner</title>
|
<title>IP KVM & OC Tuner</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<div id="streamview" class="stream-container">
|
<body>
|
||||||
<img src="/video_feed" class="stream-view" />
|
<div id="streamview" class="stream-container">
|
||||||
</div>
|
<img src="/video_feed" class="stream-view" />
|
||||||
</body>
|
</div>
|
||||||
</html>
|
<button type="button" onclick="socket.emit(`power_on`);">Power on</button>
|
||||||
<script src="{{ url_for('static', filename='mkb_handler.js') }}"></script>
|
<button type="button" onclick="socket.emit(`soft_power_off`);">Soft power off</button>
|
||||||
|
<button type="button" onclick="socket.emit(`hard_power_off`);">Hard power off</button>
|
||||||
|
<button type="button" onclick="socket.emit(`reboot`);">Reboot</button>
|
||||||
|
<button type="button" onclick="socket.emit(`reboot_into_bios`);">Reboot into BIOS</button>
|
||||||
|
<button type="button" onclick="socket.emit(`clear_cmos`);">Clear CMOS</button>
|
||||||
|
<div id="displayView" class="topic" style="background-color: rgb(36, 30, 30); border: 3px solid rgb(153, 153, 153); width: 300px; height: 188px;">
|
||||||
|
<div style="padding:20px">
|
||||||
|
<canvas id="display" width="260" height="140">
|
||||||
|
Your browser is unfortunately not supported.
|
||||||
|
</canvas>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -5,8 +5,271 @@ from ipkvm import profile
|
|||||||
import threading
|
import threading
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
|
from ipkvm import ui
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
|
# python can't use NUMBERS as enum keys?!
|
||||||
|
|
||||||
|
POSTHex7Segment = {
|
||||||
|
0: "00",
|
||||||
|
1: "01",
|
||||||
|
2: "02",
|
||||||
|
3: "03",
|
||||||
|
4: "04",
|
||||||
|
5: "05",
|
||||||
|
6: "06",
|
||||||
|
7: "07",
|
||||||
|
8: "08",
|
||||||
|
9: "09",
|
||||||
|
10: "0A",
|
||||||
|
11: "0b",
|
||||||
|
12: "0C",
|
||||||
|
13: "0d",
|
||||||
|
14: "0E",
|
||||||
|
15: "0F",
|
||||||
|
16: "10",
|
||||||
|
17: "11",
|
||||||
|
18: "12",
|
||||||
|
19: "13",
|
||||||
|
20: "14",
|
||||||
|
21: "15",
|
||||||
|
22: "16",
|
||||||
|
23: "17",
|
||||||
|
24: "18",
|
||||||
|
25: "19",
|
||||||
|
26: "1A",
|
||||||
|
27: "1b",
|
||||||
|
28: "1C",
|
||||||
|
29: "1d",
|
||||||
|
30: "1E",
|
||||||
|
31: "1F",
|
||||||
|
32: "20",
|
||||||
|
33: "21",
|
||||||
|
34: "22",
|
||||||
|
35: "23",
|
||||||
|
36: "24",
|
||||||
|
37: "25",
|
||||||
|
38: "26",
|
||||||
|
39: "27",
|
||||||
|
40: "28",
|
||||||
|
41: "29",
|
||||||
|
42: "2A",
|
||||||
|
43: "2b",
|
||||||
|
44: "2C",
|
||||||
|
45: "2d",
|
||||||
|
46: "2E",
|
||||||
|
47: "2F",
|
||||||
|
48: "30",
|
||||||
|
49: "31",
|
||||||
|
50: "32",
|
||||||
|
51: "33",
|
||||||
|
52: "34",
|
||||||
|
53: "35",
|
||||||
|
54: "36",
|
||||||
|
55: "37",
|
||||||
|
56: "38",
|
||||||
|
57: "39",
|
||||||
|
58: "3A",
|
||||||
|
59: "3b",
|
||||||
|
60: "3C",
|
||||||
|
61: "3d",
|
||||||
|
62: "3E",
|
||||||
|
63: "3F",
|
||||||
|
64: "40",
|
||||||
|
65: "41",
|
||||||
|
66: "42",
|
||||||
|
67: "43",
|
||||||
|
68: "44",
|
||||||
|
69: "45",
|
||||||
|
70: "46",
|
||||||
|
71: "47",
|
||||||
|
72: "48",
|
||||||
|
73: "49",
|
||||||
|
74: "4A",
|
||||||
|
75: "4b",
|
||||||
|
76: "4C",
|
||||||
|
77: "4d",
|
||||||
|
78: "4E",
|
||||||
|
79: "4F",
|
||||||
|
80: "50",
|
||||||
|
81: "51",
|
||||||
|
82: "52",
|
||||||
|
83: "53",
|
||||||
|
84: "54",
|
||||||
|
85: "55",
|
||||||
|
86: "56",
|
||||||
|
87: "57",
|
||||||
|
88: "58",
|
||||||
|
89: "59",
|
||||||
|
90: "5A",
|
||||||
|
91: "5b",
|
||||||
|
92: "5C",
|
||||||
|
93: "5d",
|
||||||
|
94: "5E",
|
||||||
|
95: "5F",
|
||||||
|
96: "60",
|
||||||
|
97: "61",
|
||||||
|
98: "62",
|
||||||
|
99: "63",
|
||||||
|
100: "64",
|
||||||
|
101: "65",
|
||||||
|
102: "66",
|
||||||
|
103: "67",
|
||||||
|
104: "68",
|
||||||
|
105: "69",
|
||||||
|
106: "6A",
|
||||||
|
107: "6b",
|
||||||
|
108: "6C",
|
||||||
|
109: "6d",
|
||||||
|
110: "6E",
|
||||||
|
111: "6F",
|
||||||
|
112: "70",
|
||||||
|
113: "71",
|
||||||
|
114: "72",
|
||||||
|
115: "73",
|
||||||
|
116: "74",
|
||||||
|
117: "75",
|
||||||
|
118: "76",
|
||||||
|
119: "77",
|
||||||
|
120: "78",
|
||||||
|
121: "79",
|
||||||
|
122: "7A",
|
||||||
|
123: "7b",
|
||||||
|
124: "7C",
|
||||||
|
125: "7d",
|
||||||
|
126: "7E",
|
||||||
|
127: "7F",
|
||||||
|
128: "80",
|
||||||
|
129: "81",
|
||||||
|
130: "82",
|
||||||
|
131: "83",
|
||||||
|
132: "84",
|
||||||
|
133: "85",
|
||||||
|
134: "86",
|
||||||
|
135: "87",
|
||||||
|
136: "88",
|
||||||
|
137: "89",
|
||||||
|
138: "8A",
|
||||||
|
139: "8b",
|
||||||
|
140: "8C",
|
||||||
|
141: "8d",
|
||||||
|
142: "8E",
|
||||||
|
143: "8F",
|
||||||
|
144: "90",
|
||||||
|
145: "91",
|
||||||
|
146: "92",
|
||||||
|
147: "93",
|
||||||
|
148: "94",
|
||||||
|
149: "95",
|
||||||
|
150: "96",
|
||||||
|
151: "97",
|
||||||
|
152: "98",
|
||||||
|
153: "99",
|
||||||
|
154: "9A",
|
||||||
|
155: "9b",
|
||||||
|
156: "9C",
|
||||||
|
157: "9d",
|
||||||
|
158: "9E",
|
||||||
|
159: "9F",
|
||||||
|
160: "A0",
|
||||||
|
161: "A1",
|
||||||
|
162: "A2",
|
||||||
|
163: "A3",
|
||||||
|
164: "A4",
|
||||||
|
165: "A5",
|
||||||
|
166: "A6",
|
||||||
|
167: "A7",
|
||||||
|
168: "A8",
|
||||||
|
169: "A9",
|
||||||
|
170: "AA",
|
||||||
|
171: "Ab",
|
||||||
|
172: "AC",
|
||||||
|
173: "Ad",
|
||||||
|
174: "AE",
|
||||||
|
175: "AF",
|
||||||
|
176: "b0",
|
||||||
|
177: "b1",
|
||||||
|
178: "b2",
|
||||||
|
179: "b3",
|
||||||
|
180: "b4",
|
||||||
|
181: "b5",
|
||||||
|
182: "b6",
|
||||||
|
183: "b7",
|
||||||
|
184: "b8",
|
||||||
|
185: "b9",
|
||||||
|
186: "bA",
|
||||||
|
187: "bb",
|
||||||
|
188: "bC",
|
||||||
|
189: "bd",
|
||||||
|
190: "bE",
|
||||||
|
191: "bF",
|
||||||
|
192: "C0",
|
||||||
|
193: "C1",
|
||||||
|
194: "C2",
|
||||||
|
195: "C3",
|
||||||
|
196: "C4",
|
||||||
|
197: "C5",
|
||||||
|
198: "C6",
|
||||||
|
199: "C7",
|
||||||
|
200: "C8",
|
||||||
|
201: "C9",
|
||||||
|
202: "CA",
|
||||||
|
203: "Cb",
|
||||||
|
204: "CC",
|
||||||
|
205: "Cd",
|
||||||
|
206: "CE",
|
||||||
|
207: "CF",
|
||||||
|
208: "d0",
|
||||||
|
209: "d1",
|
||||||
|
210: "d2",
|
||||||
|
211: "d3",
|
||||||
|
212: "d4",
|
||||||
|
213: "d5",
|
||||||
|
214: "d6",
|
||||||
|
215: "d7",
|
||||||
|
216: "d8",
|
||||||
|
217: "d9",
|
||||||
|
218: "dA",
|
||||||
|
219: "db",
|
||||||
|
220: "dC",
|
||||||
|
221: "dd",
|
||||||
|
222: "dE",
|
||||||
|
223: "dF",
|
||||||
|
224: "E0",
|
||||||
|
225: "E1",
|
||||||
|
226: "E2",
|
||||||
|
227: "E3",
|
||||||
|
228: "E4",
|
||||||
|
229: "E5",
|
||||||
|
230: "E6",
|
||||||
|
231: "E7",
|
||||||
|
232: "E8",
|
||||||
|
233: "E9",
|
||||||
|
234: "EA",
|
||||||
|
235: "Eb",
|
||||||
|
236: "EC",
|
||||||
|
237: "Ed",
|
||||||
|
238: "EE",
|
||||||
|
239: "EF",
|
||||||
|
240: "F0",
|
||||||
|
241: "F1",
|
||||||
|
242: "F2",
|
||||||
|
243: "F3",
|
||||||
|
244: "F4",
|
||||||
|
245: "F5",
|
||||||
|
246: "F6",
|
||||||
|
247: "F7",
|
||||||
|
248: "F8",
|
||||||
|
249: "F9",
|
||||||
|
250: "FA",
|
||||||
|
251: "Fb",
|
||||||
|
252: "FC",
|
||||||
|
253: "Fd",
|
||||||
|
254: "FE",
|
||||||
|
255: "FF"
|
||||||
|
}
|
||||||
|
|
||||||
# Python can't make number to number enums???
|
|
||||||
HIDMouseScanCodes = {
|
HIDMouseScanCodes = {
|
||||||
0: 1,
|
0: 1,
|
||||||
2: 2,
|
2: 2,
|
||||||
@ -15,6 +278,10 @@ HIDMouseScanCodes = {
|
|||||||
4: 16
|
4: 16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GPIO(IntEnum):
|
||||||
|
LOW = 0
|
||||||
|
HIGH = 1
|
||||||
|
|
||||||
# God Bless CHADGPT
|
# God Bless CHADGPT
|
||||||
class HIDKeyCode(IntEnum):
|
class HIDKeyCode(IntEnum):
|
||||||
"""
|
"""
|
||||||
@ -152,26 +419,49 @@ class Esp32Serial(threading.Thread):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.post_code_queue: Queue[str] = Queue()
|
self.post_code_queue: Queue[str] = Queue()
|
||||||
self.mkb_queue: Queue[dict[str, int | dict[str, int]]] = Queue()
|
self.mkb_queue: Queue[Mapping[str, int | str | Mapping[str, int]]] = Queue()
|
||||||
self.change_serial_device = threading.Event()
|
self.change_serial_device = threading.Event()
|
||||||
self.device = self.get_device()
|
self.device = self.get_device()
|
||||||
|
self.bios_timer = time.time()
|
||||||
|
self.power_status = None
|
||||||
|
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
with self.device as ser:
|
||||||
if self.change_serial_device.is_set():
|
while True:
|
||||||
self.change_serial_device.clear()
|
# if self.change_serial_device.is_set():
|
||||||
self.device = self.get_device()
|
# self.change_serial_device.clear()
|
||||||
|
# self.device = self.get_device()
|
||||||
|
|
||||||
with self.device as ser:
|
|
||||||
while not self.mkb_queue.empty():
|
while not self.mkb_queue.empty():
|
||||||
msg = self.mkb_queue.get()
|
msg = self.mkb_queue.get()
|
||||||
ser.write(json.dumps(msg).encode())
|
ser.write(json.dumps(msg).encode())
|
||||||
|
|
||||||
while ser.in_waiting > 0:
|
while ser.in_waiting > 0:
|
||||||
print(ser.read().hex())
|
try:
|
||||||
|
line = json.loads(ser.readline().decode().strip())
|
||||||
|
|
||||||
|
if "pwr" in line:
|
||||||
|
self.power_status = line["pwr"]
|
||||||
|
|
||||||
|
elif "post_code" in line:
|
||||||
|
# This code is what presents when you are in BIOS, but also... Other times.
|
||||||
|
# In another part of the script, we'll check to see if it's hung around for a few
|
||||||
|
# seconds. If so, we are in BIOS.
|
||||||
|
if POSTHex7Segment[line["post_code"]] != "Ab":
|
||||||
|
self.bios_timer = time.time()
|
||||||
|
|
||||||
|
ui.emit("update_seven_segment", POSTHex7Segment[line["post_code"]])
|
||||||
|
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
continue
|
||||||
|
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
continue
|
||||||
# self.post_code_queue.put(ser.read().hex())
|
# self.post_code_queue.put(ser.read().hex())
|
||||||
|
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
def get_device(self):
|
def get_device(self):
|
||||||
if name == "posix":
|
if name == "posix":
|
||||||
|
@ -41,16 +41,19 @@ def read_serial(port):
|
|||||||
# Open the serial port
|
# Open the serial port
|
||||||
with serial.Serial(port, 115200, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) as ser:
|
with serial.Serial(port, 115200, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) as ser:
|
||||||
print(f"Listening on {port} at 115200 baud...")
|
print(f"Listening on {port} at 115200 baud...")
|
||||||
|
line = ser.readline().decode().strip()
|
||||||
while True:
|
while True:
|
||||||
# Read a line from the serial port
|
# Read a line from the serial port
|
||||||
while ser.in_waiting > 0:
|
while ser.in_waiting > 0:
|
||||||
line = str(ser.read().hex())
|
line = ser.readline().decode().strip()
|
||||||
print(f'{datetime.datetime.now()} {line}')
|
line = json.loads(line)
|
||||||
|
print(line)
|
||||||
|
# print(json.loads(ser.read_all()))
|
||||||
# Print the raw data
|
# Print the raw data
|
||||||
ser.write(json.dumps(test_json_c).encode())
|
#ser.write(json.dumps(test_json_c).encode())
|
||||||
time.sleep(1)
|
#time.sleep(1)
|
||||||
ser.write(json.dumps(test_json_d).encode())
|
#ser.write(json.dumps(test_json_d).encode())
|
||||||
time.sleep(1)
|
#time.sleep(1)
|
||||||
except serial.SerialException as e:
|
except serial.SerialException as e:
|
||||||
print(f"Error: {e}")
|
print(f"Error: {e}")
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user