功能未按时投放

时间:2017-03-24 17:33:12

标签: javascript node.js raspbian raspberry-pi3

我正在尝试通过在覆盆子pi上运行nodejs应用程序来创建度量仪表板,该应用程序将附加到大型监视器上。

应用程序每小时每小时查询一次SQL Server。当我在我的Mac上运行它时效果很好,但是当我在树莓上运行它时,它似乎运行一次或两次,然后停止。我已经在树莓上禁用了屏保,但我不知道如何调试它。我将包含完整的代码,因为我不确定它是tick()函数本身还是别的......

"use strict";

var fs = require('fs');
var readline = require('readline');
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var pg = require('pg');

const config = {
    user: '<redacted>',
    database: '<redacted>',
    password: '<redacted>',
    host: '<redacted>',
    port: 5432,
    max: 10,
    idleTimeoutMillis: 5000,
};

const pool = new pg.Pool(config);

const spreadsheetId = '<this my internal sheet>'; // fulfillment kpis

// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-nodejs-quickstart.json
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH ||
    process.env.USERPROFILE) + '/.credentials/';
const TOKEN_PATH = TOKEN_DIR + 'olr-test.json';

// Load client secrets from a local file.
fs.readFile('secret.json', function processClientSecrets(err, content) {
    if (err) {
        console.log('Error loading client secret file: ' + err);
        return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Google Sheets API.
    authorize(JSON.parse(content), begin); // <---- LOOK HERE...WHERE IT REALLY BEGINS...I THINK
});

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, callback) {
    var clientSecret = credentials.installed.client_secret;
    var clientId = credentials.installed.client_id;
    var redirectUrl = credentials.installed.redirect_uris[0];
    var auth = new googleAuth();
    var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

    // Check if we have previously stored a token.
    fs.readFile(TOKEN_PATH, function (err, token) {
        if (err) {
            getNewToken(oauth2Client, callback);
        } else {
            oauth2Client.credentials = JSON.parse(token);
            callback(oauth2Client);
        }
    });
}

/**
 * Get and store new token after prompting for user authorization, and then
 * execute the given callback with the authorized OAuth2 client.
 *
 * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for.
 * @param {getEventsCallback} callback The callback to call with the authorized
 *     client.
 */
function getNewToken(oauth2Client, callback) {
    var authUrl = oauth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES
    });
    console.log('Authorize this app by visiting this url: ', authUrl);
    var rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    rl.question('Enter the code from that page here: ', function (code) {
        rl.close();
        oauth2Client.getToken(code, function (err, token) {
            if (err) {
                console.log('Error while trying to retrieve access token', err);
                return;
            }
            oauth2Client.credentials = token;
            storeToken(token);
            callback(oauth2Client);
        });
    });
}

/**
 * Store token to disk be used in later program executions.
 *
 * @param {Object} token The token to store to disk.
 */
function storeToken(token) {
    try {
        fs.mkdirSync(TOKEN_DIR);
    } catch (err) {
        if (err.code != 'EEXIST') {
            throw err;
        }
    }
    fs.writeFile(TOKEN_PATH, JSON.stringify(token));
    console.log('Token stored to ' + TOKEN_PATH);
}

