Events

:

:

Elektronik | Funk | Software

Der Technik-Blog

  • Social Media

    Werbung:


    New Posts


    Events

    • Keine zukünftigen Events vorhanden

    The Tech-Blog

    SenseCAP T1000 Payload Decoder

    SenseCAP T1000 Payload Decoder

    Alex @ AEQ-WEB

    The SenseCAP T1000 is a very affordable LoRaWAN GPS tracker with a wide range of functions and numerous sensors. In addition to the hardware, the manufacturer also offers software services and provides its own LoRaWAN network server and cloud applications for its end devices and gateways. Of course, the SenseCAP T1000 can also be connected to the community network TTN (The Things Network). Although Seeed provides a Javascript decoder for TTN, Helium and other networks, but the decoded payload parameters are provided in a very special format (probably optimized for the SenseCAP portal). Many LoRaWAN applications such as LoWTrack or the TTN mapper do not work with the original decoder. Due to numerous requests, a "TTN-friendly" Javascript decoder was written which works with conventional tools such as LoWTrack.


    Attention: This payload decoder has been carefully developed and tested with a tracker and with the payload examples from the official documentation. It cannot be guaranteed that this decoder will be compatible with future firmware versions. Use at your own risk! No liability is assumed for the correctness and functionality!


    Werbung:

    Testinformation
    This decoder was tested with TTN V3 and the LoWTrack app:
    T1000 Software Version: 1.14
    T1000 Hardware Version: 1.6
    Test date: 26/11/2023

    /*
     * Javascript Decoder for Seeed SenseCAP T1000 LoRaWAN GPS Tracker Version 1.1 (@aeqweb)
     * More Information at: https://www.aeq-web.com/seeed-sensecap-t1000-lorawan-gps-tracker-ttn-payload-decoder/
     */
    function decodeUplink(input) {
        const bytes = input['bytes']
        const fport = parseInt(input['fPort'])
    
        const packetID = bytes[0];
        var decoded = {};
    
    
        if (packetID == 1) {
            const batt = bytes[1];
            const swv = bytes[2] + "." + bytes[3];
            const hwv = bytes[4] + "." + bytes[5];
            const wm = getWorkMode(bytes[6]);
            const ps = getPosStrategy(bytes[7]);
            const hiv = bytes[8] << 8 | bytes[9];
            const uiv = bytes[10] << 8 | bytes[11];
            const eiv = bytes[12] << 8 | bytes[13];
            const so = bytes[14];
            const sm = bytes[15];
            const me = Boolean(bytes[16]);
            const mt = bytes[17] << 8 | bytes[18];
            const ms = bytes[19] << 8 | bytes[20];
            const ml = Boolean(bytes[21]);
            const mo = bytes[22] << 8 | bytes[23];
            const se = Boolean(bytes[24]);
            const st = bytes[25] << 8 | bytes[26];
            const te = Boolean(bytes[27]);
            const tu = bytes[28] << 8 | bytes[29];
            const ts = bytes[30] << 8 | bytes[31];
            const th = (bytes[32] << 8 | bytes[33]) / 10;
            const tl = (bytes[34] << 8 | bytes[35]) / 10;
            const tr = bytes[36];
            const le = Boolean(bytes[37]);
            const lu = bytes[38] << 8 | bytes[39];
            const ls = bytes[40] << 8 | bytes[41];
            const lh = bytes[42] << 8 | bytes[43];
            const ll = bytes[44] << 8 | bytes[45];
            const lw = bytes[46];
    
            var sens = "unkown"
            var sosm = "unkown"
    
    
            if (so) {
                sens = "Temp-Light Sen. on"
            } else if (sm === 0) {
                sens = "Temp-Light Sen. off"
            }
    
            if (sm) {
                sosm = "Continuous Mode"
            } else if (sm === 0) {
                sosm = "Single Mode"
            }
    
            decoded = {
                packet: "Heartbeat",
                battery: batt,
                softwareV: swv,
                hardwareV: hwv,
                workMode: wm,
                posStrategy: ps,
                heartbeatInterval: hiv,
                uplinkInterval: uiv,
                EventInterval: uiv,
                sensors: sens,
                sosMode: sosm,
                motionEventMode: me,
                motionThreshold: mt,
                motionStartInterval: ms,
                motionlessEvent: ml,
                motionlessTimeout: mo,
                shockEvent: se,
                shockThreshold: st,
                tempEvent: te,
                tempInterval: tu,
                tempSample: ts,
                tempThresholdMax: th,
                tempThresholdMin: tl,
                tempThresholdRule: tr,
                lightEvent: le,
                lightInterval: lu,
                lightSample: ls,
                lightThresholdMax: lh,
                lightThresholdMin: ll,
                lightWarningType: lw
            }
        } else if (packetID == 2) {
            const batt = bytes[1];
            const swv = bytes[2] + "." + bytes[3];
            const hwv = bytes[4] + "." + bytes[5];
            const wm = getWorkMode(bytes[6]);
            const ps = getPosStrategy(bytes[7]);
            const hiv = bytes[8] << 8 | bytes[9];
            const uiv = bytes[10] << 8 | bytes[11];
            const eiv = bytes[12] << 8 | bytes[13];
            const so = bytes[14];
            const sm = bytes[15];
            var sens = "unkown"
            var sosm = "unkown"
    
    
            if (so) {
                sens = "Temp-Light Sen. on"
            } else if (sm === 0) {
                sens = "Temp-Light Sen. off"
            }
    
            if (sm) {
                sosm = "Continuous Mode"
            } else if (sm === 0) {
                sosm = "Single Mode"
            }
    
            decoded = {
                packet: "Heartbeat",
                battery: batt,
                softwareV: swv,
                hardwareV: hwv,
                workMode: wm,
                posStrategy: ps,
                heartbeatInterval: hiv,
                uplinkInterval: uiv,
                EventInterval: uiv,
                sensors: sens,
                sosMode: sosm
            }
        } else if (packetID == 5) {
            const batt = bytes[1];
            const wm = getWorkMode(bytes[2]);
            const ps = getPosStrategy(bytes[3]);
            const sm = bytes[4];
            var sosm = "unkown"
    
            if (sm) {
                sosm = "Continuous Mode"
            } else if (sm === 0) {
                sosm = "Single Mode"
            }
    
            decoded = {
                packet: "Heartbeat",
                battery: batt,
                workMode: wm,
                posStrategy: ps,
                sosMode: sosm
            }
        } else if (packetID == 6) {
            const sta = (bytes[1] << 16 | bytes[2] << 8 | bytes[3]);
            const mcnt = bytes[4];
            const utc = unixToDateTime(bytes[5] << 24 | bytes[6] << 16 | bytes[7] << 8 | bytes[8]);
            const lon = (bytes[9] << 24 | bytes[10] << 16 | bytes[11] << 8 | bytes[12]) / 1000000;
            const lat = (bytes[13] << 24 | bytes[14] << 16 | bytes[15] << 8 | bytes[16]) / 1000000;
            const tmp = ((bytes[17] & 0x80 ? 0xFFFF << 16 : 0) | bytes[17] << 8 | bytes[18]) / 10;
            const lgt = (bytes[19] << 8 | bytes[20]);
            const batt = bytes[21];
    
            decoded = {
                packet: "GNSS Location & Sensor Data",
                eventStatus: sta,
                motionCount: mcnt,
                utcTime: utc,
                longitude: lon,
                latitude: lat,
                temperature: tmp,
                light: lgt,
                battery: batt
            }
        } else if (packetID == 9) {
            const sta = (bytes[1] << 16 | bytes[2] << 8 | bytes[3]);
            const mcnt = bytes[4];
            const utc = unixToDateTime(bytes[5] << 24 | bytes[6] << 16 | bytes[7] << 8 | bytes[8]);
            const lon = (bytes[9] << 24 | bytes[10] << 16 | bytes[11] << 8 | bytes[12]) / 1000000;
            const lat = (bytes[13] << 24 | bytes[14] << 16 | bytes[15] << 8 | bytes[16]) / 1000000;
            const batt = bytes[17];
    
            decoded = {
                packetType: "GNSS Location",
                eventStatus: sta,
                motionCount: mcnt,
                utcTime: utc,
                longitude: lon,
                latitude: lat,
                battery: batt
            }
        } else if (packetID == 0x11) {
    
            const utc = unixToDateTime(bytes[5] << 24 | bytes[6] << 16 | bytes[7] << 8 | bytes[8]);
            const batt = bytes[13];
    
            if (bytes[11] != 0x80 && bytes[9] != 0x80) {
                const tmp = ((bytes[9] & 0x80 ? 0xFFFF << 16 : 0) | bytes[9] << 8 | bytes[10]) / 10;
                const lgt = (bytes[11] << 8 | bytes[12]);
    
                decoded = {
                    packet: "Positing status",
                    utcTime: utc,
                    temperature: tmp,
                    light: lgt,
                    battery: batt
                }
            } else {
                decoded = {
                    packet: "Positing status",
                    utcTime: utc,
                    battery: batt
                }
            }
    
    
    
        } else if (packetID == 0x0D) {
            const ec = (bytes[1] << 24 | bytes[2] << 16 | bytes[3] << 8 | bytes[4]);
    
            decoded = {
                packet: "Positioning Timeout",
                longitude: 0,
                latitude: 0,
                errorCode: ec
            }
    
        } else {
            decoded = {
                packetType: "unkown",
                packetID: packetID
            }
        }
    
        return {
            data: decoded
        }
    
    }
    
    
    function convertToDec(b) {
        var return_value = parseInt(b, 16);
        return return_value;
    }
    
    function unixToDateTime(unixtime) {
        var date = new Date(unixtime * 1000);
        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
        var hours = date.getHours();
        var minutes = "0" + date.getMinutes();
        var seconds = "0" + date.getSeconds();
        var year = date.getFullYear();
        var month = months[date.getMonth()];
        var day = date.getDate();
        var DateTime = day + '-' + month + '-' + year + ' ' + hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
        return DateTime;
    }
    
    function getPosStrategy(ps) {
        var psText = "";
        switch (ps) {
            case 0:
                psText = "Only GNSS";
                break;
            case 1:
                psText = "Only WiFi";
                break;
            case 2:
                psText = "WiFi + GNSS";
                break;
            case 3:
                psText = "GNSS + WiFi";
                break;
            case 4:
                psText = "Only Bluetooth";
                break;
            case 5:
                psText = "Bluetooth + WiFi";
                break;
            case 6:
                psText = "Bluetooth + GNSS";
                break;
            case 7:
                psText = "Bluetooth + WiFi + GNSS";
                break;
            default:
                psText = "unkown";
        }
        return psText;
    }
    
    
    function getWorkMode(wm) {
        var wmText = "";
        switch (wm) {
            case 0:
                wmText = "Standby Mode";
                break;
            case 1:
                wmText = "Periodic Mode";
                break;
            case 2:
                wmText = "Event Mode";
                break;
            default:
                wmText = "unkown";
        }
        return wmText;
    }
    


    Info: This page was automatically translated and may contain errors
    122X122

    About the Author

    Alex, the founder of AEQ-WEB. He works for more of 10 years with different computers, microcontroller and semiconductors. In addition to hardware projects, he also develops websites, apps and software for computers.

    Top articles in this category:

    Vaisala RS41 Radiosonde Firmware Flash

    Radiosonde RS41 Firmware Flash

    • Video
    • DE/EN

    Every day hundreds of meteorological radiosondes fall from the sky. In this article we convert a radiosonde into a GPS tracker for APRS, RTTY & CW

    read more
    LHT65 TTN V3 Webhook PHP Webapp

    LHT65 TTN V3 Webapp

    • DE/EN

    The Things Network only handles the transport of LoRaWAN packets, but not the storage. This is about the integration of a webapp.

    read more

    Social Media

    Werbung:


    New Posts


    Events

    • Keine zukünftigen Events vorhanden