mirror of
https://github.com/scottbez1/smartknob.git
synced 2025-09-26 23:09:27 +08:00
made SmartKnob JS class
This commit is contained in:
parent
44f6f13fe2
commit
ff3e411860
@ -1,68 +0,0 @@
|
||||
|
||||
function getRandomInt(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
}
|
||||
|
||||
function bufferToString(data) {
|
||||
if (!("TextDecoder" in window))
|
||||
alert("Sorry, this browser does not support TextDecoder...");
|
||||
var enc = new TextDecoder("utf-8");
|
||||
var arr = new Uint8Array(data.buffer);
|
||||
return enc.decode(arr);
|
||||
}
|
||||
|
||||
function stringToBuffer(str) {
|
||||
'use strict'
|
||||
let Len = str.length,
|
||||
resPos = -1
|
||||
// The Uint8Array's length must be at least 3x the length of the string because an invalid UTF-16
|
||||
// takes up the equivalent space of 3 UTF-8 characters to encode it properly.
|
||||
let resArr = new Uint8Array(Len * 3)
|
||||
for (let point = 0, nextcode = 0, i = 0; i !== Len; ) {
|
||||
point = str.charCodeAt(i)
|
||||
i += 1
|
||||
if (point >= 0xd800 && point <= 0xdbff) {
|
||||
if (i === Len) {
|
||||
resArr[(resPos += 1)] = 0xef /*0b11101111*/
|
||||
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
|
||||
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
|
||||
break
|
||||
}
|
||||
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
nextcode = str.charCodeAt(i)
|
||||
if (nextcode >= 0xdc00 && nextcode <= 0xdfff) {
|
||||
point = (point - 0xd800) * 0x400 + nextcode - 0xdc00 + 0x10000
|
||||
i += 1
|
||||
if (point > 0xffff) {
|
||||
resArr[(resPos += 1)] = (0x1e /*0b11110*/ << 3) | (point >>> 18)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 12) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
resArr[(resPos += 1)] = 0xef /*0b11101111*/
|
||||
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
|
||||
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (point <= 0x007f) {
|
||||
resArr[(resPos += 1)] = (0x0 /*0b0*/ << 7) | point
|
||||
} else if (point <= 0x07ff) {
|
||||
resArr[(resPos += 1)] = (0x6 /*0b110*/ << 5) | (point >>> 6)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
} else {
|
||||
resArr[(resPos += 1)] = (0xe /*0b1110*/ << 4) | (point >>> 12)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
}
|
||||
}
|
||||
return resArr.subarray(0, resPos + 1)
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>SmartKnow web BT interface</title>
|
||||
<script src="jquery.js"></script>
|
||||
<script src="helpers.js"></script>
|
||||
<script src="smartknob.js"></script>
|
||||
|
||||
<link href="style.css" rel="stylesheet" >
|
||||
</head>
|
||||
@ -19,23 +19,69 @@
|
||||
|
||||
<div class="action_btns disabled">
|
||||
<!-- <button id="power">Power</button><br> -->
|
||||
<button data-door="1" class="pwroff">Door 1</button><br>
|
||||
<button data-door="2" class="pwroff">Door 2</button><br>
|
||||
<button data-door="3" class="pwroff">Door 3</button><br>
|
||||
<button data-door="4" class="pwroff">Door 4</button><br>
|
||||
<button data-door="5" class="pwroff">Door 5</button><br>
|
||||
<button data-door="6" class="pwroff">Door 6</button><br>
|
||||
<div class="profilegroup">
|
||||
<button id="setactive" class="statebtns" data-cmd="STA">Active</button>
|
||||
<button id="setmobile" class="statebtns" data-cmd="STM">Mobile</button>
|
||||
<button id="setlocked" class="statebtns" data-cmd="STL">Locked</button>
|
||||
<label for="position_cur" class="pwroff">Position:</label>
|
||||
<input style="text-align: right;" name="position_cur" value="0" type="text" disabled>
|
||||
<span style="text-align: center; width: 10px;" >/</span>
|
||||
<input name="position" value="0" type="text" disabled>
|
||||
</div>
|
||||
<button id="wificonfig" >WiFi Config</button><br>
|
||||
<div class="wificonfig_dialog">
|
||||
<span id="wifi_message">Enter WiFi credentials</span>
|
||||
SSID: <input name="ssid" type="text"><br>
|
||||
PASS: <input name="wifipass" type="text"><br>
|
||||
<button id="wificonfig_send">Save and connect</button>
|
||||
<div class="profilegroup">
|
||||
<label for="light" class="pwroff">Light:</label>
|
||||
<input style="text-align: right;" name="light" value="0" type="text" disabled>
|
||||
<span>millilux</span>
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="strain" class="pwroff">Strain:</label>
|
||||
<input style="width: 100%;" name="strain" value="0" type="text" disabled>
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="strain" class="pwroff">Button:</label>
|
||||
<input style="width: 100%;" name="knob_button" value="0" type="text" disabled>
|
||||
</div>
|
||||
|
||||
<div class="profilegroup">
|
||||
<label for="strain" class="pwroff">Profile:</label>
|
||||
<input style="width: 100%;" name="profile_name" value="" type="text" disabled>
|
||||
</div>
|
||||
|
||||
<div class="profilegroup">
|
||||
<button id="setactive" class="statebtns" data-cmd="STA">Red</button>
|
||||
<button id="setmobile" class="statebtns" data-cmd="STM">Green</button>
|
||||
<button id="setlocked" class="statebtns" data-cmd="STL">Blue</button>
|
||||
</div>
|
||||
<button id="profileconfig" >SmartKnob Config</button><br>
|
||||
<div class="profileconfig_dialog">
|
||||
|
||||
<div class="profilegroup">
|
||||
<label for="preset_profile">Preset profiles:</label><select name="preset_profile"></select>
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="pos_num">Num. positions:</label><input name="pos_num" value="32" type="number">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="pos_start">Start position:</label><input name="pos_start" value="0" type="number">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="pos_rad">Position with radians:</label><input name="pos_rad" value="8.2258" type="number" min="1" max="60">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="strenght_detent">Detent strenght:</label><input name="strenght_detent" value="2" type="number" min="0" max="2">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="strenght_endpoint">Endstop strenght:</label><input name="strenght_endpoint" value="1" type="number" min="0" max="1">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="snap_point">Snap point (1.1 / 0.5):</label><input name="snap_point" value="1.1" type="number" min="0.5" max="1.1">
|
||||
</div>
|
||||
<div class="profilegroup">
|
||||
<label for="new_profile_name">Profile name:</label><input name="new_profile_name" value="Coarse values / Strong detents" type="text">
|
||||
</div>
|
||||
<button id="profileconfig_send">Send</button>
|
||||
|
||||
<div class="profilegroup">
|
||||
<span id="profile_message">...</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- <button id="alarmtest" data-cmd="ARM">Alarm test</button><br> -->
|
||||
<!-- <button id="setwifi" data-cmd="SWN">Connect Wifi</button> -->
|
||||
@ -44,149 +90,139 @@
|
||||
<script>
|
||||
|
||||
$ = jQuery
|
||||
|
||||
let sk = new SmartKnob()
|
||||
|
||||
var buffer = new ArrayBuffer(4);
|
||||
var data = new Int32Array(buffer);
|
||||
|
||||
message_disconnected = "Disconnected"
|
||||
message_connecting = "Connecting"
|
||||
message_connected = "Connected"
|
||||
message_tryagain = "Try again"
|
||||
message_error = "Error"
|
||||
// message_disconnected = "Disconnected"
|
||||
// message_connecting = "Connecting"
|
||||
// message_connected = "Connected"
|
||||
// message_tryagain = "Try again"
|
||||
// message_error = "Error"
|
||||
|
||||
// Function structure
|
||||
|
||||
// Sensor Updates
|
||||
// *Ambient
|
||||
// *Gyro
|
||||
|
||||
// Events
|
||||
// *Button
|
||||
// *Push
|
||||
// *Encoder
|
||||
|
||||
// Config
|
||||
// *Lights
|
||||
// *Motor/Haptic
|
||||
|
||||
// Trigger
|
||||
// *Haptic
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// https://gist.github.com/sam016/4abe921b5a9ee27f67b3686910293026#file-allgattcharacteristics-java
|
||||
// /////////////////////////////////////////////////
|
||||
// // https://gist.github.com/sam016/4abe921b5a9ee27f67b3686910293026#file-allgattcharacteristics-java
|
||||
|
||||
var serviceUuid = 0x340f
|
||||
var characteristicUuid = "000042ff-0000-1000-8000-00805f9b34fb" //0x42ff
|
||||
// var serviceUuid = 0x340f
|
||||
// var characteristicUuid = "000042ff-0000-1000-8000-00805f9b34fb" //0x42ff
|
||||
|
||||
var serviceCharacteristic;
|
||||
// var serviceCharacteristic;
|
||||
|
||||
navigator.bluetooth.addEventListener("availabilitychanged", onavailabilitychanged)
|
||||
// navigator.bluetooth.addEventListener("availabilitychanged", onavailabilitychanged)
|
||||
|
||||
async function onStartButtonClick() {
|
||||
|
||||
try {
|
||||
isDisconnected(message_connecting, "processing")
|
||||
console.log('Requesting Bluetooth Device...');
|
||||
const device = await navigator.bluetooth.requestDevice({
|
||||
filters: [{"namePrefix": "SmartKnob_"}], // <- Prefer filters to save energy & show relevant devices
|
||||
optionalServices: [serviceUuid] // <- Required because "secuuurity"
|
||||
});
|
||||
|
||||
console.log('Connecting to GATT Server...');
|
||||
const server = await device.gatt.connect();
|
||||
|
||||
console.log('Getting Service...');
|
||||
const service = await server.getPrimaryService(serviceUuid);
|
||||
|
||||
console.log('Getting Characteristic...');
|
||||
let serviceCharacteristics = await service.getCharacteristics()
|
||||
console.log(serviceCharacteristics)
|
||||
serviceCharacteristic = await service.getCharacteristic(serviceCharacteristics[0].uuid);
|
||||
|
||||
await serviceCharacteristic.startNotifications();
|
||||
console.log('> Notifications started');
|
||||
serviceCharacteristic.addEventListener('characteristicvaluechanged', handleNotifications);
|
||||
|
||||
// console.log('Getting Service 2...');
|
||||
// const service2 = await server.getPrimaryService(serviceUuid2);
|
||||
|
||||
// console.log('Getting Characteristic 2...');
|
||||
// powerCharacteristic = await service2.getCharacteristic(powerCharacteristicUuid);
|
||||
|
||||
// await powerCharacteristic.startNotifications();
|
||||
// console.log('> Notifications started');
|
||||
// powerCharacteristic.addEventListener('characteristicvaluechanged', handlePwrNotifications);
|
||||
|
||||
isConnected()
|
||||
|
||||
// document.querySelector('#writeButton').disabled = false;
|
||||
// console.log('Reading Alert Level...');
|
||||
// const value = await serviceCharacteristic.readValue();
|
||||
|
||||
// console.log('> Alert Level: ' + getAlertLevel(value));
|
||||
|
||||
} catch(error) {
|
||||
// document.querySelector('#writeButton').disabled = true;
|
||||
// NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
console.log('! BT Connection error' + error);
|
||||
isDisconnected(message_tryagain, "error")
|
||||
}
|
||||
}
|
||||
|
||||
function onStopButtonClick(){
|
||||
if(serviceCharacteristic){
|
||||
serviceCharacteristic.stopNotifications()
|
||||
.then(_ => {
|
||||
console.log('> Notifications stopped');
|
||||
serviceCharacteristic.removeEventListener('characteristicvaluechanged', handleNotifications);
|
||||
})
|
||||
.catch(error => {
|
||||
if(error == "NotFoundError: User cancelled the requestDevice() chooser."){
|
||||
isDisconnected(message_tryagain)
|
||||
}
|
||||
//NetworkError: GATT operation already in progress.
|
||||
//NotSupportedError: GATT operation failed for unknown reason.
|
||||
//NetworkError: Failed to execute 'writeValue' on 'BluetoothRemoteGATTCharacteristic': GATT Server is disconnected. Cannot perform GATT operations. (Re)connect first with `device.gatt.connect`.
|
||||
//NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
else{
|
||||
console.log('! BT error: ' + error);
|
||||
isDisconnected(message_error, "error")
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onavailabilitychanged(event){
|
||||
console.log("Availabiliy changed: "+event.value)
|
||||
}
|
||||
|
||||
|
||||
function handleNotifications(event) {
|
||||
|
||||
let buffer = event.target.value;
|
||||
|
||||
let a = [];
|
||||
// Convert raw data bytes to hex values just for the sake of showing something.
|
||||
// In the "real" world, you'd use data.getUint8, data.getUint16 or even
|
||||
// TextDecoder to process raw data bytes.
|
||||
for (let i = 0; i < buffer.byteLength; i++) {
|
||||
a.push('0x' + ('00' + buffer.getUint8(i).toString(16)).slice(-2));
|
||||
}
|
||||
console.log('>> ' + a.join(' '));
|
||||
//console.log('RAW ', event.target.value);
|
||||
|
||||
//let data = bufferToString(value)
|
||||
// let data = new DataView(buffer, 0)
|
||||
//let data = new Uint8Array(buffer)
|
||||
let value = buffer.getUint8(0)+(buffer.getUint8(1)*256)+(buffer.getUint8(2)*256)+(buffer.getUint8(3)*256)
|
||||
if(buffer.getUint8(2) > 0){
|
||||
value = (value-196096)
|
||||
}
|
||||
console.log(value);
|
||||
//processNotificationState(data)
|
||||
|
||||
sk.connect()
|
||||
|
||||
// try {
|
||||
// isDisconnected(message_connecting, "processing")
|
||||
// console.log('Requesting Bluetooth Device...');
|
||||
// const device = await navigator.bluetooth.requestDevice({
|
||||
// filters: [{"namePrefix": "SmartKnob_"}], // <- Prefer filters to save energy & show relevant devices
|
||||
// optionalServices: [serviceUuid] // <- Required because "secuuurity"
|
||||
// });
|
||||
|
||||
// console.log('Connecting to GATT Server...');
|
||||
// const server = await device.gatt.connect();
|
||||
|
||||
// console.log('Getting Service...');
|
||||
// const service = await server.getPrimaryService(serviceUuid);
|
||||
|
||||
// console.log('Getting Characteristic...');
|
||||
// let serviceCharacteristics = await service.getCharacteristics()
|
||||
// console.log(serviceCharacteristics)
|
||||
// serviceCharacteristic = await service.getCharacteristic(serviceCharacteristics[0].uuid);
|
||||
|
||||
// await serviceCharacteristic.startNotifications();
|
||||
// console.log('> Notifications started');
|
||||
// serviceCharacteristic.addEventListener('characteristicvaluechanged', handleNotifications);
|
||||
|
||||
// // console.log('Getting Service 2...');
|
||||
// // const service2 = await server.getPrimaryService(serviceUuid2);
|
||||
|
||||
// // console.log('Getting Characteristic 2...');
|
||||
// // powerCharacteristic = await service2.getCharacteristic(powerCharacteristicUuid);
|
||||
|
||||
// // await powerCharacteristic.startNotifications();
|
||||
// // console.log('> Notifications started');
|
||||
// // powerCharacteristic.addEventListener('characteristicvaluechanged', handlePwrNotifications);
|
||||
|
||||
// isConnected()
|
||||
|
||||
// // document.querySelector('#writeButton').disabled = false;
|
||||
// // console.log('Reading Alert Level...');
|
||||
// // const value = await serviceCharacteristic.readValue();
|
||||
|
||||
// // console.log('> Alert Level: ' + getAlertLevel(value));
|
||||
|
||||
// } catch(error) {
|
||||
// // document.querySelector('#writeButton').disabled = true;
|
||||
// // NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
// console.log('! BT Connection error' + error);
|
||||
// isDisconnected(message_tryagain, "error")
|
||||
// }
|
||||
}
|
||||
|
||||
// function onStopButtonClick(){
|
||||
// if(serviceCharacteristic){
|
||||
// serviceCharacteristic.stopNotifications()
|
||||
// .then(_ => {
|
||||
// console.log('> Notifications stopped');
|
||||
// serviceCharacteristic.removeEventListener('characteristicvaluechanged', handleNotifications);
|
||||
// })
|
||||
// .catch(error => {
|
||||
// if(error == "NotFoundError: User cancelled the requestDevice() chooser."){
|
||||
// isDisconnected(message_tryagain)
|
||||
// }
|
||||
// //NetworkError: GATT operation already in progress.
|
||||
// //NotSupportedError: GATT operation failed for unknown reason.
|
||||
// //NetworkError: Failed to execute 'writeValue' on 'BluetoothRemoteGATTCharacteristic': GATT Server is disconnected. Cannot perform GATT operations. (Re)connect first with `device.gatt.connect`.
|
||||
// //NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
// else{
|
||||
// console.log('! BT error: ' + error);
|
||||
// isDisconnected(message_error, "error")
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// function onavailabilitychanged(event){
|
||||
// this.log("Availabiliy changed: "+event.value)
|
||||
// }
|
||||
|
||||
|
||||
// function handleNotifications(event) {
|
||||
|
||||
// let buffer = event.target.value;
|
||||
|
||||
// // Display raw hex
|
||||
// // let a = [];
|
||||
// // for (let i = 0; i < buffer.byteLength; i++) {
|
||||
// // a.push('0x' + ('00' + buffer.getUint8(i).toString(16)).slice(-2));
|
||||
// // }
|
||||
// // console.log('>> ' + a.join(' '));
|
||||
|
||||
// //let data = bufferToString(value)
|
||||
// // let data = new DataView(buffer, 0)
|
||||
// //let data = new Uint8Array(buffer)
|
||||
// let value = buffer.getUint8(0)+(buffer.getUint8(1)*256)+(buffer.getUint8(2)*256)+(buffer.getUint8(3)*256)
|
||||
// if(buffer.getUint8(2) > 0){
|
||||
// value = (value-196096)
|
||||
// }
|
||||
// $('[name="position_cur"]').val(value)
|
||||
// //console.log(value);
|
||||
// //processNotificationState(data)
|
||||
|
||||
// }
|
||||
|
||||
|
||||
sk.addListener('handleNotifications', (e)=>{
|
||||
$('[name="position_cur"]').val(e.detail.value)
|
||||
})
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// PROCESSOR
|
||||
@ -238,7 +274,107 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
let PI = Math.PI;
|
||||
|
||||
|
||||
let preset_profiles = [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
10 * PI / 180,
|
||||
0,
|
||||
1,
|
||||
1.1,
|
||||
"Unbounded\nNo detents",
|
||||
],
|
||||
[
|
||||
11,
|
||||
0,
|
||||
10 * PI / 180,
|
||||
0,
|
||||
1,
|
||||
1.1,
|
||||
"Bounded 0-10\nNo detents",
|
||||
],
|
||||
[
|
||||
73,
|
||||
0,
|
||||
10 * PI / 180,
|
||||
0,
|
||||
1,
|
||||
1.1,
|
||||
"Multi-rev\nNo detents",
|
||||
],
|
||||
[
|
||||
2,
|
||||
0,
|
||||
60 * PI / 180,
|
||||
1,
|
||||
1,
|
||||
0.55, // Note the snap point is slightly past the midpoint (0.5); compare to normal detents which use a snap point *past* the next value (i.e. > 1)
|
||||
"On/off\nStrong detent",
|
||||
],
|
||||
[
|
||||
1,
|
||||
0,
|
||||
60 * PI / 180,
|
||||
0.01,
|
||||
0.6,
|
||||
1.1,
|
||||
"Return-to-center",
|
||||
],
|
||||
[
|
||||
256,
|
||||
127,
|
||||
1 * PI / 180,
|
||||
0,
|
||||
1,
|
||||
1.1,
|
||||
"Fine values\nNo detents",
|
||||
],
|
||||
[
|
||||
256,
|
||||
127,
|
||||
1 * PI / 180,
|
||||
1,
|
||||
1,
|
||||
1.1,
|
||||
"Fine values\nWith detents",
|
||||
],
|
||||
[
|
||||
32,
|
||||
0,
|
||||
8.225806452,
|
||||
2,
|
||||
1,
|
||||
1.1,
|
||||
"Coarse values\nStrong detents",
|
||||
],
|
||||
[
|
||||
32,
|
||||
0,
|
||||
8.225806452 * PI / 180,
|
||||
0.2,
|
||||
1,
|
||||
1.1,
|
||||
"Coarse values\nWeak detents",
|
||||
]
|
||||
]
|
||||
|
||||
preset_profiles.forEach(function(valuearr, i){
|
||||
$('<option value="'+i+'">'+valuearr[6].replace("\n", " / ")+'</option>').appendTo('[name="preset_profile"]')
|
||||
})
|
||||
$('[name="preset_profile"]').on('change', (e)=>{
|
||||
console.log(preset_profiles[e.target.value])
|
||||
let v = preset_profiles[e.target.value]
|
||||
$('[name="pos_num"]').val(v[0])
|
||||
$('[name="pos_start"]').val(v[1])
|
||||
$('[name="pos_rad"]').val(v[2]/PI*180)
|
||||
$('[name="strenght_detent"]').val(v[3])
|
||||
$('[name="strenght_endpoint"]').val(v[4])
|
||||
$('[name="snap_point"]').val(v[5])
|
||||
$('[name="new_profile_name"]').val(v[6].replace("\n", " / "))
|
||||
})
|
||||
|
||||
$('#request').on('click', async event => {
|
||||
try {
|
||||
@ -266,8 +402,6 @@
|
||||
|
||||
// await bt.readDoor();
|
||||
|
||||
// data[0] = getRandomInt(1023);
|
||||
// await bt.writeDoor(data);
|
||||
|
||||
//console.log("Done")
|
||||
|
||||
@ -287,81 +421,29 @@
|
||||
console.log(" Done")
|
||||
}
|
||||
|
||||
$('#debug').on('click', async event => {
|
||||
$('#log, .action_btns button').toggleClass("debug")
|
||||
$('#debug').toggleClass("success")
|
||||
})
|
||||
|
||||
$('#power').on('click', async event => {
|
||||
|
||||
elem = $(event.target)
|
||||
setto = elem.hasClass('pwron') ? "OFF" : "ON"
|
||||
elem.addClass('processing')
|
||||
|
||||
let value = stringToBuffer("PWR|"+setto)
|
||||
try{
|
||||
console.log('Setting power to '+setto+'...');
|
||||
await serviceCharacteristic.writeValue(value);
|
||||
|
||||
elem.removeClass('processing')
|
||||
console.log('> Power set to '+setto);
|
||||
// $('#power').toggleClass("pwron")
|
||||
// let value = stringToBuffer("OD|"+number)
|
||||
// await serviceCharacteristic.writeValue(value);
|
||||
}
|
||||
catch(error){
|
||||
console.log('> PWR BT error: '+error);
|
||||
}
|
||||
});
|
||||
|
||||
$('#alarmtest').on('click', async event => {
|
||||
cmd = event.target.dataset.cmd
|
||||
elem = $(event.target)
|
||||
elem.addClass('processing')
|
||||
|
||||
let value = stringToBuffer("CMD|"+cmd)
|
||||
try{
|
||||
console.log('Sending command: '+cmd+'...');
|
||||
await serviceCharacteristic.writeValue(value);
|
||||
|
||||
elem.removeClass('processing')
|
||||
console.log('> Command sent: '+cmd);
|
||||
}
|
||||
catch(error){
|
||||
console.log('> Command BT error: '+error);
|
||||
isDisconnected(message_tryagain, "error")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$('#wificonfig').on('click', async event => {
|
||||
$('#profileconfig').on('click', async event => {
|
||||
// OPEN CONFIG WINDOW
|
||||
// $('#wifi_message').html("Wifi is connected!")
|
||||
$('.wificonfig_dialog').toggleClass("open")
|
||||
$('.profileconfig_dialog').toggleClass("open")
|
||||
})
|
||||
|
||||
// $('#wificonfig_close').on('click', async event => {
|
||||
// // OPEN CONFIG WINDOW
|
||||
// // $('#wifi_message').html("Wifi is connected!")
|
||||
// $('.wificonfig_dialog').removeClass("open")
|
||||
// })
|
||||
|
||||
|
||||
$('#wificonfig_send').on('click', async event => {
|
||||
let msg = $('#wifi_message')
|
||||
$('#profileconfig_send').on('click', async event => {
|
||||
let msg = $('#profile_message')
|
||||
|
||||
cmd = "SWN|"+$('[name="ssid"]').val()+"|"+$('[name="wifipass"]').val()
|
||||
elem = $(event.target)
|
||||
elem.addClass('processing')
|
||||
|
||||
msg.html("Sending WiFi credentials to Toolbox")
|
||||
msg.html("Sending config to SmartKnob")
|
||||
|
||||
let value = stringToBuffer("CMD|"+cmd)
|
||||
try{
|
||||
console.log('Sending command: '+cmd+'...');
|
||||
await serviceCharacteristic.writeValue(value);
|
||||
|
||||
msg.html("Sending done, trying to connect")
|
||||
msg.html("Sending done, waiting back")
|
||||
elem.removeClass('processing')
|
||||
console.log('> Command sent: '+cmd);
|
||||
}
|
||||
@ -372,26 +454,6 @@
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$('#setactive, #setmobile, #setlocked').on('click', async event => {
|
||||
cmd = event.target.dataset.cmd
|
||||
elem = $(event.target)
|
||||
elem.addClass('processing')
|
||||
|
||||
let value = stringToBuffer("CMD|"+cmd)
|
||||
try{
|
||||
console.log('Sending command: '+cmd+'...');
|
||||
await serviceCharacteristic.writeValue(value);
|
||||
|
||||
// elem.removeClass('processing')
|
||||
console.log('> Command sent: '+cmd);
|
||||
}
|
||||
catch(error){
|
||||
console.log('> Command BT error: '+error);
|
||||
isDisconnected(message_tryagain, "error")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
$('#setwifi').on('click', async event => {
|
||||
cmd = event.target.dataset.cmd
|
||||
@ -412,60 +474,24 @@
|
||||
}
|
||||
})
|
||||
|
||||
$('[data-door]').on('click', async event => {
|
||||
|
||||
elem = event.target
|
||||
number = elem.dataset.door
|
||||
|
||||
if(!serviceCharacteristic) return;
|
||||
|
||||
let value = stringToBuffer("OD|"+number)
|
||||
try{
|
||||
console.log('Opening door '+number+'...');
|
||||
await serviceCharacteristic.writeValue(value);
|
||||
|
||||
console.log('> Opened door '+number);
|
||||
}
|
||||
catch(error){
|
||||
console.log('> Door BT error: '+error);
|
||||
}
|
||||
|
||||
// try {
|
||||
// elem = event.target
|
||||
// number = elem.dataset.door
|
||||
// console.log("Opendoor "+number)
|
||||
// doorBtn(elem, "processing")
|
||||
// // await toolBoxBT.request();
|
||||
// if(!bt.connected)
|
||||
// await bt.connect();
|
||||
|
||||
// await bt.writeDoor(stringToBuffer("OD|"+number));
|
||||
// doorBtn(elem, "open")
|
||||
// console.log(" Done")
|
||||
|
||||
// } catch(error) {
|
||||
// processError(error)
|
||||
// console.log(error);
|
||||
// }
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
/// GUI MAGIX 4 MEATBAGS
|
||||
|
||||
var isDisconnected = function(message=message_disconnected, style=""){
|
||||
connectBtn(message, style)
|
||||
|
||||
sk.addListener('isConnected', (e)=>{
|
||||
connectBtn(e.detail.message, e.detail.type)
|
||||
$('.action_btns').removeClass('disabled')
|
||||
})
|
||||
|
||||
sk.addListener('isDisconnected', (e)=>{
|
||||
connectBtn(e.detail.message, e.detail.type)
|
||||
$('[data-door]').removeClass("open error processing")
|
||||
$('.action_btns').addClass('disabled')
|
||||
$('.action_btns button').removeClass("open error processing closed")
|
||||
$('.action_btns [data-door]').addClass('pwroff')
|
||||
}
|
||||
|
||||
var isConnected = function(){
|
||||
connectBtn(message_connected, "success")
|
||||
$('.action_btns').removeClass('disabled')
|
||||
$('.action_btns [data-door]').removeClass('pwroff')
|
||||
}
|
||||
})
|
||||
|
||||
var connectBtn = function(message, style=""){
|
||||
var elem = $("#request")
|
||||
@ -475,37 +501,7 @@
|
||||
}
|
||||
elem.html(message)
|
||||
}
|
||||
|
||||
var setWifiState = function(message, css){
|
||||
console.log("Set wifi state "+message)
|
||||
$('#wifi_message').html(message)
|
||||
$('#wifistate').html("Wifi ["+message+"]").removeClass("gray, yellow, red, green").addClass(css)
|
||||
}
|
||||
|
||||
var setPwrState = function(state){
|
||||
console.log("Set pwr state "+state)
|
||||
if(state){
|
||||
$('.action_btns').removeClass("disabled")
|
||||
}
|
||||
else{
|
||||
$('.action_btns').addClass("disabled")
|
||||
}
|
||||
}
|
||||
|
||||
var doorBtn = function(elem, style=""){
|
||||
elem = $(elem)
|
||||
elem.removeClass("open error processing closed")
|
||||
if(style !== ""){
|
||||
elem.addClass(style);
|
||||
}
|
||||
}
|
||||
|
||||
var doorNotification = function(event){
|
||||
console.log("notification", event)
|
||||
let data = bufferToString(event.target.value)
|
||||
processNotificationState(data)
|
||||
}
|
||||
|
||||
var processError = function(error){
|
||||
switch(error){
|
||||
case "Device is not connected.":
|
||||
@ -537,9 +533,8 @@
|
||||
},1000)
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
287
browser_sdk/smartknob.js
Normal file
287
browser_sdk/smartknob.js
Normal file
@ -0,0 +1,287 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
// SmartKnob I/O:
|
||||
|
||||
// Sensor reads
|
||||
// *Ambient
|
||||
// *Gyro (firmare not implemented)
|
||||
// *Push
|
||||
// *Proximity (firmare not implemented)
|
||||
|
||||
// Interaciton event triggers
|
||||
// *Button change
|
||||
// *Position change
|
||||
|
||||
// Set config / calls
|
||||
// *Motor/Haptic
|
||||
// *Motor calibration
|
||||
// *Push
|
||||
// *Lights (firmare not implemented)
|
||||
|
||||
// Hardware manipulation
|
||||
// *Haptic
|
||||
// *Speaker (firmare not implemented)
|
||||
|
||||
// Value event triggers (set up a event to be called at certain level)
|
||||
// *Ambient (firmare not implemented)
|
||||
// *Proximity (firmare not implemented)
|
||||
|
||||
const SmartKnob = class {
|
||||
|
||||
debug = true
|
||||
|
||||
ble_nameprefix = "SmartKnob_"
|
||||
|
||||
ble_connected = false
|
||||
|
||||
debug_messages = {
|
||||
'disconnected': "Disconnected",
|
||||
'connecting': "Connecting",
|
||||
'connected': "Connected",
|
||||
'tryagain': "Try again",
|
||||
'error': "Error"
|
||||
}
|
||||
|
||||
// isConnected = new CustomEvent('isConnected', {detail: {'message': this.debug_messages.connected, 'type': "success"}})
|
||||
// isDisconnected = new CustomEvent('isDisconnected', {})
|
||||
|
||||
serviceUuid = 0x340f // Primary service
|
||||
|
||||
characteristicUuids = {
|
||||
'ambient': {
|
||||
'uuid': "0000420f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'write', 'notify', 'indicate']
|
||||
},
|
||||
'push': {
|
||||
'uuid': "0000421f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'notify', 'indicate']
|
||||
},
|
||||
'button': {
|
||||
'uuid': "0000422f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'notify', 'indicate']
|
||||
},
|
||||
'position': {
|
||||
'uuid': "0000423f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'write', 'notify', 'indicate']
|
||||
},
|
||||
'lights': {
|
||||
'uuid': "0000424f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'notify', 'indicate']
|
||||
},
|
||||
'haptic': {
|
||||
'uuid': "0000425f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['write']
|
||||
},
|
||||
'config': {
|
||||
'uuid': "0000426f-0000-1000-8000-00805f9b34fb",
|
||||
'functions': ['read', 'write', 'notify', 'indicate']
|
||||
},
|
||||
}
|
||||
|
||||
constructor() {
|
||||
window.addEventListener('onunload', this.disconnect())
|
||||
}
|
||||
|
||||
async connect(){
|
||||
|
||||
this.serviceCharacteristic;
|
||||
navigator.bluetooth.addEventListener("availabilitychanged", this.onavailabilitychanged)
|
||||
|
||||
try {
|
||||
|
||||
this.eventDisconnected(this.debug_messages.connecting, "processing")
|
||||
this.log('Requesting Bluetooth Device...');
|
||||
const device = await navigator.bluetooth.requestDevice({
|
||||
filters: [{"namePrefix": this.ble_nameprefix}],
|
||||
optionalServices: [this.serviceUuid]
|
||||
});
|
||||
|
||||
this.log('Connecting to GATT Server...');
|
||||
const server = await device.gatt.connect();
|
||||
|
||||
this.log('Getting Service...');
|
||||
const service = await server.getPrimaryService(this.serviceUuid);
|
||||
|
||||
this.log('Getting Characteristic...');
|
||||
let serviceCharacteristics = await service.getCharacteristics()
|
||||
this.log(serviceCharacteristics)
|
||||
let serviceCharacteristic = await service.getCharacteristic(serviceCharacteristics[0].uuid);
|
||||
|
||||
await serviceCharacteristic.startNotifications();
|
||||
this.log('> Notifications started');
|
||||
serviceCharacteristic.addEventListener('characteristicvaluechanged', this.handleNotifications);
|
||||
|
||||
this.eventConnected()
|
||||
|
||||
// log('Getting Service 2...');
|
||||
// const service2 = await server.getPrimaryService(serviceUuid2);
|
||||
|
||||
// log('Getting Characteristic 2...');
|
||||
// powerCharacteristic = await service2.getCharacteristic(powerCharacteristicUuid);
|
||||
|
||||
// await powerCharacteristic.startNotifications();
|
||||
// log('> Notifications started');
|
||||
// powerCharacteristic.addEventListener('characteristicvaluechanged', handlePwrNotifications);
|
||||
|
||||
|
||||
// document.querySelector('#writeButton').disabled = false;
|
||||
// log('Reading Alert Level...');
|
||||
// const value = await serviceCharacteristic.readValue();
|
||||
|
||||
// log('> Alert Level: ' + getAlertLevel(value));
|
||||
|
||||
} catch(error) {
|
||||
// document.querySelector('#writeButton').disabled = true;
|
||||
// NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
this.log('! BT Connection error' + error);
|
||||
this.eventDisconnected(this.debug_messages.tryagain, "error")
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(){
|
||||
if(this.serviceCharacteristic){
|
||||
|
||||
navigator.bluetooth.removeEventListener("availabilitychanged")
|
||||
|
||||
this.serviceCharacteristic.stopNotifications()
|
||||
.then(_ => {
|
||||
this.log('> Notifications stopped');
|
||||
this.serviceCharacteristic.removeEventListener('characteristicvaluechanged', handleNotifications);
|
||||
})
|
||||
.catch(error => {
|
||||
if(error == "NotFoundError: User cancelled the requestDevice() chooser."){
|
||||
this.eventDisconnected(this.debug_messages.tryagain)
|
||||
}
|
||||
//NetworkError: GATT operation already in progress.
|
||||
//NotSupportedError: GATT operation failed for unknown reason.
|
||||
//NetworkError: Failed to execute 'writeValue' on 'BluetoothRemoteGATTCharacteristic': GATT Server is disconnected. Cannot perform GATT operations. (Re)connect first with `device.gatt.connect`.
|
||||
//NetworkError: GATT Server is disconnected. Cannot retrieve services. (Re)connect first with `device.gatt.connect`.
|
||||
else{
|
||||
console.log('! BT error: ' + error);
|
||||
this.eventDisconnected(this.debug_messages.error, "error")
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleNotifications(event) {
|
||||
|
||||
let buffer = event.target.value;
|
||||
|
||||
// Display raw hex
|
||||
// let a = [];
|
||||
// for (let i = 0; i < buffer.byteLength; i++) {
|
||||
// a.push('0x' + ('00' + buffer.getUint8(i).toString(16)).slice(-2));
|
||||
// }
|
||||
// console.log('>> ' + a.join(' '));
|
||||
|
||||
// var data = new Int32Array(buffer);
|
||||
//let data = bufferToString(value)
|
||||
// let data = new DataView(buffer, 0)
|
||||
//let data = new Uint8Array(buffer)
|
||||
let value = buffer.getUint8(0)+(buffer.getUint8(1)*256)+(buffer.getUint8(2)*256)+(buffer.getUint8(3)*256)
|
||||
if(buffer.getUint8(2) > 0){
|
||||
value = (value-196096)
|
||||
}
|
||||
// $('[name="position_cur"]').val(value)
|
||||
//console.log(value);
|
||||
//processNotificationState(data)
|
||||
document.dispatchEvent(new CustomEvent('handleNotifications', {detail: {'value': value}}))
|
||||
|
||||
}
|
||||
|
||||
onavailabilitychanged(event){
|
||||
this.log("Availabiliy changed: "+event.value)
|
||||
}
|
||||
|
||||
eventConnected(){
|
||||
console.log("connected")
|
||||
this.ble_connected = true
|
||||
document.dispatchEvent(new CustomEvent('isConnected', {detail: {'message': this.debug_messages.connected, 'type': "success"}}))
|
||||
}
|
||||
eventDisconnected(msg=this.debug_messages.disconnected, cls=""){
|
||||
this.ble_connected = false
|
||||
document.dispatchEvent(new CustomEvent('isDisconnected', {detail: {'message': msg, 'type': cls}}))
|
||||
}
|
||||
|
||||
// Function to add event listener and log who is listening
|
||||
addListener(eventName, handler) {
|
||||
// Register here that there is a new listener
|
||||
// this.log(`now listening for ${eventName}`);
|
||||
document.addEventListener(eventName, handler);
|
||||
}
|
||||
// Function to add event listener and log who is listening
|
||||
removeListener(eventName, handler) {
|
||||
// Deregister here that there is a new listener
|
||||
document.removeEventListener(eventName, handler);
|
||||
// this.log(`${element} is removed from listening for ${eventName}`);
|
||||
}
|
||||
|
||||
bufferToString(data) {
|
||||
if (!("TextDecoder" in window))
|
||||
alert("Sorry, this browser does not support TextDecoder...");
|
||||
var enc = new TextDecoder("utf-8");
|
||||
var arr = new Uint8Array(data.buffer);
|
||||
return enc.decode(arr);
|
||||
}
|
||||
|
||||
stringToBuffer(str) {
|
||||
let Len = str.length,
|
||||
resPos = -1
|
||||
// The Uint8Array's length must be at least 3x the length of the string because an invalid UTF-16
|
||||
// takes up the equivalent space of 3 UTF-8 characters to encode it properly.
|
||||
let resArr = new Uint8Array(Len * 3)
|
||||
for (let point = 0, nextcode = 0, i = 0; i !== Len; ) {
|
||||
point = str.charCodeAt(i)
|
||||
i += 1
|
||||
if (point >= 0xd800 && point <= 0xdbff) {
|
||||
if (i === Len) {
|
||||
resArr[(resPos += 1)] = 0xef /*0b11101111*/
|
||||
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
|
||||
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
|
||||
break
|
||||
}
|
||||
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
nextcode = str.charCodeAt(i)
|
||||
if (nextcode >= 0xdc00 && nextcode <= 0xdfff) {
|
||||
point = (point - 0xd800) * 0x400 + nextcode - 0xdc00 + 0x10000
|
||||
i += 1
|
||||
if (point > 0xffff) {
|
||||
resArr[(resPos += 1)] = (0x1e /*0b11110*/ << 3) | (point >>> 18)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 12) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
resArr[(resPos += 1)] = 0xef /*0b11101111*/
|
||||
resArr[(resPos += 1)] = 0xbf /*0b10111111*/
|
||||
resArr[(resPos += 1)] = 0xbd /*0b10111101*/
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (point <= 0x007f) {
|
||||
resArr[(resPos += 1)] = (0x0 /*0b0*/ << 7) | point
|
||||
} else if (point <= 0x07ff) {
|
||||
resArr[(resPos += 1)] = (0x6 /*0b110*/ << 5) | (point >>> 6)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
} else {
|
||||
resArr[(resPos += 1)] = (0xe /*0b1110*/ << 4) | (point >>> 12)
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f) /*0b00111111*/
|
||||
resArr[(resPos += 1)] =
|
||||
(0x2 /*0b10*/ << 6) | (point & 0x3f) /*0b00111111*/
|
||||
}
|
||||
}
|
||||
return resArr.subarray(0, resPos + 1)
|
||||
}
|
||||
|
||||
log(){
|
||||
if(this.debug) console.log(...arguments);
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ body{
|
||||
margin-bottom: 7px;
|
||||
padding: 5px 16px;
|
||||
}
|
||||
.action_btns button{
|
||||
.action_btns button, .action_btns label, .action_btns input, .action_btns span, .action_btns select{
|
||||
font-size: 38px;
|
||||
padding: 13px;
|
||||
margin: 16px 10% 0;
|
||||
@ -23,9 +23,12 @@ body{
|
||||
border-radius: 11px;
|
||||
border: 0;
|
||||
box-shadow: 3px 3px 5px #00000070;
|
||||
background-color: #ccc;
|
||||
background-color: #abaaaa;
|
||||
transition: background-color 0.4s;
|
||||
}
|
||||
.action_btns label{
|
||||
max-width: 120px;
|
||||
}
|
||||
.action_btns button:hover{
|
||||
box-shadow: 3px 3px 5px #855200c5;
|
||||
}
|
||||
@ -80,28 +83,27 @@ body{
|
||||
width: 80%;
|
||||
margin: 0 10% 0;
|
||||
}
|
||||
.profilegroup .statebtns{
|
||||
.profilegroup .statebtns, .profilegroup>label, .profilegroup>span, .profilegroup>input, .profilegroup>select{
|
||||
margin: 16px 0;
|
||||
font-size: 0.7em;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.profilegroup .statebtns:nth-child(2){
|
||||
.profilegroup .statebtns, .profilegroup>label, .profilegroup>span, .profilegroup>input, .profilegroup>select{
|
||||
border-radius: 0;
|
||||
border-left: 1px #313131 solid;
|
||||
}
|
||||
.profilegroup .statebtns:last-child{
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
border-left: 2px #313131 solid;
|
||||
.profilegroup > *:last-child{
|
||||
border-top-right-radius: 11px;
|
||||
border-bottom-right-radius: 11px;
|
||||
}
|
||||
.profilegroup .statebtns:first-child{
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-right: 2px #313131 solid;
|
||||
.profilegroup > *:first-child{
|
||||
border-top-left-radius: 11px;
|
||||
border-bottom-left-radius: 11px;
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.wificonfig_dialog{
|
||||
color: #fff;
|
||||
.profileconfig_dialog{
|
||||
width: calc(80% - 140px);
|
||||
background-color: #383838;
|
||||
padding: 0px 50px;
|
||||
@ -114,25 +116,33 @@ body{
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
.wificonfig_dialog.open{
|
||||
|
||||
.profileconfig_dialog .profilegroup{
|
||||
font-size: 1em;
|
||||
width: 100%;
|
||||
margin: 0 0 5px 0;
|
||||
}
|
||||
.profileconfig_dialog .profilegroup input, .profileconfig_dialog .profilegroup select{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
.profileconfig_dialog .profilegroup label{
|
||||
max-width: 300px;
|
||||
margin: 0;
|
||||
}
|
||||
.profileconfig_dialog.open{
|
||||
height: auto;
|
||||
padding: 35px 50px;
|
||||
}
|
||||
.wificonfig_dialog button{
|
||||
.profileconfig_dialog button{
|
||||
width: 100%;
|
||||
margin: 18px 0 0 0;
|
||||
/* display: inline-block; */
|
||||
font-size: 0.5em;
|
||||
}
|
||||
.wificonfig_dialog input{
|
||||
font-size: 20px;
|
||||
width: 100%;
|
||||
margin: 0px 0px 10px 0;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#wifi_message{
|
||||
#profile_message{
|
||||
color: #000;
|
||||
width: 100%;
|
||||
padding: 3px 6px;
|
||||
|
Loading…
Reference in New Issue
Block a user