govee-bt-client
Advanced tools
Comparing version 1.0.7 to 1.0.8
@@ -19,2 +19,8 @@ export declare const decodeH5074Values: (streamUpdate: string) => { | ||
}; | ||
export declare const decodeH5179Values: (streamUpdate: string) => { | ||
battery: number; | ||
humidity: number; | ||
tempInC: number; | ||
tempInF: number; | ||
}; | ||
export declare const decodeAny: (streamUpdate: string) => { | ||
@@ -21,0 +27,0 @@ battery: number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decodeAny = exports.decodeH5101Values = exports.decodeH5075Values = exports.decodeH5074Values = void 0; | ||
exports.decodeAny = exports.decodeH5179Values = exports.decodeH5101Values = exports.decodeH5075Values = exports.decodeH5074Values = void 0; | ||
const validation_1 = require("./validation"); | ||
@@ -52,2 +52,21 @@ exports.decodeH5074Values = (streamUpdate) => { | ||
}; | ||
exports.decodeH5179Values = (streamUpdate) => { | ||
// TODO would be great to find a way to validate | ||
const temp_lsb = streamUpdate | ||
.substring(14, 16) | ||
.concat(streamUpdate.substring(16, 18)); | ||
const hum_lsb = streamUpdate | ||
.substring(18, 20) | ||
.concat(streamUpdate.substring(16, 18)); | ||
const tempInC = twos_complement(parseInt(temp_lsb, 16)) / 100; | ||
const tempInF = (tempInC * 9) / 5 + 32; | ||
const humidity = parseInt(hum_lsb, 16) / 100; | ||
const battery = parseInt(streamUpdate.substring(20, 22), 16); | ||
return { | ||
battery, | ||
humidity, | ||
tempInC, | ||
tempInF, | ||
}; | ||
}; | ||
exports.decodeAny = (streamUpdate) => { | ||
@@ -63,2 +82,5 @@ if (validation_1.isHt5074(streamUpdate)) { | ||
} | ||
if (validation_1.isHt5179(streamUpdate)) { | ||
return exports.decodeH5179Values(streamUpdate); | ||
} | ||
throw new Error("Unsupported stream update: " + streamUpdate); | ||
@@ -65,0 +87,0 @@ }; |
@@ -42,2 +42,13 @@ "use strict"; | ||
}); | ||
it("should decode H5179 values", () => { | ||
const hex = "0188ec0001012e09740e64"; | ||
const expectedReading = { | ||
battery: 100, | ||
humidity: 37, | ||
tempInC: 24.2, | ||
tempInF: 75.56, | ||
}; | ||
const reading = decode_1.decodeH5179Values(hex); | ||
expect(reading).toMatchObject(expectedReading); | ||
}); | ||
describe("test matrix", () => { | ||
@@ -44,0 +55,0 @@ test("decode from any supported device", () => { |
@@ -24,3 +24,5 @@ "use strict"; | ||
let DEBUG = false; | ||
let currentCallback; | ||
let discoverCallback; | ||
let scanStartCallback; | ||
let scanStopCallback; | ||
noble_1.default.on("discover", async (peripheral) => { | ||
@@ -57,6 +59,18 @@ const { id, uuid, address, state, rssi, advertisement } = peripheral; | ||
}; | ||
if (currentCallback) { | ||
currentCallback(current); | ||
if (discoverCallback) { | ||
discoverCallback(current); | ||
} | ||
}); | ||
noble_1.default.on("scanStart", (callback) => { | ||
if (DEBUG) { | ||
console.log("scanStart"); | ||
} | ||
scanStartCallback = callback; | ||
}); | ||
noble_1.default.on("scanStop", (callback) => { | ||
if (DEBUG) { | ||
console.log("scanStop"); | ||
} | ||
scanStopCallback = callback; | ||
}); | ||
exports.debug = (on) => { | ||
@@ -66,3 +80,3 @@ DEBUG = on; | ||
exports.startDiscovery = async (callback) => { | ||
currentCallback = callback; | ||
discoverCallback = callback; | ||
await noble_1.default.startScanningAsync([h5075_uuid, h5101_uuid], true); | ||
@@ -72,4 +86,6 @@ }; | ||
await noble_1.default.stopScanningAsync(); | ||
currentCallback = undefined; | ||
discoverCallback = undefined; | ||
scanStartCallback = undefined; | ||
scanStopCallback = undefined; | ||
}; | ||
__exportStar(require("./goveeReading"), exports); |
@@ -5,3 +5,4 @@ import noble from "@abandonware/noble"; | ||
export declare const isHt5101: (hex: string) => boolean; | ||
export declare const isHt5179: (hex: string) => boolean; | ||
export declare const isValidPeripheral: (peripheral: noble.Peripheral) => boolean; | ||
//# sourceMappingURL=validation.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isValidPeripheral = exports.isHt5101 = exports.isHt5075 = exports.isHt5074 = void 0; | ||
exports.isValidPeripheral = exports.isHt5179 = exports.isHt5101 = exports.isHt5075 = exports.isHt5074 = void 0; | ||
const h5074_uuid_rev = "88ec"; | ||
const h5075_uuid_rev = "88ec"; | ||
const h5101_uuid_rev = "0100"; | ||
const h5179_uuid_rev = "0188"; | ||
exports.isHt5074 = (hex) => hex.includes(h5074_uuid_rev) && hex.length == 18; // Govee H5074 | ||
exports.isHt5075 = (hex) => hex.includes(h5075_uuid_rev) && hex.length == 16; // Govee H5072/H5075 | ||
exports.isHt5101 = (hex) => hex.includes(h5101_uuid_rev); // Govee H5101/H5102 | ||
exports.isHt5179 = (hex) => hex.includes(h5179_uuid_rev) && hex.length == 22; // Govee H5179 | ||
exports.isValidPeripheral = (peripheral) => { | ||
@@ -16,3 +18,3 @@ const { address, advertisement } = peripheral; | ||
const hex = advertisement.manufacturerData.toString("hex"); | ||
if (!exports.isHt5074(hex) && !exports.isHt5075(hex) && !exports.isHt5101(hex)) { | ||
if (!exports.isHt5074(hex) && !exports.isHt5075(hex) && !exports.isHt5101(hex) && !exports.isHt5179(hex)) { | ||
return false; | ||
@@ -19,0 +21,0 @@ } |
@@ -19,2 +19,3 @@ "use strict"; | ||
it("should pass as h5101", () => expect(validation_1.isHt5101("0100010103165564")).toBeTruthy()); | ||
it("should pass as h5179", () => expect(validation_1.isHt5179("0188ec0001012e09740e64")).toBeTruthy()); | ||
}); | ||
@@ -21,0 +22,0 @@ describe("validate peripheral", () => { |
@@ -36,2 +36,7 @@ "use strict"; | ||
}, | ||
{ | ||
deviceModel: "h5179", | ||
mfgData: "0188ec0001012e09740e64", | ||
address: "", | ||
}, | ||
]; |
{ | ||
"name": "govee-bt-client", | ||
"version": "1.0.7", | ||
"version": "1.0.8", | ||
"description": "Govee H5xxx Thermometer Hygrometer Bluetooth Client", | ||
@@ -26,2 +26,3 @@ "main": "dist/index.js", | ||
"H5102", | ||
"H5179", | ||
"API", | ||
@@ -28,0 +29,0 @@ "Client" |
@@ -12,2 +12,3 @@ # Govee H5xxx Bluetooth Client | ||
- H5102 | ||
- H5179 | ||
## Installation | ||
@@ -14,0 +15,0 @@ |
@@ -5,2 +5,3 @@ import { | ||
decodeH5101Values, | ||
decodeH5179Values, | ||
decodeAny, | ||
@@ -49,3 +50,13 @@ } from "./decode"; | ||
}); | ||
it("should decode H5179 values", () => { | ||
const hex = "0188ec0001012e09740e64"; | ||
const expectedReading = { | ||
battery: 100, | ||
humidity: 37, | ||
tempInC: 24.2, | ||
tempInF: 75.56, | ||
}; | ||
const reading = decodeH5179Values(hex); | ||
expect(reading).toMatchObject(expectedReading); | ||
}); | ||
describe("test matrix", () => { | ||
@@ -52,0 +63,0 @@ test("decode from any supported device", () => { |
@@ -1,2 +0,2 @@ | ||
import { isHt5074, isHt5075, isHt5101 } from "./validation"; | ||
import { isHt5074, isHt5075, isHt5101, isHt5179 } from "./validation"; | ||
@@ -60,2 +60,26 @@ export const decodeH5074Values = (streamUpdate: string) => { | ||
export const decodeH5179Values = (streamUpdate: string) => { | ||
// TODO would be great to find a way to validate | ||
const temp_lsb = streamUpdate | ||
.substring(14, 16) | ||
.concat(streamUpdate.substring(16, 18)); | ||
const hum_lsb = streamUpdate | ||
.substring(18, 20) | ||
.concat(streamUpdate.substring(16, 18)); | ||
const tempInC = twos_complement(parseInt(temp_lsb, 16)) / 100; | ||
const tempInF = (tempInC * 9) / 5 + 32; | ||
const humidity = parseInt(hum_lsb, 16) / 100; | ||
const battery = parseInt(streamUpdate.substring(20, 22), 16); | ||
return { | ||
battery, | ||
humidity, | ||
tempInC, | ||
tempInF, | ||
}; | ||
}; | ||
export const decodeAny = (streamUpdate: string) => { | ||
@@ -71,2 +95,5 @@ if (isHt5074(streamUpdate)) { | ||
} | ||
if (isHt5179(streamUpdate)) { | ||
return decodeH5179Values(streamUpdate); | ||
} | ||
@@ -73,0 +100,0 @@ throw new Error("Unsupported stream update: " + streamUpdate); |
@@ -13,3 +13,5 @@ import noble from "@abandonware/noble"; | ||
let currentCallback: undefined | ((reading: GoveeReading) => void); | ||
let discoverCallback: undefined | ((reading: GoveeReading) => void); | ||
let scanStartCallback: undefined | Function; | ||
let scanStopCallback: undefined | Function; | ||
@@ -54,7 +56,21 @@ noble.on("discover", async (peripheral) => { | ||
if (currentCallback) { | ||
currentCallback(current); | ||
if (discoverCallback) { | ||
discoverCallback(current); | ||
} | ||
}); | ||
noble.on("scanStart", (callback: Function) => { | ||
if (DEBUG) { | ||
console.log("scanStart"); | ||
} | ||
scanStartCallback = callback; | ||
}); | ||
noble.on("scanStop", (callback: Function) => { | ||
if (DEBUG) { | ||
console.log("scanStop"); | ||
} | ||
scanStopCallback = callback; | ||
}); | ||
export const debug = (on: boolean) => { | ||
@@ -67,3 +83,3 @@ DEBUG = on; | ||
) => { | ||
currentCallback = callback; | ||
discoverCallback = callback; | ||
@@ -76,5 +92,7 @@ await noble.startScanningAsync([h5075_uuid, h5101_uuid], true); | ||
currentCallback = undefined; | ||
discoverCallback = undefined; | ||
scanStartCallback = undefined; | ||
scanStopCallback = undefined; | ||
}; | ||
export * from "./goveeReading"; |
@@ -1,2 +0,8 @@ | ||
import { isHt5074, isHt5075, isHt5101, isValidPeripheral } from "./validation"; | ||
import { | ||
isHt5074, | ||
isHt5075, | ||
isHt5101, | ||
isHt5179, | ||
isValidPeripheral, | ||
} from "./validation"; | ||
import { validationMatrix } from "./validationMatrix"; | ||
@@ -19,2 +25,4 @@ | ||
expect(isHt5101("0100010103165564")).toBeTruthy()); | ||
it("should pass as h5179", () => | ||
expect(isHt5179("0188ec0001012e09740e64")).toBeTruthy()); | ||
}); | ||
@@ -21,0 +29,0 @@ |
@@ -6,2 +6,3 @@ import noble from "@abandonware/noble"; | ||
const h5101_uuid_rev = "0100"; | ||
const h5179_uuid_rev = "0188"; | ||
@@ -13,2 +14,4 @@ export const isHt5074 = (hex: string) => | ||
export const isHt5101 = (hex: string) => hex.includes(h5101_uuid_rev); // Govee H5101/H5102 | ||
export const isHt5179 = (hex: string) => | ||
hex.includes(h5179_uuid_rev) && hex.length == 22; // Govee H5179 | ||
@@ -24,3 +27,3 @@ export const isValidPeripheral = (peripheral: noble.Peripheral) => { | ||
if (!isHt5074(hex) && !isHt5075(hex) && !isHt5101(hex)) { | ||
if (!isHt5074(hex) && !isHt5075(hex) && !isHt5101(hex) && !isHt5179(hex)) { | ||
return false; | ||
@@ -27,0 +30,0 @@ } |
@@ -40,2 +40,7 @@ import { StreamReading } from "./streamReading"; | ||
}, | ||
{ | ||
deviceModel: "h5179", | ||
mfgData: "0188ec0001012e09740e64", | ||
address: "", | ||
}, | ||
]; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
43377
915
51