As an enthusiastic amateur in home automation, I’ve lately moved my home over to use a Homey Pro hub.
I wasn’t able to easily get my Qingping Air Quality monitors working with Homey, but I found a forum thread which discussed a process for doing just that. I thought I would write up the collected process of the thread and post it online for other users who might be looking to solve the same problem.
Here are the steps I’ve worked out.
Enable HomeyScript on your Homey device. Log in via a browser to the web app. In the side bar, click the Homeyscript icon (which looks like this; “</>”), then in the main window, agree click the button to install HomeyScript. This should only take a moment.
Install the Device Capabilities app on your Homey. Device capabilities allows you to create custom virtual or dummy smart devices for your home. We will use it to create a virtual air quality monitor, then populate that virtual device with data from your actual air quality monitor.
Connect your Qingping air quality monitor to the Qingping+ app on your phone. The steps may vary depending on what type of phone you have. Your air quality monitor must be connected to the Qingping+ online service because we will grab data from online.
Get a Qingping API key to access your data. You will need to go to the Qingping developer website, create an account, and get an Oauth2 API key. This will consist of two strings of random letters and numbers, known as the Key and the Secret. Note these values down as we will need to enter them into Homey later.
Add a new virtual air quality sensor device to Homey. Using the Homey web app, click the “+” button at the top right of the screen and select New Device. From the menu of device types, select Device Capabilities to create a virtual device using the Device Capabilities app. In the following menu, click the Advanced Virtual Device icon, and then the “Connect” button. You will now be presented with options of how to create the device. The easiest method is Importing a TEF. Click the button, then paste the following code into the text box, then click the Read Device button.
[tef:AVD:"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":/tef]
This will create a virtual device with all the right sensor fields for a Qingping air quality monitor. The sensors are named in French, but this can be corrected later if you wish. Click OK through the remaining dialog boxes and you should now have a virtual sensor ready to receive data.
Create HomeyScript to fetch data from Qingping+. In the Homey web app, use the sidebar to go to the HomeyScript area. At the bottom of the sidebar, click + New HomeyScript to create a new blank script. Name the script “qingping_update” or something similar. Paste the following code into the text editor.
/**
* Configuration: App Key & App Secret
* Required for API authentication.
* Credentials can be obtained from: https://developer.qingping.co/personal/permissionApply
*/
const APP_KEY = 'XXXXXXXXXXX';
const APP_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const CREDENTIALS = Buffer.from(`${APP_KEY}:${APP_SECRET}`).toString('base64');
/**
* Performs an authenticated HTTP request.
* Uses Basic Authentication for token requests and Bearer Authentication for API calls.
*/
async function fetchWithAuth(url, method = 'GET', token = '', body = null) {
const headers = token
? { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }
: { 'Authorization': 'Basic ' + CREDENTIALS, 'Content-Type': 'application/x-www-form-urlencoded' };
const options = { method, headers, ...(body ? { body: JSON.stringify(body) } : {}) };
const response = await fetch(url, options);
if (!response.ok) throw new Error(`Error: ${response.status} - ${response.statusText}`);
return response.json();
}
/**
* Retrieves sensor data and stores it as Homey tags.
*/
async function main() {
try {
console.log("š Starting data retrieval...");
console.log("š Requesting access token...");
// Access token retrieval
const params = new URLSearchParams({
grant_type: 'client_credentials',
scope: 'device_full_access'
});
const authResponse = await fetch("https://oauth.cleargrass.com/oauth2/token", {
method: 'POST',
headers: {
'Authorization': 'Basic ' + CREDENTIALS,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params,
});
if (!authResponse.ok) throw new Error(`Auth Error: ${authResponse.status} - ${authResponse.statusText}`);
const { access_token: accessToken } = await authResponse.json();
console.log("ā
Access Token received");
console.log("\nš” Retrieving devices...");
const timestamp = Date.now().toString();
const deviceResponse = await fetchWithAuth(`https://apis.cleargrass.com/v1/apis/devices?timestamp=${timestamp}`, 'GET', accessToken);
if (!deviceResponse.devices || deviceResponse.devices.length === 0) throw new Error("No device data available");
console.log(`š” Found ${deviceResponse.devices.length} devices`);
// Iterates through each device and creates Homey tags
for (const device of deviceResponse.devices) {
const { info: deviceInfo, data: deviceData } = device;
const mac = deviceInfo.mac.replace(/:/g, "").toLowerCase(); // Normalizes the MAC address
console.log(`\nš Processing device: ${deviceInfo.name} (MAC: ${deviceInfo.mac})`);
// Stores device metadata as tags with the "qp_" prefix
await Promise.all([
tag(`qp_${mac}_mac`, deviceInfo.mac),
tag(`qp_${mac}_report_interval`, deviceInfo.setting?.report_interval ?? "N/A"),
tag(`qp_${mac}_collect_interval`, deviceInfo.setting?.collect_interval ?? "N/A")
]);
console.log(`š·ļø Stored metadata for ${deviceInfo.name}`);
console.log(`š¹ Stored: qp_${mac}_mac = ${deviceInfo.mac}`);
console.log(`š¹ Stored: qp_${mac}_report_interval = ${deviceInfo.setting?.report_interval ?? "N/A"}`);
console.log(`š¹ Stored: qp_${mac}_collect_interval = ${deviceInfo.setting?.collect_interval ?? "N/A"}`);
// Stores sensor readings
await Promise.all(Object.entries(deviceData).map(async ([key, { value }]) => {
if (value !== undefined) {
const tagName = `qp_${mac}_${key}`;
console.log(`š¹ Stored: ${tagName} = ${value}`);
return tag(tagName, value);
}
}));
}
// Creates a global tag to track error status
await tag("qp_error", "No error");
console.log("ā
All device data stored successfully!");
} catch (error) {
console.error("ā Error:", error.message);
await tag("qp_error", error.message);
}
}
// Executes the script
await main();
return "Script completed";
Now edit the script, replacing the X’s with the APP_KEY and APP_SECRET you earlier got from the Qingping developer website. Keep the quotation marks, but delete all the X’s. Save the script by clicking the blue checkmark at the top of the text box, then try running the script with the Test button. The output should look something like this:
š Starting data retrieval...
š Requesting access token...
ā
Access Token received
š” Retrieving devices...
š” Found 2 devices
š Processing device: Qingping Air Monitor (MAC: XXXXXXXX)
This will be followed by sensor readouts from your device, including the usual temperature, humidity, CO2 values, etc.. If you don’t see all the sensor values listed, or the start of your script output doesn’t look like the above, something has gone wrong.
Changing the update frequency of data from the air quality sensor. This step is optional but recommended if you want your air quality data refreshed more than four times per hour. A special script is needed to instruct your Qingping device to upload data more frequently. Create a new HomeyScript as was done in the last step, naming it qingping_update_speed. Paste the following script into the empty text editor:
/**
* Configuration: App Key & App Secret
* Required for API authentication.
* Credentials can be obtained from: https://developer.qingping.co/personal/permissionApply
*/
const APP_KEY = 'XXXXXXXXXXX';
const APP_SECRET = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
const CREDENTIALS = Buffer.from(`${APP_KEY}:${APP_SECRET}`).toString('base64');
/**
* Device settings configuration.
* These values define the report and collection intervals in seconds.
*/
const REPORT_INTERVAL = 60; // Interval for reporting sensor data
const COLLECT_INTERVAL = 60; // Interval for collecting sensor data
/**
* Performs an authenticated HTTP request.
* Uses Basic Authentication for token requests and Bearer Authentication for API calls.
*/
async function fetchWithAuth(url, method = 'GET', token = '', body = null) {
const headers = token
? { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }
: { 'Authorization': 'Basic ' + CREDENTIALS, 'Content-Type': 'application/x-www-form-urlencoded' };
const options = {
method,
headers,
...(body ? { body: JSON.stringify(body) } : {})
};
const response = await fetch(url, options);
const responseText = await response.text();
if (!response.ok) {
throw new Error(`Error: ${response.status} - ${responseText}`);
}
return responseText ? JSON.parse(responseText) : {};
}
/**
* Updates the settings of multiple devices.
* Applies the configured report and collect intervals to all specified devices.
*/
async function updateDeviceSettings(accessToken, macAddresses) {
try {
if (macAddresses.length === 0) {
console.log("ā ļø No devices found to update.");
return;
}
const timestamp = Date.now();
const requestBody = {
mac: macAddresses,
report_interval: REPORT_INTERVAL,
collect_interval: COLLECT_INTERVAL,
timestamp: timestamp
};
console.log("\nāļø Updating device settings...");
const response = await fetchWithAuth("https://apis.cleargrass.com/v1/apis/devices/settings", 'PUT', accessToken, requestBody);
// š The API returns an empty response upon success.
console.log("ā
Device settings update request sent.\n");
} catch (error) {
console.error("ā Error updating device settings:", error.message);
}
}
/**
* Main function to retrieve device data and update settings.
*/
async function main() {
try {
console.log("š Starting settings update...");
console.log("š Requesting access token...");
// Retrieve access token
const params = new URLSearchParams({
grant_type: 'client_credentials',
scope: 'device_full_access'
});
const authResponse = await fetch("https://oauth.cleargrass.com/oauth2/token", {
method: 'POST',
headers: {
'Authorization': 'Basic ' + CREDENTIALS,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params,
});
if (!authResponse.ok) throw new Error(`Auth Error: ${authResponse.status} - ${authResponse.statusText}`);
const { access_token: accessToken } = await authResponse.json();
console.log("ā
Access Token received");
console.log("\nš” Retrieving devices...");
const timestamp = Date.now().toString();
const deviceResponse = await fetchWithAuth(`https://apis.cleargrass.com/v1/apis/devices?timestamp=${timestamp}`, 'GET', accessToken);
if (!deviceResponse.devices || deviceResponse.devices.length === 0) throw new Error("No devices found");
console.log(`š” Found ${deviceResponse.devices.length} devices`);
const macAddresses = deviceResponse.devices.map(device => device.info.mac);
console.log("\nš Current settings before update:");
deviceResponse.devices.forEach(device => {
console.log(` - ${device.info.name} (MAC: ${device.info.mac}) ā Report: ${device.info.setting?.report_interval ?? "N/A"}s, Collect: ${device.info.setting?.collect_interval ?? "N/A"}s`);
});
// Apply new settings to all devices
await updateDeviceSettings(accessToken, macAddresses);
// Retrieve devices again to confirm the update
console.log("\nš” Verifying updated settings...");
const updatedDeviceResponse = await fetchWithAuth(`https://apis.cleargrass.com/v1/apis/devices?timestamp=${timestamp}`, 'GET', accessToken);
console.log("\nš Updated settings:");
updatedDeviceResponse.devices.forEach(device => {
console.log(` - ${device.info.name} (MAC: ${device.info.mac}) ā Report: ${device.info.setting?.report_interval ?? "N/A"}s, Collect: ${device.info.setting?.collect_interval ?? "N/A"}s`);
});
console.log("\nā
Device settings update completed.\n");
} catch (error) {
console.error("\nā Error:", error.message);
}
}
// Execute the script
await main();
return "Script completed";
Replace the APP_KEY and APP_SECRET fields with your key and secret. Save the script then run it using the Test button. This will change the update frequency of your Qingping devices to every 60 seconds (this is can be changed in the script by editing the REPORT_INTERVAL and COLLECT_INTERVAL variables near the top of the script. You have to re-run the script every time you want to change the update frequency.
Set up a flow to populate virtual sensor data with data from your Qingping device. In the web app, go to the Flow section in the sidebar, and click + New Flow at the bottom of the sidebar. Select an Advanced Flow from the menu. The flow will function as follows:
Every 5 minutes ā Run qingping_update script ā Wait for it to finish ā Assign data to virtual device sensor fields
Here is a screenshot of my script which you can use as an example for constructing your own:

Now you should be all set! Looking at the air monitor device on your dashboard, you should see it populated with air quality data. This data should update every few minutes. Congratulations, you now have integrated your Qingping air quality monitor into Homey!