Read variable Java Script

Good afternoon everyone. I’m trying to implement a project that increments a variable and at the same time paying the value of that variable. On node and particle console everything works very well. The problem is in the HTML and JavaScript. In the case of HTML, I can only increment the variable, I don’t get the status of the variable. If anyone can help.

int count;
int addr;


void setup() {
    Particle.function("IoT",myCount);
    Particle.variable("IoT", &count, INT);
}
void loop() {
  static uint32_t msLastExec = 0;
   if (millis() - msLastExec < 500) return; 
   msLastExec = millis();
   count = EEPROM.read(addr);
}
int myCount(String command) {
    if (command.equalsIgnoreCase("INC")){
       count++;
       if(count >= 24){
           count = 0;
       }
       EEPROM.write(addr, count);
       Particle.publish("My count: ", String(count) , PRIVATE);
       count = EEPROM.read(addr);
    }
    return count;
}

<script>
    var particle = new Particle();
    let mfa_token;

    $(document).ready(function () {
        // This function is called when the page loads

        $('#loginForm').submit(function (e) {
            // The Login button on the login page was clicked (or Return pressed)
            e.preventDefault();

            // Hide the login page so the button goes away
            $('#loginDiv').css('display', 'none');
            $('#loginFailedDiv').css('display', 'none');
            sessionStorage.particleUser = $('#userInput').val();

            // Attempt to log into the Particle cloud
            $.ajax({
                data: {
                    'client_id': 'particle',
                    'client_secret': 'particle',
                    'expires_in': 3600,
                    'grant_type': 'password',
                    'password': $('#passwordInput').val(),
                    'username': $('#userInput').val()
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    if (jqXHR.status === 403) {
                        // Got a 403 error, MFA required. Show the MFA/OTP page.
                        mfa_token = jqXHR.responseJSON.mfa_token;
                        $('#otpDiv').css('display', 'inline');
                        return;
                    }
                    console.log('error ' + textStatus, errorThrown);
                    $('#loginDiv').css('display', 'inline');
                    $('#loginFailedDiv').css('display', 'inline');
                },
                method: 'POST',
                success: function (data) {
                    loginSuccess(data.access_token);
                },
                url: 'https://api.particle.io/oauth/token',
            });
        });

        $('#otpForm').submit(function (e) {
            // Login on the OTP/MFA form
            e.preventDefault();

            $('#otpDiv').css('display', 'none');

            $.ajax({
                data: {
                    'client_id': 'particle',
                    'client_secret': 'particle',
                    'grant_type': 'urn:custom:mfa-otp',
                    'mfa_token': mfa_token,
                    'otp': $('#otpInput').val()
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    // Invalid MFA token
                    $('#loginDiv').css('display', 'inline');
                    $('#loginFailedDiv').css('display', 'inline');
                },
                method: 'POST',
                success: function (data) {
                    loginSuccess(data.access_token);
                },
                url: 'https://api.particle.io/oauth/token',
            });

        });

        $('#logoutButton').on('click', function (e) {
            // Logout button clicked
            e.preventDefault();

            // Delete the access token from local session storage
            const accessToken = sessionStorage.particleToken;
            delete sessionStorage.particleToken;
            delete sessionStorage.particleUser;

            // Invalidate the token on the cloud side
            $.ajax({
                data: {
                    'access_token': accessToken
                },
                method: 'DELETE',
                complete: function () {
                    // Show the login page
                    $('#mainDiv').css('display', 'none');
                    $('#loginDiv').css('display', 'inline');
                    $('#loginFailedDiv').css('display', 'none');
                },
                url: 'https://api.particle.io/v1/access_tokens/current',
            });
        });
        $('#myINC').on('click', function (e) {
            e.preventDefault();
            myIncrement('INC');
        });

        if (sessionStorage.particleToken) {
            // We have a Particle access token in the session storage. Probably
            // refreshed the page, so try to use it. You don't need to log in
            // every time, you can reuse the access token if it has not expired.
            $('#loginDiv').css('display', 'none');
            getDevices();
        }
    });

    function loginSuccess(token) {
        sessionStorage.particleToken = token;
        getDevices();
    }

    function getDevices() {
        // Request the device list from the cloud
        particle.listDevices({ auth: sessionStorage.particleToken }).then(
            function (data) {
                // Success! Show the main page
                $('#mainDiv').css('display', 'inline');

                // Load the device selector popup
                loadDeviceList(data.body);
            },
            function (err) {
                // Failed to retrieve the device list. The token may have expired
                // so prompt for login again.
                $('#mainDiv').css('display', 'none');
                $('#loginDiv').css('display', 'inline');
                $('#loginFailedDiv').css('display', 'inline');
            }
        );
    }

    function loadDeviceList(deviceList) {
        let html = '';

        $('#userSpan').text(sessionStorage.particleUser);

        deviceList.forEach(function (dev) {
            // For each device in the user's account, see if the device supports the "led" function call
            // Also note whether it's online or not.
            if (dev.functions.includes('IoT')) {
                html += '<option value="' + dev.id + '">' + dev.name + (dev.online ? '' : ' (offline)') + '</option>';
            }
        });
        $('#deviceSelect').html(html);

        if (html == '') {
            $('#statusSpan').text('No device are running led control firmware');
        }
        else {
            $('#statusSpan').text('');
        }
    }

    function myIncrement(cmd) {
        // Used to turn on or off the LED by using the Particle.function "led"
        const deviceId = $('#deviceSelect').val();

        $('#statusSpan').text('');

        particle.callFunction({ deviceId, name: 'IoT', argument: cmd, auth: sessionStorage.particleToken }).then(
            function (data) {
                $('#statusSpan').text('Call completed');
            },
            function (err) {
                $('#statusSpan').text('Error calling device: ' + err);
            }
        );
        particle.getVariable({ deviceId, name: 'IoT', auth: token }).then(function(data) {
            $('#statusSpan').text('data: ' + data);
        }, function(err) {
            $('#statusSpan').text('error',err);
        });
    }
</script>
<body>
    <div id="mainDiv" style="display: none;">
        <h3>increment variable!</h3>
        <form>
            <p>Device: <select id="deviceSelect"></select></p>
            <p><button id="myINC">increment variable</button></p>
            <p>&nbsp;</p>
            <p><span id="statusSpan"></span></p>
            <p>&nbsp;</p>
            <p>Logged in as <span id="userSpan"></span> <button id="logoutButton">Log out</button></p>
        </form>
    </div>
    <div id="loginDiv">
        <h3>Login to Particle</h3>
        <div id="loginFailedDiv" style="display: none;">
            <p>Login failed, please try again.</p>
        </div>
        <form id="loginForm">
            <p>Username (Email): <input type="text" id="userInput" /></p>
            <p>Password: <input type="password" id="passwordInput" /></p>
            <p><input type="submit" value="Login" /></p>
        </form>
    </div>
    <div id="otpDiv" style="display: none;">
        <form id="otpForm">
            <p>One-time password from your authenticator app: <input type="text" id="otpInput" /></p>
            <p><input type="submit" value="Login" /></p>
        </form>
    </div>
</body>

Since your function returns the count, it’s not necessary to get the count again, which will save a data operation.

However, the reason why your code doesn’t work is probably that callFunction is asynchronous. You’re doing the callFunction and getVariable at the same time, and it’s possible that the get is occurring before the call completes. If you want to do both steps, you need to move the getVariable inside the block right after ‘Call completed!’ so the function will complete first.

Also you probably don’t need to read the count every 500 milliseconds. You can just read it once in setup() because it will be updated whenever it is incremented.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.