Avelon - Wisely CarbonSense
- Manufacturer: Avelon
- Product: Wisely CarbonSense
The Wisely CarbonSense is an indoor room sensor to measure temperature, humidity, CO2 and atmosperic pressure.
Table of contents
- Specifications
- Documents / Links
- Wisely Product Overview
- Ordering Info
- Device specific Information
- Adding the Device to TTN
- Optional Settings
- Payload formatter
Specifications
- Indoor device
- Price ca. CHF 191.- (25.05.2022)
- Sensors
- Temperature, -10 … +80 [°C], ± 0.1 °C between 20 … 60 °C
- relative Humidity, 0 … 95[%rH], ± 1.5 %rH between 10…80 %rH
- CO2, 400 … 5’000 [ppm], ± 30 ppm + 3 % of measurement value
- atmospheric pressure, [hPa], ± 1 hPa Attention: A series of Wisely CarbonSense (software version < 3.3) does not support air pressure measurement!
- Power Supply: 1 battery, 3.6 V, 3600 mAh, (A), Li-SOCl₂
- Expected life time: 3 … 8 years at roomtemperature
- Size: 80 × 80 × 27 mm
- Weight: 100 g
Documents / Links
- Payload description from avelon (online)
- Wisely Datasheet from avelon.com (2020-07-14)
- FAQ on avelon.com
- Temp- and Humidity Sensor Datasheet - Sensirion SHT3x
- Atmospheric Pressure Sensor Datasheet - Bosch BMP380
- CO2 Sensor Datasheet - Senseair Sunrise
- Wisely LED Payload Creator Excel (2023-10-19)
Wisely Product Overview
Sensor | Wisely Standard | Wisely CarbonSense | Wisely AllSense (Simple Payload) | Wisely AllSense (Extended Payload) |
---|---|---|---|---|
Atmospheric pressure | ✓ | ✓ | * | ✓ * |
Temperature | ✓ | ✓ | ✓ | ✓ |
Humidity | ✓ | ✓ | ✓ | ✓ |
VOC | ✓ | ✓ | ||
Brightness | * | ✓ * | ||
CO2 | ✓ | ✓ | ✓ | |
PIR/Presence | * | ✓ * |
- Due to limitations in payload length, these sensors are not activated by default
Ordering Info
Attention, there are four different versions of the same sensor which have different software loaded on them. Only the “Self-Managed” version works with the lcm application. Do not order the version “The Things Network”, it will not work with the lcm application.
- Self-Managed -> that’s what you want to have!!!
Data goes over the ttn network to the ttn server where the lcm application can fetch them, no monthly charges or fees.
Other variants which don’t work with TTN
- Swisscom LPN
Means that the data goes to the AVELON server via Swisscom low power network, monthly charges apply. - The Things Network
Means that the data goes via ttn, but to the AVELON-server! No monthly charges. In this case the lcm application can’t access the data! - Building Automation
Integration in the Avelon automation system, license fees system.
Device specific Information
LED blinking behaviour
If a CO2 limit is exceeded, the LED on the front side of the device changes color. It blinks every SensorSampleTime (250 ms lighting, 500 ms pause - repeating 4 times).
CO2 value | LED Color |
---|---|
0 … 800 | green (on some devices this is deactivated) |
801 … 1400 | blue |
> 1400 | red |
To deactivate or change the led behaviour see Change the LED blinking behaviour
CO2 Sensor ABC Algorithm
The ABC algorithm in CO2 sensors uses automatic base correction to reduce fluctuations and drifts in CO2 measurements. It continuously determines the zero point of the CO2 signal and adjusts it to 400 ppm (more or less the outside level) to ensure accurate and stable detection of CO2 concentrations in ambient air. This improves the long-term stability and reliability of CO2 sensors.
However, this means that the sensor must be exposed to clean air at least every 14 days. Otherwise the CO2 value will drift.
The sensor determines this base value during the first 2 weeks of operation and only provides usable values after this time. It is therefore important that the sensor has been exposed to the outside air for more than 2 hours during this time. If you want to accelerate this process, you can expose the sensor to the outside air and then send a downlink payload B2
. This is how you end the 2 weeks period.
- In the TTN Console on the device view, select the device and change to the tab
Messaging
, selectDownlink
- Change the
FPort to 10
- Write
B2
into thePayload
field - Press
Send
- In the
Data
tab you should now see the scheduled telegram. The wisely sensor only receives downlink data after a transmission. Therefore start a transmission by pressing the button on the back of the sensor (push once short, green led will illuminate)
Handler Change
- The Wisely sensors are per default configured for the Avelon Cloud, even if ordered as “self-managed”. Thats why we have to detach the device from the avelon cloud.
- Switch the device on and scan the
QR-Code
with e.g. a Mobile Phone (detailed information here) - Click on the round
information (i) symbol
top right aside the sensor name - Press
Register for free
- Press
create new account
or login if you already have created an account - When promted select
Private
and fill in the fields, then register - Assign the device and skip the
select location
as well asalerting
- Change to your computer and log in to https://avelon.cloud/login
- Click
your name > Devices
on top right - Your device should appear. Click on it to open the
Device Configuration
- Click on the
three small circles top right (More)
and chooseConfigure LoraWAN Network Provider
- Choose
Self-Managed
and hitOK
- Press the
blue floppy disk symbol
top right to save the configuration. - Copy the
Device EUI
,Application EUI
andApplication Key
, we will need them later on. - Now we have to
reset the device manually
approximately 1-2 minutes after closing the previous dialog by pressing the small button on the back of the device.5 seconds -> Off
,2 seconds -> On
Adding the Device to TTN
- Before a device can communicate via “The Things Network” we need to register it with an application.
- The Avelon Wisely sensors use the so called “Over The Air Activation” (OTAA) and for a secure communication we will need to register the beforehand copied keys.
- Create a new application
- Under
Overview
click(+) Register device
- Under
Input method
selectEnter end device specifics manually
- Under
Frequency plan
selectEurope 863-870 Mhz (SF9 for RX2 - recommended)
- Under
LoRaWAN version
selectLoRaWAN Specification 1.0.3
- As
JoinEUI
enter theApplication EUI
, fill in as well theDevice EUI
and theApplication Key
- Set an end-device name
- Press
Register end device
- Add the payload formatter
- Switch to the tab
Payload formatters
- As
Formatter type
selectCustom Javascript formatter
- Copy/Paste the code from the payload Formatter section below
- Click
Save changes
- Switch to the tab
- Now we have to reset the device manually by pressing the small button on the back of the device.
5 seconds -> Off
,2 seconds -> On
- The device should log in and you should see a green circle as
Status
in the tabDevice Overview
.- if not, please wait several hours and check again. The change of the handler can take a long time…
Optional Settings
Change sampling and transmission intervals
There are two configuration values, SensorSampleTime
and CyclicTransmissionCounter
. To change these two values, you have to send the device configuration telegrams (Downlink-Messages)
SensorSampleTime
The time interval in minutes at which the sensor queries the current values.
- In the TTN Console on the device view, select the device and change to the tab
Messaging
, selectDownlink
- Change the
FPort to 10
- Copy/paste the payload from the examples below, e.g.
FF 01 0A
into thePayload
field - Press
Send
- In the
Data
tab you should now see the scheduled telegram. The wisely sensor only receives downlink data after a transmission. Therefore start a transmission by pressing the button on the back of the sensor (push once short, green led will illuminate)
CyclicTransmissionTime and CyclicTransmissionCounter
The time interval at which the sensor transmits the recorded measurement values. Must be a multiple of the sampling period.
To avoid overburdening the battery of the device, the smallest permissible time interval is 10 minutes.
The CyclicTransmissionTime cannot be configured. Instead, a counter can be configured.
CyclicTransmissionTime = CyclicTransmissionCounter × SensorSampleTime
This setting cannot be configured. But instead the value CyclicTransmissionCounter
can be set.
CyclicTransmissionCounter
Per default the CyclicTransmissionCounter is set to 60, which means the device in default configuration sends data every 60 minutes (60 × 1 min = 60 min).
The device sends the data cyclically. When a certain number of samples has been taken, the measured values are sent. The CyclicTransmissionCounter
is therefore the number of samples that are to be sent together.
CyclicTransmissionCounter = CyclicTransmissionTime / SensorSampleTime
Per default the CyclicTransmissionCounter
is set to 60, so every 1h a set of 6 measurements of all sensors gets transmitted.
- In the TTN Console on the device view, select the device and change to the tab
Messaging
, selectDownlink
- Change the
FPort to 10
- Copy/paste the payload from the examples below, e.g.
FF F0 06
into thePayload
field - Press
Send
- In the
Data
tab you should now see the scheduled telegram. The wisely sensor only receives downlink data after a transmission. Therefore start a transmission by pressing the button on the back of the sensor (push once short, green led will illuminate)
Example configurations
Example 1 (default config)
This configuration makes sense if the LED is used, so the occupant gets every minute a flashing LED. If the LED gets deactivated anyway, the sampling rate is unecessary high.
- SensorSampleTime = 1 (HEX 01 ->
FF 01 01
) Every 1 min a sensor sample, every 10 min an averaged measurement. - CyclicTransmissionCounter = 60 (HEX 3C ->
FF F0 3C
) After 60 samples a data transmission, that means 6 averaged measurements in the payload, transmitted every 60 minutes.
Example 2
This configuration makes sense if the LED is used and the values should arrive faster than every hour. This has an impact on battery life! If the LED gets deactivated anyway, the sampling rate is unecessary high.
- SensorSampleTime = 1 (HEX 01 ->
FF 01 01
) Every 1 min a sensor sample, every 10 min an averaged measurement. - CyclicTransmissionCounter = 20 (HEX 14 ->
FF F0 14
) After 20 samples a data transmission, that means 2 averaged measurements in the payload, transmitted every 20 minutes.
Example 3
This configuration makes sense if the smallest possible measuring rate is required and the LED gets deactivated.
- SensorSampleTime = 10 (HEX 0A ->
FF 01 0A
) Every 10 min a sensor sample, every 10 min an averaged measurement. - CyclicTransmissionCounter = 6 (HEX 06 ->
FF F0 06
) After 6 samples a data transmission, that means 6 averaged measurements in the payload, transmitted every 60 minutes.
Example 4
This configuration makes sense if a long battery life is required and the LED gets deactivated. The sensor acts as a logger and the data is not real time, but battery life is optimized. Small changes in sensor values cannot get detected, so the accuracy is slightly lower. E.g. the impact of an opened window might not be visible in the temperature data.
- SensorSampleTime = 60 (HEX 3C ->
FF 01 3C
) Every 60 min a sensor sample, every 60 min an averaged measurement. - CyclicTransmissionCounter = 24 (HEX 18 ->
FF F0 18
) After 6 samples a data transmission, that means 6 averaged measurements in the payload, transmitted every 360 minutes (6 hours).
Change the led blinking behaviour
With the following procedure you can deactivate the LED
- Select the device and change to the tab
Messaging
, selectDownlink
- Change the
FPort to 10
- Copy/paste
06 06 0B 03 20 00 00 FF 00
into thePayload
field for deactivating the blue led - Press
Send
- The wisely sensor only receives downlink data after a transmission. Therefore start a transmission by pressing the button on the back of the sensor (push once short, green led will illuminate)
- Copy/paste
06 06 0B 05 78 FF 00 00 00
into thePayload
field for deactivating the red led - Press
Send
- Press again the button on the back of the sensor
- Now the led should not blink anymore.
- To reset the behaviour exchange the last byte with
01
instead of00
:06 06 0B 03 20 00 00 FF 01
06 06 0B 05 78 FF 00 00 01
Look at the Wisely LED Payload Creator Excel to create the payload information.
Further info in the payload description .
Payload formatter
function getValues(bytes, measurement, byteIndices, deviceType, datasetCount, datasetLength, payloadOffset) {
var decoded = [];
var measurementByteLengths = {"pressure_hPa": 2, "temperature_degrC": 2, "humidity_perc": 1, "voc_index": 2, "brightness_lux": 2, "co2_ppm": 2, "presence_min": 2};
var divFactors = {"pressure_hPa": 10.0, "temperature_degrC": 10.0, "humidity_perc": 2.0, "voc_index": 1.0, "brightness_lux": 1.0, "co2_ppm": 1.0, "presence_min": 1.0};
if (measurement in byteIndices[deviceType]) {
var byteIndexValue = byteIndices[deviceType][measurement];
for (var i = 0; i < datasetCount; i++) {
var byteIndex = i * datasetLength + byteIndexValue + payloadOffset;
if (measurementByteLengths[measurement] === 2) {
decoded.push((bytes[byteIndex] << 8 | bytes[byteIndex + 1]) / divFactors[measurement]);
} else {
decoded.push((bytes[byteIndex]) / divFactors[measurement]);
}
}
}
return decoded;
}
function decodeUplink(input) {
var deviceType = "CarbonSense";
var samplingRate = 10; //minutes
var datasetLengthDict = {
"Standard": 5,
"CarbonSense": 7,
"AllSense": 7,
"AllSenseExt": 13
};
var byteIndices = {
"Standard": {"pressure_hPa": 0, "temperature_degrC": 2, "humidity_perc": 4},
"CarbonSense": {"pressure_hPa": 0, "temperature_degrC": 2, "humidity_perc": 4, "co2_ppm": 5},
"AllSense": {"temperature_degrC": 0, "humidity_perc": 2, "voc_index": 3, "co2_ppm": 5},
"AllSenseExt": {"pressure_hPa": 0, "temperature_degrC": 2, "humidity_perc": 4, "voc_index": 5, "brightness_lux": 7, "co2_ppm": 9, "presence_min": 11}
};
var payloadOffset = 1; // Offset of battery information, offset before datasets
var warnings = [];
var errors = [];
if(datasetLengthDict[deviceType] === undefined){
errors.push("Error: Typo in deviceType configuration in payload decoder");
}
if((input.fPort === 5) || (input.fPort === 6)){
// Battery status and percent
var batVal = input.bytes[0];
var batteryPerc;
if((batVal >= 30) && (batVal < 254)){
batteryPerc = Math.round(batVal / 254.0 * 100.0 * 10) / 10;
}else if((batVal < 30) && (batVal > 1)){
batteryPerc = Math.round(batVal / 254.0 * 100.0 * 10) / 10;
warnings.push("Battery Warning: Low state");
}else if((batVal === 1)){
batteryPerc = 1;
warnings.push("Battery Warning: No further battery capacity available");
}else if(batVal === 254){
batteryPerc = 100.0;
} else{
batteryPerc = 0.0;
warnings.push("Battery Warning: Could not acquire the voltage");
}
if(input.fPort === 6 && deviceType !== "AllSense"){
warnings.push("Warning: deviceType in payload decoder is not set to AllSense");
}
var datasetLength = datasetLengthDict[deviceType];
var datasetCount = (input.bytes.length - 2) / datasetLength;
var readings = [];
if(!Number.isInteger(datasetCount)) {
errors.push("Error: datasetCount is not a whole number!");
} else {
for (var i = 0; i < datasetCount; i++) {
var reading = { battery_perc: batteryPerc };
for (const [key, value] of Object.entries(byteIndices[deviceType])) {
var decoded = getValues(input.bytes, key, byteIndices, deviceType, 1, datasetLength, payloadOffset + i * datasetLength);
if (decoded.length > 0) {
reading[key] = decoded[0];
}
}
reading["offset"] = (datasetCount - i - 1) * samplingRate * (-1);
readings.push(reading);
}
}
} else {
errors.push("Unknown fPort");
}
return {
data: readings,
warnings: warnings,
errors: errors
};
}