64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
import { Farmbot } from "farmbot";
|
|
import { dispatchNetworkDown, dispatchNetworkUp } from "./index";
|
|
import { isNumber } from "lodash";
|
|
import axios from "axios";
|
|
import { API } from "../api/index";
|
|
import { timestamp } from "../util";
|
|
import { FarmBotInternalConfig } from "farmbot/dist/config";
|
|
|
|
export const PING_INTERVAL = 3000;
|
|
export const ACTIVE_THRESHOLD = PING_INTERVAL * 2;
|
|
|
|
const PING_LABEL = "ping";
|
|
export const LAST_IN: keyof FarmBotInternalConfig = "LAST_PING_IN";
|
|
export const LAST_OUT: keyof FarmBotInternalConfig = "LAST_PING_OUT";
|
|
export function buildPing(bot: Farmbot) {
|
|
const rpc = bot.rpcShim([]);
|
|
rpc.args.label = PING_LABEL;
|
|
return rpc;
|
|
}
|
|
|
|
type Direction = "in" | "out";
|
|
|
|
export function writePing(bot: Farmbot, direction: Direction) {
|
|
const dir = direction === "out" ? LAST_OUT : LAST_IN;
|
|
bot.setConfig(dir, timestamp());
|
|
}
|
|
|
|
export function readPing(bot: Farmbot, direction: Direction): number | undefined {
|
|
const val = bot.getConfig(direction === "out" ? LAST_OUT : LAST_IN);
|
|
return isNumber(val) ? val : undefined;
|
|
}
|
|
|
|
export function markStale() {
|
|
dispatchNetworkDown("bot.mqtt", undefined, "markStale()");
|
|
}
|
|
|
|
export function markActive() {
|
|
dispatchNetworkUp("user.mqtt", undefined, "markActive()");
|
|
dispatchNetworkUp("bot.mqtt", undefined, "markActive()");
|
|
}
|
|
|
|
export function isInactive(last: number, now: number): boolean {
|
|
return last ? (now - last) > ACTIVE_THRESHOLD : true;
|
|
}
|
|
|
|
export function sendOutboundPing(bot: Farmbot) {
|
|
bot.publish(buildPing(bot));
|
|
const now = timestamp();
|
|
const lastPing = readPing(bot, "in");
|
|
lastPing && (isInactive(lastPing, now) ? markStale() : markActive());
|
|
writePing(bot, "out");
|
|
}
|
|
|
|
export function startPinging(bot: Farmbot) {
|
|
setInterval(() => sendOutboundPing(bot), PING_INTERVAL);
|
|
bot.on(PING_LABEL, () => writePing(bot, "in"));
|
|
}
|
|
|
|
export function pingAPI() {
|
|
const ok = () => dispatchNetworkUp("user.api", undefined, "pingApi OK");
|
|
const no = () => dispatchNetworkDown("user.api", undefined, "pingApi NO");
|
|
axios.get(API.current.devicePath).then(ok, no);
|
|
}
|