Compare commits
3 Commits
a623ec7b85
...
4082a155a4
| Author | SHA1 | Date |
|---|---|---|
|
|
4082a155a4 | |
|
|
f64540a8f5 | |
|
|
e6556e5eb2 |
|
|
@ -193,7 +193,10 @@ const BTH = {
|
||||||
0x01: { n: "battery", t: uint8 },
|
0x01: { n: "battery", t: uint8 },
|
||||||
0x02: { n: "temperature", t: int16, f: 0.01 },
|
0x02: { n: "temperature", t: int16, f: 0.01 },
|
||||||
0x03: { n: "humidity", t: uint16, f: 0.01 },
|
0x03: { n: "humidity", t: uint16, f: 0.01 },
|
||||||
|
0x1e: { n: "light", t: uint8 },
|
||||||
|
0x2d: { n: "window", t: uint8 },
|
||||||
0x2e: { n: "humidity", t: uint8 },
|
0x2e: { n: "humidity", t: uint8 },
|
||||||
|
0x3f: { n: "rotation", t: int16, f: 0.1 },
|
||||||
0x45: { n: "temperature", t: int16, f: 0.1 }
|
0x45: { n: "temperature", t: int16, f: 0.1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -209,24 +212,24 @@ const BTHomeDecoder = {
|
||||||
const mask = 1 << (bitsz - 1);
|
const mask = 1 << (bitsz - 1);
|
||||||
return num & mask ? num - (1 << bitsz) : num;
|
return num & mask ? num - (1 << bitsz) : num;
|
||||||
},
|
},
|
||||||
getUInt8: function (buffer) {
|
getUInt8: function (buffer, offset) {
|
||||||
return buffer.at(0);
|
return buffer.at(offset);
|
||||||
},
|
},
|
||||||
getInt8: function (buffer) {
|
getInt8: function (buffer, offset) {
|
||||||
return this.utoi(this.getUInt8(buffer), 8);
|
return this.utoi(this.getUInt8(buffer, offset), 8);
|
||||||
},
|
},
|
||||||
getUInt16LE: function (buffer) {
|
getUInt16LE: function (buffer, offset) {
|
||||||
return 0xffff & ((buffer.at(1) << 8) | buffer.at(0));
|
return 0xffff & ((buffer.at(offset + 1) << 8) | buffer.at(offset));
|
||||||
},
|
},
|
||||||
getInt16LE: function (buffer) {
|
getInt16LE: function (buffer, offset) {
|
||||||
return this.utoi(this.getUInt16LE(buffer), 16);
|
return this.utoi(this.getUInt16LE(buffer, offset), 16);
|
||||||
},
|
},
|
||||||
getBufValue: function (type, buffer) {
|
getBufValue: function (type, buffer, offset) {
|
||||||
if (buffer.length < getByteSize(type)) return null;
|
if (buffer.length - offset < getByteSize(type)) return null;
|
||||||
if (type === uint8) return this.getUInt8(buffer);
|
if (type === uint8) return this.getUInt8(buffer, offset);
|
||||||
if (type === int8) return this.getInt8(buffer);
|
if (type === int8) return this.getInt8(buffer, offset);
|
||||||
if (type === uint16) return this.getUInt16LE(buffer);
|
if (type === uint16) return this.getUInt16LE(buffer, offset);
|
||||||
if (type === int16) return this.getInt16LE(buffer);
|
if (type === int16) return this.getInt16LE(buffer, offset);
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -238,17 +241,17 @@ const BTHomeDecoder = {
|
||||||
result["BTHome_version"] = _dib >> 5;
|
result["BTHome_version"] = _dib >> 5;
|
||||||
if (result["BTHome_version"] !== 2) return null;
|
if (result["BTHome_version"] !== 2) return null;
|
||||||
if (result["encryption"]) return result;
|
if (result["encryption"]) return result;
|
||||||
buffer = buffer.slice(1);
|
|
||||||
|
|
||||||
|
let offset = 1;
|
||||||
let _bth;
|
let _bth;
|
||||||
let _value;
|
let _value;
|
||||||
while (buffer.length > 0) {
|
while (offset < buffer.length) {
|
||||||
_bth = BTH[buffer.at(0)];
|
_bth = BTH[buffer.at(offset)];
|
||||||
if (typeof _bth === "undefined") {
|
if (typeof _bth === "undefined") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer = buffer.slice(1);
|
offset++;
|
||||||
_value = this.getBufValue(_bth.t, buffer);
|
_value = this.getBufValue(_bth.t, buffer, offset);
|
||||||
|
|
||||||
if (_value === null) break;
|
if (_value === null) break;
|
||||||
if (typeof _bth.f !== "undefined") _value = _value * _bth.f;
|
if (typeof _bth.f !== "undefined") _value = _value * _bth.f;
|
||||||
|
|
@ -268,7 +271,7 @@ const BTHomeDecoder = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = buffer.slice(getByteSize(_bth.t));
|
offset += getByteSize(_bth.t);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
@ -347,10 +350,6 @@ if (typeof HTTPServer !== "undefined" && typeof HTTPServer.registerEndpoint ===
|
||||||
function addGauge(name, val, help) {
|
function addGauge(name, val, help) {
|
||||||
if ((typeof val === "number" && !isNaN(val)) || typeof val === "boolean") {
|
if ((typeof val === "number" && !isNaN(val)) || typeof val === "boolean") {
|
||||||
var numVal = (typeof val === "boolean") ? (val ? 1 : 0) : val;
|
var numVal = (typeof val === "boolean") ? (val ? 1 : 0) : val;
|
||||||
if (help) {
|
|
||||||
body += "# HELP " + name + " " + help + "\n";
|
|
||||||
}
|
|
||||||
body += "# TYPE " + name + " gauge\n";
|
|
||||||
body += name + " " + numVal + "\n";
|
body += name + " " + numVal + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,15 @@ def upload(ip, script_id, code_file):
|
||||||
with open(code_file, 'r', encoding='utf-8') as f:
|
with open(code_file, 'r', encoding='utf-8') as f:
|
||||||
code = f.read()
|
code = f.read()
|
||||||
|
|
||||||
|
import re
|
||||||
|
# Remove comments and whitespace to save Shelly RAM
|
||||||
|
# Remove multi-line comments
|
||||||
|
code = re.sub(r'/\*.*?\*/', '', code, flags=re.DOTALL)
|
||||||
|
# Remove single-line comments (ignoring http:// or https://)
|
||||||
|
code = re.sub(r'(?<!:)\/\/.*', '', code)
|
||||||
|
# Strip leading/trailing whitespace and drop empty lines
|
||||||
|
code = '\n'.join([line.strip() for line in code.split('\n') if line.strip()])
|
||||||
|
|
||||||
url = f"http://{ip}/rpc"
|
url = f"http://{ip}/rpc"
|
||||||
|
|
||||||
# Stop the script first to prevent write locks
|
# Stop the script first to prevent write locks
|
||||||
|
|
@ -49,6 +58,23 @@ def upload(ip, script_id, code_file):
|
||||||
|
|
||||||
print("Script upload complete!")
|
print("Script upload complete!")
|
||||||
|
|
||||||
|
# Start the script after upload
|
||||||
|
print(f"Starting script {script_id}...")
|
||||||
|
req = urllib.request.Request(
|
||||||
|
url,
|
||||||
|
data=json.dumps({"id": 1, "method": "Script.Start", "params": {"id": int(script_id)}}).encode('utf-8'),
|
||||||
|
headers={'Content-Type': 'application/json'}
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
with urllib.request.urlopen(req) as resp:
|
||||||
|
res = json.loads(resp.read().decode('utf-8'))
|
||||||
|
if "error" in res:
|
||||||
|
print(f"Start request returned error: {res['error']}")
|
||||||
|
else:
|
||||||
|
print("Script started successfully.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Start request failed: {e}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) < 4:
|
if len(sys.argv) < 4:
|
||||||
print("Usage: python3 upload.py <ip> <script_id> <code_file>")
|
print("Usage: python3 upload.py <ip> <script_id> <code_file>")
|
||||||
|
|
|
||||||
|
|
@ -71,5 +71,5 @@ variable "critical_humi_ref_temp" {
|
||||||
variable "critical_humi_buffer" {
|
variable "critical_humi_buffer" {
|
||||||
type = number
|
type = number
|
||||||
description = "Safety buffer [%] subtracted from the critical relative humidity threshold"
|
description = "Safety buffer [%] subtracted from the critical relative humidity threshold"
|
||||||
default = 15
|
default = 5
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue