Javascript 功能未按时运行

Javascript 功能未按时运行,javascript,node.js,raspberry-pi3,raspbian,xtuple,Javascript,Node.js,Raspberry Pi3,Raspbian,Xtuple,我试图通过在将连接到大型监视器的raspberry pi上运行nodejs应用程序来创建度量仪表板 应用程序每小时查询一次SQL server。当我在mac上运行它时,效果非常好,但当我在raspberry上运行它时,它似乎运行了一两次,然后停止。我已经在覆盆子上禁用了屏幕保护程序,但我不知道如何调试它。我将包含完整的代码,因为我不确定是tick()函数本身还是其他什么 "use strict"; var fs = require('fs'); var readline = require('

我试图通过在将连接到大型监视器的raspberry pi上运行nodejs应用程序来创建度量仪表板

应用程序每小时查询一次SQL server。当我在mac上运行它时,效果非常好,但当我在raspberry上运行它时,它似乎运行了一两次,然后停止。我已经在覆盆子上禁用了屏幕保护程序,但我不知道如何调试它。我将包含完整的代码,因为我不确定是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);
}
“严格使用”;
var fs=需要('fs');
var readline=require('readline');
var google=require('googleapis');
var googleAuth=require('google-auth-library');
var pg=需要(“pg”);
常量配置={
用户:“”,
数据库:“”,
密码:“”,
主机:“”,
港口:5432,
最高:10,
idleTimeoutMillis:5000,
};
const pool=新的pg.pool(配置);
常量电子表格ID=“”;//履行KPI
//如果修改这些作用域,请删除以前保存的凭据
//位于~/.credentials/sheets.googleapis.com-nodejs-quickstart.json
常量作用域=['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';
//从本地文件加载客户端机密。
fs.readFile('secret.json',函数processClientSecrets(err,content){
如果(错误){
log('加载客户端机密文件时出错:'+err);
返回;
}
//使用加载的凭据授权客户端,然后调用
//GoogleSheetsAPI。

授权(JSON.parse(content),begin);//你的tick函数有点复杂。问题可能出在tick函数中。我只想简单地说一下。只需在一个间隔计时器上运行更新,看看它是否有效,比如说一分钟。如果有效,那么问题可能出在你的计时和pi时钟上。如果你不能调试它,可能是代码在它首先抓取,并且勾号永远不会被调用。尝试在更新中捕获异常。或者删除勾号函数工作并调用更新的所有代码测试,然后在更新中只需在PI上闪烁屏幕。这将帮助您缩小问题所在的范围。谢谢,我将尝试一下。勾号函数是必要的,但也许我可以简化正如您所建议的。滴答函数之所以要在下午1:00、下午2:00、下午3:00等时间运行。如果我按原样使用setInterval,并且在下午12:13启动脚本,那么它直到下午1:13才运行,这对我来说是不起作用的。我建议您只是为了测试/查找出现此错误的原因。如果工作人员说,每隔30秒,你就会知道这是你的勾号函数中的代码。我相信我已经找到了导致这一点的原因。我注意到,当我在办公桌旁或在脚本运行时让计算机保持运行时,一切都很好。它发生故障或偏移的时间是在我的计算机进入睡眠状态时。超时会暂停,并在我把机器弄醒。