Smartico E307
Smartico E307
Smartico
- Platform
- ThingsBoard
- Hardware Type
- Sensors
- Connectivity
- LoRaWAN
- Industry
- Energy Management, Smart Cities, Smart Buildings
- Use Case
- Smart Energy, Smart Metering
Introduction
The Smartico E307 is a three-phase smart electricity meter optimized for smart metering systems. It measures active and reactive energy in both consumed and delivered directions, and stores data in non-volatile memory. It measures voltage, current, power, frequency, and related grid quality parameters.
This guide describes how to receive telemetry from the Smartico E307 over LoRaWAN using ChirpStack and a ThingsBoard MQTT integration, and visualize the data on a dashboard.
The dashboard displays two states: counter readings and quality parameters.
Prerequisites
- Smartico E307 — 1×
- ChirpStack LoRaWAN Network Server with the device registered and connected
- ChirpStack MQTT integration configured with a Mosquitto MQTT broker
- ThingsBoard PE instance: use ThingsBoard Cloud or install a local PE server
Configure ChirpStack
Register the Smartico E307 in ChirpStack and verify the device is transmitting. The device should appear on the Applications page with its serial number (like 0012778).
Create the uplink data converter
The uplink data converter decodes the Base64-encoded payload from the E307 into ThingsBoard telemetry format.
- Download uplink_electricity_smart_meter.json.
- Go to Integrations center ⇾ Data converters and click + Add data converter > Import converter.
- Drag and drop the downloaded
uplink_electricity_smart_meter.jsonfile. - Click Import.
/** Decoder **/var payloadStr = decodeToString(payload);var data = JSON.parse(payloadStr);var deviceName = data.deviceName;var deviceType = 'elecMeter';var res = _base64ToArrayBuffer(data.data);if(res[0]==35) return null;var dateTime=GetCurrentDateTime();var voltage_A=null;var voltage_B=null;var voltage_C=null;var current_A=null;var current_B=null;var current_C=null;var frequency=null;var power_full_Summary=null;var power_full_A=null;var power_full_B=null;var power_full_C=null;var power_active_Summary=null;var power_active_A=null;var power_active_B=null;var power_active_C=null;var power_reactive_Summary=null;var power_reactive_A=null;var power_reactive_B=null;var power_reactive_C=null;var energy_active_Summary=null;var energy_active_t1=null;var energy_active_t2=null;var energy_active_t3=null;var energy_active_t4=null;var energy_active_t5=null;var energy_active_t6=null;var energy_active_t7=null;var energy_active_t8=null;var energy_reactive_Summary=null;var energy_reactive_t1=null;var energy_reactive_t2=null;var energy_reactive_t3=null;var energy_reactive_t4=null;var energy_reactive_t5=null;var energy_reactive_t6=null;var energy_reactive_t7=null;var energy_reactive_t8=null;
var k=0;for (var i = 0; i < res.length; ) { switch(res[i]) { case 0x40: i+=5; break; case 0x20: var phase = GetPhase(res[i+1]); if(phase==1) voltage_A=GetVoltageValue(res[i+1],res[i+2]); if(phase==2) voltage_B=GetVoltageValue(res[i+1],res[i+2]); if(phase==3) voltage_C=GetVoltageValue(res[i+1],res[i+2]); i+=3; break; case 0x21: var phase = GetPhase(res[i+1]); if(phase==1) current_A=GetCurrentValue(res[i+1],res[i+2]); if(phase==2) current_B=GetCurrentValue(res[i+1],res[i+2]); if(phase==3) current_C=GetCurrentValue(res[i+1],res[i+2]); i+=3; break; case 0x22: frequency=GetFrequency(res[i+1],res[i+2]); i+=3; break; case 0x41: var typePower = GetPhase(res[i+1]); var phasePower=GetPhasePower(res[i+1]); if(typePower==1) { if(phasePower==0) power_active_Summary=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==1) power_active_A=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==2) power_active_B=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==3) power_active_C=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); } if(typePower==2) { if(phasePower==0) power_reactive_Summary=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==1) power_reactive_A=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==2) power_reactive_B=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==3) power_reactive_C=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); } if(typePower==3) { if(phasePower==0) { power_full_Summary=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); } if(phasePower==1) power_full_A=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==2) power_full_B=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(phasePower==3) power_full_C=GetPowerValue(res[i+1], res[i+2], res[i+3], res[i+4]); } i+=5; break; case 0x42: var typeEnergy = GetEnergy(res[i+1]); var tariff=GetTariff(res[i+1]); if(typeEnergy==0) { if(tariff==0) energy_active_Summary=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==1) energy_active_t1=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==2) energy_active_t2=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==3) energy_active_t3=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==4) energy_active_t4=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==5) energy_active_t5=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==6) energy_active_t6=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==7) energy_active_t7=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==8) energy_active_t8=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); } if(typeEnergy==1) { if(tariff==0) energy_reactive_Summary=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==1) energy_reactive_t1=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==2) energy_reactive_t2=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==3) energy_reactive_t3=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==4) energy_reactive_t4=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==5) energy_reactive_t5=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==6) energy_reactive_t6=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==7) energy_reactive_t7=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); if(tariff==8) energy_reactive_t8=GetEnergyValue(res[i+1], res[i+2], res[i+3], res[i+4]); }
i+=5; break; default: k=1; break; } if(k==1) break; }
var result = { deviceName: deviceName, deviceType: deviceType, attributes: { integrationName: metadata['integrationName'], }, telemetry: { REAL_TIME: dateTime, SN: data.deviceName, deviceTypeTelemetry: "Smartico E307", NAME_DEV: "Electricity Meter 'Smartico E307'", VOLTAGE_A: voltage_A, VOLTAGE_B: voltage_B, VOLTAGE_C: voltage_C, CURRENT_A: current_A, CURRENT_B: current_B, CURRENT_C: current_C, FREQUENCY: frequency, POWER_FULL_SUMMARY: power_full_Summary, POWER_FULL_A: power_full_A, POWER_FULL_B: power_full_B, POWER_FULL_C: power_full_C, POWER_ACTIVE_SUMMARY: power_active_Summary, POWER_ACTIVE_A: power_active_A, POWER_ACTIVE_B: power_active_B, POWER_ACTIVE_C: power_active_C, POWER_REACTIVE_SUMMARY: power_reactive_Summary, POWER_REACTIVE_A: power_reactive_A, POWER_REACTIVE_B: power_reactive_B, POWER_REACTIVE_C: power_reactive_C,
VALUE: energy_active_Summary, ENERGY_ACTIVE_SUMMARY: energy_active_Summary, ENERGY_ACTIVE_T1: energy_active_t1, ENERGY_ACTIVE_T2: energy_active_t2, ENERGY_ACTIVE_T3: energy_active_t3, ENERGY_ACTIVE_T4: energy_active_t4, ENERGY_ACTIVE_T5: energy_active_t5, ENERGY_ACTIVE_T6: energy_active_t6, ENERGY_ACTIVE_T7: energy_active_t7, ENERGY_ACTIVE_T8: energy_active_t8, ENERGY_REACTIVE_SUMMARY: energy_reactive_Summary, ENERGY_REACTIVE_T1: energy_reactive_t1, ENERGY_REACTIVE_T2: energy_reactive_t2, ENERGY_REACTIVE_T3: energy_reactive_t3, ENERGY_REACTIVE_T4: energy_reactive_t4, ENERGY_REACTIVE_T5: energy_reactive_t5, ENERGY_REACTIVE_T6: energy_reactive_t6, ENERGY_REACTIVE_T7: energy_reactive_t7, ENERGY_REACTIVE_T8: energy_reactive_t8, }};
/** Helper functions **/
function decodeToString(payload) { return String.fromCharCode.apply(String, payload);}
function decodeToJson(payload) { var str = decodeToString(payload); var data = JSON.parse(str); return data;}
function _base64ToArrayBuffer(base64) { var binary_string = atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); var str=""; for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes;}
function GetCurrentDateTime(){ var a=new Date(); var year = a.getFullYear().toString(); var month = (a.getMonth()+1).toString(); if(month.length==1) month="0"+month; var date = a.getDate().toString(); if(date.length==1) date="0"+date; var hour = a.getHours().toString();; if(hour.length==1) hour="0"+hour; var min = a.getMinutes().toString();; if(min.length==1) min="0"+min; var sec = a.getSeconds().toString();; if(sec.length==1) sec="0"+sec; var time = date + '.' + month + '.' + year + ' ' + hour + ':' + min + ':' + sec ; return time;}
function GetPowerValue(byte1, byte2, byte3, byte4) { var value1 = byte1.toString(2) while(value1.length<8){ value1='0'+value1;} var value2 = byte2.toString(2); while(value2.length<8){ value2='0'+value2;} var value3 = byte3.toString(2) while(value3.length<8){ value3='0'+value3;} var value4 = byte4.toString(2); while(value4.length<8){ value4='0'+value4;} var value = value1[4]+value1[5]+value1[6]+value1[7] + value2+value3+value4; return parseInt(value,2)/100;}
function SimulatePower(persent) { return parseInt(value,2)/100;}
function GetEnergyValue(byte1, byte2, byte3, byte4) { var value1 = byte1.toString(2) while(value1.length<8){ value1='0'+value1;} var value2 = byte2.toString(2); while(value2.length<8){ value2='0'+value2;} var value3 = byte3.toString(2) while(value3.length<8){ value3='0'+value3;} var value4 = byte4.toString(2); while(value4.length<8){ value4='0'+value4;} var value = value1[5]+value1[6]+value1[7] + value2+value3+value4; return parseInt(value,2)/100;}
function GetFrequency(byte1, byte2) { var value1 = byte1.toString(2) while(value1.length<8){ value1='0'+value1;} var value2 = byte2.toString(2); while(value2.length<8){ value2='0'+value2;} var value = value1 + value2;
return parseInt(value,2)/1000;}
function GetVoltageValue(byte1, byte2) { var value1 = byte1.toString(2) while(value1.length<8){ value1='0'+value1;} var value2 = byte2.toString(2); while(value2.length<8){ value2='0'+value2;} var value = value1[2]+value1[3]+value1[4]+value1[5]+value1[6]+value1[7] + value2;
return parseInt(value,2)/10;}
function GetCurrentValue(byte1, byte2) { var value1 = byte1.toString(2) while(value1.length<8){ value1='0'+value1;} var value2 = byte2.toString(2); while(value2.length<8){ value2='0'+value2;} var value = value1[3]+value1[4]+value1[5]+value1[6]+value1[7] + value2; if(parseInt(value1[2],2) == 0) return parseInt(value,2)/100; else return parseInt(value,2)/10;}
function GetPhase(mainByte){ var phase = mainByte.toString(2); while(phase.length<8){ phase='0'+phase;} phase=phase[0].toString(2)+phase[1].toString(2); return parseInt(phase,2);}
function GetEnergy(mainByte){ var phase = mainByte.toString(2); while(phase.length<8){ phase='0'+phase;} phase=phase[0].toString(2); return parseInt(phase,2);}
function GetPhasePower(mainByte){ var phase = mainByte.toString(2); while(phase.length<8){ phase='0'+phase;} phase=phase[2].toString(2)+phase[3].toString(2); return parseInt(phase,2);}
function GetTariff(mainByte){ var tariff = mainByte.toString(2); while(tariff.length<8){ tariff='0'+tariff;} tariff=tariff[1].toString(2)+tariff[2].toString(2)+tariff[3].toString(2)+tariff[4].toString(2); return parseInt(tariff,2);}
return result;You can test the converter before connecting the device. Open the Uplink Elec Meter converter, enter edit mode and click the Test decoder function tab. Paste the sample input below into Payload content field and press Test.
Sample input payload (Base64-encoded)
{ "applicationID": "2", "applicationName": "Smartico_electric_meters", "deviceName": "0012778", "devEUI": "02aaaa02000031ea", "rxInfo": [{ "gatewayID": "647fdafffe00d228", "uplinkID": "9d29d67f-8db2-4c7e-9fa8-b7f9bd5be9e6", "name": "tectelic_micro_lite_TECH", "rssi": -80, "loRaSNR": 5.2, "location": { "latitude": 48.44229794818326, "longitude": 35.014479160308845, "altitude": 144}}], "txInfo": { "frequency": 868500000, "dr": 0}, "adr": true, "fCnt": 2202, "fPort": 15, "data": "QF8gJWwgSK4giMogyIYhQHEhgcshwTwiw1BBwABNNw=="}Expected decoded output
{ "deviceName": "0012778", "deviceType": "elecMeter", "attributes": { "integrationName": "Elec Meter"}, "telemetry": { "REAL_TIME": "27.08.2020 09:51:49", "SN": "0012778", "deviceTypeTelemetry": "Smartico E307", "NAME_DEV": "Electricity Meter 'Smartico E307'", "VOLTAGE_A": 222.2, "VOLTAGE_B": 225, "VOLTAGE_C": 218.2, "CURRENT_A": 1.13, "CURRENT_B": 4.59, "CURRENT_C": 3.16, "FREQUENCY": 50, "POWER_FULL_SUMMARY": 197.67}}Create the integration
For more information about MQTT integrations in ThingsBoard, see the MQTT integration documentation.
- Go to Integrations center ⇾ Integrations and click + Add integration.
- Basic settings:
- Set Integration type to MQTT.
- Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Select existing — choose a previously created
Uplink Electricity Smart Meterfrom the list. - Click Next.
- Select existing — choose a previously created
- Downlink data converter:
- Click Skip — only needed for RPC; can be added later.
- Connection:
- Set your MQTT broker Host and Port.
- Select the Credentials type (e.g. Anonymous).
- Add at least one topic filter with QoS (e.g.
application/2/device/+/rx, QoS0 — At most once).
- Click Add to complete the integration setup.
Verify data
After the E307 transmits its first packet, a new device named after its serial number (like 0012778) appears automatically in Entities > Devices.
Create an asset
To display data on the dashboard, create an asset and add the device as a relation.
-
Go to Entities ⇾ Assets and create a new asset. Named
Electricity Meterwithelectricity-meterasset type. -
Open the asset, go to the Relations tab, and add a relation to device
0012778.
Import the dashboard
-
Download dashboard_elec_meter.json and import it in Dashboards. See the dashboard import instructions.
-
After importing, edit the dashboard alias and set it to the Electricity Meter asset created in the previous step.
The dashboard now displays live counter readings and quality parameters from the Smartico E307.