// Let's get the information out of xTuple now...
function begin(auth) {

    // Promise function to return results from SQL query passed as an argument
    function getResults(passedQuery) {
        return new Promise((resolve, reject) => {
            pool.connect((err, client, done) => {

                var sql = client.query(passedQuery);

                sql.on('row', (row, result) => {
                    result.addRow(row);
                });

                sql.on('end', (result) => {
                    var rightNow = timeStamp();
                    // console.log('Query finished at %s', rightNow);
                    resolve(result.rows);
                });

                done(err);

                if (err) {
                    return console.error('error running query', err);
                }
            });
        });
        pool.on('error', (err, client) => {
            console.error('idle client error', err.message, err.stack);
        });
    }

    function convertArray(sqlObj) {
        return new Promise((resolve, reject) => {
            var result = [];

            if (sqlObj.length > 0) {
                var order = Object.keys(sqlObj[0]);

                var result = sqlObj.map((row) => {
                    return order.map((col) => {
                        return row[col];
                    });
                });   
            }

            result[0].push(timeStamp());

            resolve(result);
        });
    }

    function appendSheet (value) {
        return new Promise((resolve, reject) => {
            var sheets = google.sheets('v4');

            var options = {
                auth: auth,
                spreadsheetId: spreadsheetId,
                range: "Sales ABPH!A1:B",
                valueInputOption: "USER_ENTERED",
                resource: {
                    range: "Sales ABPH!A1:B",
                    majorDimension: "ROWS",
                    values: value,
                }
            }


            // console.log(options);
            sheets.spreadsheets.values.append(options, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        });
    }

    function fixFormats(id) {
        return new Promise((resolve, reject) => {
            var sheets = google.sheets('v4');

            var options = {
                auth: auth,
                spreadsheetId: spreadsheetId,
                resource: {
                    requests: [{
                        repeatCell: {
                            fields: "userEnteredFormat.numberFormat",
                            range: {
                                sheetId: id,
                                startColumnIndex: 0, // inclusive
                                endColumnIndex: 1, // exclusive...meaning this counts UP TO column 4 but NOT 5
                            },
                            cell: {
                                userEnteredFormat: {
                                    numberFormat: {
                                        type: "CURRENCY",
                                        pattern: "\"$\"#,##0.00",
                                    }
                                }
                            }
                        }
                    }],
                }
            }

            sheets.spreadsheets.batchUpdate(options, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        });
    }

    function timeStamp() {
        var now = new Date();
        var date = [now.getMonth() + 1, now.getDate()];
        var time = [now.getHours(),now.getMinutes(),now.getSeconds()];
        var suffix = (time[0] < 12) ? "AM" : "PM";
        time[0] = (time[0] < 12) ? time[0] : time[0] - 12;
        time[0] = time[0] || 12;

        for (var i = 1; i < 3; i++) {
            if (time[i] < 10) {
                time[i] = "0" + time[i];
            }
        }
        return date.join("/") + " " + time.join(":") + " " + suffix;
    }

    function insertRow() {
        return new Promise((resolve, reject) => {
            var sheets = google.sheets('v4');

            var options = {
                auth: auth,
                spreadsheetId: spreadsheetId,
                resource: {
                    requests: [{
                        insertRange: {
                            range: {
                                sheetId: 1769404692,
                                startRowIndex: 1,
                                endRowIndex: 2,
                                startColumnIndex: 1,
                                endColumnIndex: 4
                            },
                            shiftDimension: "ROWS",
                        }
                    }],
                }
            }

            sheets.spreadsheets.batchUpdate(options, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        });
    }

    function update() {
        getResults(`
        select formatMoney(sum(qry.total)) as \"Booked\"
    FROM cohead c
        LEFT OUTER JOIN
        (SELECT coitem_cohead_id, SUM(coitem_qtyord*coitem_price) as total
        FROM coitem
        WHERE coitem_status NOT IN (\'X\')
        GROUP BY coitem_cohead_id) as qry
        ON (c.cohead_id=qry.coitem_cohead_id)
    WHERE (extract(DAY FROM c.cohead_orderdate) = extract(DAY from current_date) AND extract(MONTH from c.cohead_orderdate) = extract(MONTH from current_date) AND extract(YEAR from c.cohead_orderdate) = extract(YEAR from current_date))
        `)
            .then((sqlObj) => {
                insertRow();
                return convertArray(sqlObj);
            })
            .then((results) => {
                console.log(results);
                return appendSheet(results);
            })
            .then((fixMe) => {
                fixFormats('1769404692');
            })
            .catch((error) => {
                console.log('Something went wrong...\n%s', error);
            });

        tick();
    }

    function tick(force) {
        var d = new Date();
        var min = d.getMinutes();
        var sec = d.getSeconds();
        var hr = d.getHours();

        if (force || (min == '0' && sec == '0') && (hr >= 7 || hr <= 19))
            update();
        else
            setTimeout(update, (60 * (60 - min) + (60 - sec)) * 1000);    
    }

    tick(true);
}

我正在使用nodemon运行它来监视脚本文件中的更改,如果找到则重新启动。

我的预感是,覆盆子会以某种方式进入某种“睡眠”模式,但仍会输出视频。

编辑:我以为我在这里找到了一个解决方案:https://raspberrypi.stackexchange.com/questions/4773/raspberry-pi-sleep-mode-how-to-avoid/56046#56046

我已经为wlan0关闭了power_save(这是我用于LAN连接的)然后重新启动。同样的问题,但再次检查power_save选项看起来像是重新打开了。

我刚测试关闭它,重新启动,并立即再次检查它是否已重新启用。

编辑#2:确认如果我在wlan0上设置power_save并且不重启,它仍然不会在适当的超时运行循环。我等了30分钟才重新启动它并且运行正常,但这是因为tick()在第一次运行时被强制执行。

0 个答案:

没有答案