Farmbot-Web-App/frontend/farmware/weed_detector/remote_env/constants.ts

109 lines
3.6 KiB
TypeScript

import { box } from "boxed_value";
import { WDENVKey, Translation, FormatTranslationMap } from "./interfaces";
import { snakeCase, get, isUndefined } from "lodash";
/** I would rather not deal with all the weird edge cases that come with
* supporting strings and numbers right now. It adds too many edge cases for the
* FE to validate against. Example: Needing to conditionally determine if an ENV
* key is string vs. number vs. bool. Using only numbers (and translating values
* when transmitting) allows us to minimize the use of such conditionals.
* When we need to support text that users will read, I can re-visit this. */
export enum SPECIAL_VALUES {
FALSE = 0,
TRUE = 1,
TOP_LEFT = 2,
TOP_RIGHT = 3,
BOTTOM_LEFT = 4,
BOTTOM_RIGHT = 5,
X = 6,
Y = 7
}
/** Sometimes, ENV var values are not available but rendering must still be
* performed. This map provides a set of defaults for every ENV var. */
export const WD_KEY_DEFAULTS = {
CAMERA_CALIBRATION_calibration_along_axis: SPECIAL_VALUES.X,
CAMERA_CALIBRATION_image_bot_origin_location: SPECIAL_VALUES.BOTTOM_LEFT,
CAMERA_CALIBRATION_invert_hue_selection: SPECIAL_VALUES.TRUE,
CAMERA_CALIBRATION_blur: 5,
CAMERA_CALIBRATION_calibration_object_separation: 100,
CAMERA_CALIBRATION_camera_offset_x: 50,
CAMERA_CALIBRATION_camera_offset_y: 100,
CAMERA_CALIBRATION_coord_scale: 0,
CAMERA_CALIBRATION_H_HI: 160,
CAMERA_CALIBRATION_H_LO: 20,
CAMERA_CALIBRATION_iteration: 1,
CAMERA_CALIBRATION_morph: 5,
CAMERA_CALIBRATION_S_HI: 255,
CAMERA_CALIBRATION_S_LO: 100,
CAMERA_CALIBRATION_total_rotation_angle: 0,
CAMERA_CALIBRATION_V_HI: 255,
CAMERA_CALIBRATION_V_LO: 100,
WEED_DETECTOR_blur: 15,
WEED_DETECTOR_H_HI: 90,
WEED_DETECTOR_H_LO: 30,
WEED_DETECTOR_iteration: 4,
WEED_DETECTOR_morph: 6,
WEED_DETECTOR_S_HI: 255,
WEED_DETECTOR_S_LO: 50,
WEED_DETECTOR_V_HI: 255,
WEED_DETECTOR_V_LO: 50,
};
/** The runtime equivalent for WeedDetectorENVKey.
* Good for iterating and whatnot. */
export const EVERY_WD_KEY: WDENVKey[] =
Object.keys(WD_KEY_DEFAULTS).map((x: WDENVKey) => x);
export const DEFAULT_FORMATTER: Translation = {
format: (key, val): number | string => {
switch (key) {
case "CAMERA_CALIBRATION_calibration_along_axis":
case "CAMERA_CALIBRATION_image_bot_origin_location":
case "CAMERA_CALIBRATION_invert_hue_selection":
return ("" + (SPECIAL_VALUES[val] || val));
default:
return val;
}
},
parse: (__, val) => {
try {
const b = box(JSON.parse(val));
switch (b.kind) {
case "number":
return b.value;
case "boolean":
case "string":
return getSpecialValue(val);
default:
throw new Error("BAD DATA TYPE");
}
} catch (error) {
throw new Error(`An input from FarmWare caused a crash.
This is the value we got: ${val}
This is the error: ${error}
`);
}
}
};
/** If we hit any "special cases", we can register them here. */
export const TRANSLATORS: FormatTranslationMap = {};
/** We only expect certain string values from the weed detector.
* Tokens like "BOTTOM_RIGHT" or "X" all have a numeric counterpart.
* This function converts such strings to their numeric equivalent.
* If a matching numeric code is not found, throws an exception.
*/
export function getSpecialValue(key: string | number):
SPECIAL_VALUES {
const k = snakeCase(("" + key).toUpperCase()).toUpperCase();
const v = get(SPECIAL_VALUES, k, NaN);
if (isUndefined(v) || isNaN(v)) {
throw new Error("Not a SPECIAL_VALUE: " + k);
} else {
return v;
}
}