Last active
February 18, 2024 17:06
-
-
Save 9zigen/5219085e6d06eb53bfffc3cd064e5308 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); | |
const tz = require('zigbee-herdsman-converters/converters/toZigbee'); | |
const exposes = require('zigbee-herdsman-converters/lib/exposes'); | |
const reporting = require('zigbee-herdsman-converters/lib/reporting'); | |
const extend = require('zigbee-herdsman-converters/lib/extend'); | |
const ota = require('zigbee-herdsman-converters/lib/ota'); | |
const {} = require('zigbee-herdsman-converters/lib/tuya'); | |
const utils = require('zigbee-herdsman-converters/lib/utils'); | |
const globalStore = require('zigbee-herdsman-converters/lib/store'); | |
const e = exposes.presets; | |
const ea = exposes.access; | |
const bind = async (endpoint, target, clusters) => { | |
for await (const cluster of clusters) { | |
await endpoint.bind(cluster, target); | |
} | |
}; | |
const fzLocal = { | |
ph_measurement: { | |
cluster: 'pHMeasurement', | |
type: ['attributeReport', 'readResponse'], | |
convert: (model, msg, publish, options, meta) => { | |
let response = {}; | |
if (msg.data.hasOwnProperty('measuredValue')) { | |
response.ph_measurement = parseFloat(msg.data['measuredValue']) / 100.0; | |
} | |
if (msg.data.hasOwnProperty('4112')) { | |
response.probe_raw = parseFloat(msg.data["4112"]); | |
} | |
if (msg.data.hasOwnProperty('4113')) { | |
response.probe_ntc = parseFloat(msg.data["4113"]) / 100.0; | |
} | |
return response | |
} | |
}, | |
alab_ph_sensor: { | |
cluster: 'pHMeasurement', | |
type: ['attributeReport', 'readResponse'], | |
convert: (model, msg, publish, options, meta) => { | |
let response = {}; | |
if (msg.data[0x1000]) { | |
response.scan_interval = parseFloat(msg.data[0x1000]); | |
} | |
if (msg.data[0x1001]) { | |
response.calibration_low = parseFloat(msg.data[0x1001]); | |
} | |
if (msg.data[0x1002]) { | |
response.calibration_mid = parseFloat(msg.data[0x1002]); | |
} | |
if (msg.data[0x1003]) { | |
response.calibration_high = parseFloat(msg.data[0x1003]); | |
} | |
return response; | |
}, | |
}, | |
}; | |
const tzLocal = { | |
alab_ph_calibration: { | |
key: ['scan_interval', 'calibration_low', 'calibration_mid', 'calibration_high', 'probe_raw', 'probe_ntc'], | |
convertSet: async (entity, key, value, meta) => { | |
const payloads = { | |
'scan_interval': {0x1000: {value, type: 0x21}}, | |
'calibration_low': {0x1001: {value, type: 0x21}}, | |
'calibration_mid': {0x1002: {value, type: 0x21}}, | |
'calibration_high': {0x1003: {value, type: 0x21}} | |
} | |
await entity.write('pHMeasurement', payloads[key]); | |
}, | |
convertGet: async (entity, key, meta) => { | |
const payloads = { | |
'scan_interval': 0x1000, | |
'calibration_low': 0x1001, | |
'calibration_mid': 0x1002, | |
'calibration_high': 0x1003 | |
}; | |
return await entity.read('pHMeasurement', [payloads[key]]); | |
} | |
}, | |
} | |
const definition = { | |
zigbeeModel: ['Alab-PhSensor-1.0'], | |
model: 'Alab-PhSensor-1.0', | |
vendor: 'Alab', | |
description: '[DiY Wireless PH Sensor](https://github.com/9zigen/zigbee-ph-sensor)', | |
supports: 'temperature, humidity', | |
fromZigbee: [ | |
fz.temperature, | |
fz.humidity, | |
fz.battery, | |
fzLocal.ph_measurement, | |
fzLocal.alab_ph_sensor | |
], | |
toZigbee: [tz.factory_reset, tzLocal.alab_ph_calibration], | |
meta: { | |
configureKey: 1, | |
timeout: 10000, | |
}, | |
configure: async (device, coordinatorEndpoint) => { | |
const endpoint = device.getEndpoint(10); | |
await bind(endpoint, coordinatorEndpoint, ['genPowerCfg']); | |
await bind(endpoint, coordinatorEndpoint, ['pHMeasurement']); | |
await bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement']); | |
await bind(endpoint, coordinatorEndpoint, ['msRelativeHumidity']); | |
// await reporting.bind(endpoint, coordinatorEndpoint, ['pHMeasurement', 'genPowerCfg']); | |
// await endpoint.read('genPowerCfg', ['batteryVoltage']); | |
// await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']); | |
// await reporting.batteryPercentageRemaining(endpoint); | |
// await reporting.temperature(endpoint, { min: 0, change: 0 }); | |
// await reporting.humidity(endpoint, { min: 0, change: 0 }); | |
/* pH Reporting */ | |
// const payload = [{ | |
// attribute: 'measuredValue', | |
// minimumReportInterval: 0, | |
// maximumReportInterval: 3600, | |
// reportableChange: 0 | |
// }]; | |
// await endpoint.configureReporting('pHMeasurement', payload); | |
}, | |
exposes: [ | |
e.battery(), | |
e.battery_voltage(), | |
exposes.numeric('ph_measurement', ea.STATE).withUnit('pH'), | |
exposes.numeric('probe_raw', ea.STATE).withUnit('mV').withDescription('RAW value from pH electrode'), | |
exposes.numeric('probe_ntc', ea.STATE).withUnit('°C').withDescription('Temperature measured by Probe'), | |
exposes.numeric('temperature', ea.STATE).withUnit('°C').withDescription('Temperature measured by onboard sensor'), | |
exposes.numeric('humidity', ea.STATE).withUnit('%').withDescription('Humidity measured by onboard sensor'), | |
//device options | |
exposes.numeric('scan_interval', ea.ALL).withUnit('seconds'), | |
exposes.numeric('calibration_low', ea.ALL).withUnit('pH (x100)'), | |
exposes.numeric('calibration_mid', ea.ALL).withUnit('pH (x100)'), | |
exposes.numeric('calibration_high', ea.ALL).withUnit('pH (x100)'), | |
], | |
}; | |
module.exports = definition; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment