Add battery indicator
This commit is contained in:
parent
225ba206bc
commit
3ad7b18516
174
core.js
174
core.js
@ -1,7 +1,10 @@
|
|||||||
var device = null;
|
var device = null;
|
||||||
var devname = "";
|
var devname = "";
|
||||||
var mode = 0;
|
var mode = 0;
|
||||||
var disable_btn = false;
|
|
||||||
|
// bitmask: 1: clone, 2: update ds5 firmware, 4: battery low, 8: ds-edge not supported
|
||||||
|
var disable_btn = 0;
|
||||||
|
var last_disable_btn = 0;
|
||||||
|
|
||||||
var lang_orig_text = {};
|
var lang_orig_text = {};
|
||||||
var lang_cur = {};
|
var lang_cur = {};
|
||||||
@ -94,11 +97,18 @@ function is_rare(hw_ver) {
|
|||||||
|
|
||||||
async function ds4_info() {
|
async function ds4_info() {
|
||||||
try {
|
try {
|
||||||
|
var ooc = l("unknown");
|
||||||
|
var is_clone = false;
|
||||||
|
|
||||||
const view = lf("ds4_info", await device.receiveFeatureReport(0xa3));
|
const view = lf("ds4_info", await device.receiveFeatureReport(0xa3));
|
||||||
|
|
||||||
var cmd = view.getUint8(0, true);
|
var cmd = view.getUint8(0, true);
|
||||||
if(cmd != 0xa3 || view.buffer.byteLength != 49) {
|
|
||||||
return false;
|
if(cmd != 0xa3 || view.buffer.byteLength < 49) {
|
||||||
|
if(view.buffer.byteLength != 49) {
|
||||||
|
ooc = l("clone");
|
||||||
|
is_clone = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var k1 = new TextDecoder().decode(view.buffer.slice(1, 0x10));
|
var k1 = new TextDecoder().decode(view.buffer.slice(1, 0x10));
|
||||||
@ -110,19 +120,16 @@ async function ds4_info() {
|
|||||||
var hw_ver_minor= view.getUint16(0x23, true)
|
var hw_ver_minor= view.getUint16(0x23, true)
|
||||||
var sw_ver_major= view.getUint32(0x25, true)
|
var sw_ver_major= view.getUint32(0x25, true)
|
||||||
var sw_ver_minor= view.getUint16(0x25+4, true)
|
var sw_ver_minor= view.getUint16(0x25+4, true)
|
||||||
var ooc = l("unknown");
|
|
||||||
|
|
||||||
ooc = l("original");
|
|
||||||
|
|
||||||
var is_clone = false;
|
|
||||||
try {
|
try {
|
||||||
|
if(!is_clone) {
|
||||||
const view = await device.receiveFeatureReport(0x81);
|
const view = await device.receiveFeatureReport(0x81);
|
||||||
ooc = l("original");
|
ooc = l("original");
|
||||||
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
la("clone");
|
la("clone");
|
||||||
is_clone = true;
|
is_clone = true;
|
||||||
ooc = "<font color='red'><b>" + l("clone") + "</b></font>";
|
ooc = "<font color='red'><b>" + l("clone") + "</b></font>";
|
||||||
disable_btn = true;
|
disable_btn |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_info();
|
clear_info();
|
||||||
@ -145,7 +152,7 @@ async function ds4_info() {
|
|||||||
}
|
}
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
ooc = "<font color='red'><b>" + l("clone") + "</b></font>";
|
ooc = "<font color='red'><b>" + l("clone") + "</b></font>";
|
||||||
disable_btn = true;
|
disable_btn |= 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -516,7 +523,7 @@ async function ds5_info() {
|
|||||||
old_controller = build_date.search(/ 2020| 2021/);
|
old_controller = build_date.search(/ 2020| 2021/);
|
||||||
if(old_controller != -1) {
|
if(old_controller != -1) {
|
||||||
la("ds5_info_error", {"r": "old"})
|
la("ds5_info_error", {"r": "old"})
|
||||||
disable_btn = true;
|
disable_btn |= 2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,7 +791,7 @@ async function disconnect() {
|
|||||||
mode = 0;
|
mode = 0;
|
||||||
device.close();
|
device.close();
|
||||||
device = null;
|
device = null;
|
||||||
disable_btn = false;
|
disable_btn = 0;
|
||||||
reset_circularity();
|
reset_circularity();
|
||||||
$("#offlinebar").show();
|
$("#offlinebar").show();
|
||||||
$("#onlinebar").hide();
|
$("#onlinebar").hide();
|
||||||
@ -1118,6 +1125,46 @@ function refresh_sticks() {
|
|||||||
setTimeout(timeout_ok, 20);
|
setTimeout(timeout_ok, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var last_bat_txt = "";
|
||||||
|
var last_bat_disable = null;
|
||||||
|
|
||||||
|
function bat_percent_to_text(bat_charge, is_charging, is_error) {
|
||||||
|
var icon_txt = "";
|
||||||
|
|
||||||
|
if(bat_charge < 20) {
|
||||||
|
icon_txt = 'fa-battery-empty';
|
||||||
|
} else if(bat_charge < 40) {
|
||||||
|
icon_txt = 'fa-battery-quarter';
|
||||||
|
} else if(bat_charge < 60) {
|
||||||
|
icon_txt = 'fa-battery-half';
|
||||||
|
} else if(bat_charge < 80) {
|
||||||
|
icon_txt = 'fa-battery-three-quarters';
|
||||||
|
} else {
|
||||||
|
icon_txt = 'fa-battery-full';
|
||||||
|
}
|
||||||
|
|
||||||
|
var icon_full = '<i class="fa-solid ' + icon_txt + '"></i>';
|
||||||
|
var bolt_txt = '';
|
||||||
|
if(is_charging)
|
||||||
|
bolt_txt = '<i class="fa-solid fa-bolt"></i>';
|
||||||
|
bat_txt = bat_charge + "%" + ' ' + bolt_txt + ' ' + icon_full;
|
||||||
|
|
||||||
|
if(is_error) {
|
||||||
|
bat_txt = '<font color="red">' + l("error") + '</font>';
|
||||||
|
}
|
||||||
|
return bat_txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_battery_status(bat_capacity, cable_connected, is_charging, is_error) {
|
||||||
|
var bat_txt = bat_percent_to_text(bat_capacity, is_charging);
|
||||||
|
var can_use_tool = (bat_capacity >= 30 && cable_connected && !is_error);
|
||||||
|
|
||||||
|
if(bat_txt != last_bat_txt) {
|
||||||
|
$("#d-bat").html(bat_txt);
|
||||||
|
last_bat_txt = bat_txt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function process_ds4_input(data) {
|
function process_ds4_input(data) {
|
||||||
var lx = data.data.getUint8(0);
|
var lx = data.data.getUint8(0);
|
||||||
var ly = data.data.getUint8(1);
|
var ly = data.data.getUint8(1);
|
||||||
@ -1137,8 +1184,46 @@ function process_ds4_input(data) {
|
|||||||
ll_updated = true;
|
ll_updated = true;
|
||||||
refresh_sticks();
|
refresh_sticks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read battery
|
||||||
|
var bat = data.data.getUint8(29);
|
||||||
|
var bat_data = bat & 0x0f;
|
||||||
|
var bat_status = (bat >> 4) & 1;
|
||||||
|
|
||||||
|
var bat_capacity = 0;
|
||||||
|
var cable_connected = false;
|
||||||
|
var is_charging = false;
|
||||||
|
var is_error = false;
|
||||||
|
|
||||||
|
if(bat_status == 1) {
|
||||||
|
cable_connected = true;
|
||||||
|
if(bat_data < 10) {
|
||||||
|
bat_capacity = Math.min(bat_data * 10 + 5, 100);
|
||||||
|
is_charging = true;
|
||||||
|
} else if(bat_data == 10) {
|
||||||
|
bat_capacity = 100;
|
||||||
|
is_charging = true;
|
||||||
|
} else if(bat_data == 11) {
|
||||||
|
bat_capacity = 100;
|
||||||
|
// charged
|
||||||
|
} else {
|
||||||
|
// error
|
||||||
|
bat_capacity = 0;
|
||||||
|
is_error = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cable_connected = false;
|
||||||
|
if(bat_data < 10) {
|
||||||
|
bat_capacity = bat_data * 10 + 5;
|
||||||
|
} else {
|
||||||
|
bat_capacity = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_battery_status(bat_capacity, cable_connected, is_charging, is_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function process_ds_input(data) {
|
function process_ds_input(data) {
|
||||||
var lx = data.data.getUint8(0);
|
var lx = data.data.getUint8(0);
|
||||||
var ly = data.data.getUint8(1);
|
var ly = data.data.getUint8(1);
|
||||||
@ -1158,6 +1243,30 @@ function process_ds_input(data) {
|
|||||||
ll_updated = true;
|
ll_updated = true;
|
||||||
refresh_sticks();
|
refresh_sticks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var bat = data.data.getUint8(52);
|
||||||
|
var bat_charge = bat & 0x0f;
|
||||||
|
var bat_status = bat >> 4;
|
||||||
|
|
||||||
|
var bat_capacity = 0;
|
||||||
|
var cable_connected = false;
|
||||||
|
var is_charging = false;
|
||||||
|
var is_error = false;
|
||||||
|
|
||||||
|
if(bat_status == 0) {
|
||||||
|
bat_capacity = Math.min(bat_charge * 10 + 5, 100);
|
||||||
|
} else if(bat_status == 1) {
|
||||||
|
bat_capacity = Math.max(bat_charge * 10 + 5, 100);
|
||||||
|
is_charging = true;
|
||||||
|
cable_connected = true;
|
||||||
|
} else if(bat_status == 2) {
|
||||||
|
bat_capacity = 100;
|
||||||
|
cable_connected = true;
|
||||||
|
} else {
|
||||||
|
is_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_battery_status(bat_capacity, cable_connected, is_charging, is_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function continue_connection(report) {
|
async function continue_connection(report) {
|
||||||
@ -1202,7 +1311,7 @@ async function continue_connection(report) {
|
|||||||
connected = true;
|
connected = true;
|
||||||
mode = 0;
|
mode = 0;
|
||||||
devname = l("Sony DualSense Edge");
|
devname = l("Sony DualSense Edge");
|
||||||
disable_btn = true;
|
disable_btn |= 8;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$("#btnconnect").prop("disabled", false);
|
$("#btnconnect").prop("disabled", false);
|
||||||
@ -1228,17 +1337,8 @@ async function continue_connection(report) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(disable_btn) {
|
if(disable_btn != 0)
|
||||||
if(device.productId == 0x0ce6) {
|
update_disable_btn();
|
||||||
show_popup(l("This DualSense controller has outdated firmware.") + "<br>" + l("Please update the firmware and try again."), true);
|
|
||||||
} else if(device.productId == 0x0df2) {
|
|
||||||
show_popup(l("Calibration of the DualSense Edge is not currently supported."));
|
|
||||||
} else {
|
|
||||||
show_popup(l("The device appears to be a DS4 clone. All functionalities are disabled."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".ds-btn").prop("disabled", disable_btn);
|
|
||||||
|
|
||||||
$("#btnconnect").prop("disabled", false);
|
$("#btnconnect").prop("disabled", false);
|
||||||
$("#connectspinner").hide();
|
$("#connectspinner").hide();
|
||||||
@ -1250,10 +1350,36 @@ async function continue_connection(report) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function update_disable_btn() {
|
||||||
|
if(disable_btn == last_disable_btn)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(disable_btn == 0) {
|
||||||
|
$(".ds-btn").prop("disabled", false);
|
||||||
|
last_disable_btn = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".ds-btn").prop("disabled", true);
|
||||||
|
|
||||||
|
// show only one popup
|
||||||
|
if(disable_btn & 1 && !(last_disable_btn & 1)) {
|
||||||
|
show_popup(l("The device appears to be a DS4 clone. All functionalities are disabled."));
|
||||||
|
} else if(disable_btn & 2 && !(last_disable_btn & 2)) {
|
||||||
|
show_popup(l("This DualSense controller has outdated firmware.") + "<br>" + l("Please update the firmware and try again."), true);
|
||||||
|
} else if(disable_btn & 8 && !(last_disable_btn & 8)) {
|
||||||
|
show_popup(l("Calibration of the DualSense Edge is not currently supported."));
|
||||||
|
} else if(disable_btn & 4 && !(last_disable_btn & 4)) {
|
||||||
|
show_popup(l("Please charge controller battery over 30% to use this tool."));
|
||||||
|
}
|
||||||
|
last_disable_btn = disable_btn;
|
||||||
|
}
|
||||||
|
|
||||||
async function connect() {
|
async function connect() {
|
||||||
gj = crypto.randomUUID();
|
gj = crypto.randomUUID();
|
||||||
reset_circularity();
|
reset_circularity();
|
||||||
la("begin");
|
la("begin");
|
||||||
|
last_bat_txt = "";
|
||||||
try {
|
try {
|
||||||
$("#btnconnect").prop("disabled", true);
|
$("#btnconnect").prop("disabled", true);
|
||||||
$("#connectspinner").show();
|
$("#connectspinner").show();
|
||||||
|
20
index.html
20
index.html
@ -11,8 +11,13 @@
|
|||||||
crossorigin="anonymous">
|
crossorigin="anonymous">
|
||||||
|
|
||||||
<link rel="stylesheet"
|
<link rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.2/css/fontawesome.min.css"
|
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/fontawesome.min.css"
|
||||||
integrity="sha384-BY+fdrpOd3gfeRvTSMT+VUZmA728cfF9Z2G42xpaRkUGu2i3DyzpTURDo5A6CaLK"
|
integrity="sha384-NvKbDTEnL+A8F/AA5Tc5kmMLSJHUO868P+lDtTpJIeQdGYaUIuLr4lVGOEA1OcMy"
|
||||||
|
crossorigin="anonymous">
|
||||||
|
|
||||||
|
<link rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.6.0/css/all.min.css"
|
||||||
|
integrity="sha384-h/hnnw1Bi4nbpD6kE7nYfCXzovi622sY5WBxww8ARKwpdLj5kUWjRuyiXaD1U2JT"
|
||||||
crossorigin="anonymous">
|
crossorigin="anonymous">
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
|
||||||
@ -97,7 +102,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="onlinebar" class="vstack p-2" style="display: none;">
|
<div id="onlinebar" class="vstack p-2" style="display: none;">
|
||||||
<div class="hstack gap-2"><p><b class="ds-i18n">Connected to:</b></p><p id="devname"></p></div>
|
<div class="row">
|
||||||
|
<div class="col-sm-9 hstack">
|
||||||
|
<p><b class="ds-i18n">Connected to:</b></p> <p id="devname"></p>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<p id="d-bat" style="text-align: right;"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button type="button" class="btn btn-outline-secondary ds-i18n" onclick="disconnect()">Disconnect</button><br>
|
<button type="button" class="btn btn-outline-secondary ds-i18n" onclick="disconnect()">Disconnect</button><br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -508,7 +520,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<footer>
|
<footer>
|
||||||
<div class="d-flex flex-column flex-sm-row justify-content-between py-4 my-4 border-top" id="footbody">
|
<div class="d-flex flex-column flex-sm-row justify-content-between py-4 my-4 border-top" id="footbody">
|
||||||
<p><span class="ds-i18n">Version</span> 1.3 (2024-06-21) - <a href="#" class="ds-i18n" onclick="show_donate_modal();">Support this project</a> <span id="authorMsg"></span></p>
|
<p><span class="ds-i18n">Version</span> 1.4 (2024-08-14) - <a href="#" class="ds-i18n" onclick="show_donate_modal();">Support this project</a> <span id="authorMsg"></span></p>
|
||||||
|
|
||||||
<ul class="list-unstyled d-flex">
|
<ul class="list-unstyled d-flex">
|
||||||
<li class="ms-3"><a class="link-body-emphasis" href="mailto:ds4@the.al" target="_blank"><svg class="bi" width="24" height="24"><use xlink:href="#mail"/></svg></a></li>
|
<li class="ms-3"><a class="link-body-emphasis" href="mailto:ds4@the.al" target="_blank"><svg class="bi" width="24" height="24"><use xlink:href="#mail"/></svg></a></li>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user