Farmbot-Web-App/frontend/devices/pin_bindings/list_and_label_support.tsx

145 lines
4.5 KiB
TypeScript

import {
PinBindingType,
PinBindingSpecialAction,
} from "farmbot/dist/resources/api_resources";
import { DropDownItem } from "../../ui";
import { gpio } from "./rpi_gpio_diagram";
import { flattenDeep, isNumber } from "lodash";
import { sysBtnBindings } from "./tagged_pin_binding_init";
import { t } from "../../i18next_wrapper";
export const bindingTypeLabelLookup: { [x: string]: string } = {
[PinBindingType.standard]: t("Sequence"),
[PinBindingType.special]: t("Action"),
"": t("Sequence"),
};
export const bindingTypeList = (): DropDownItem[] =>
Object.entries(bindingTypeLabelLookup)
.filter(([value, _]) => !(value == ""))
.map(([value, label]) => ({ label, value }));
export const specialActionLabelLookup: { [x: string]: string } = {
[PinBindingSpecialAction.emergency_lock]: t("E-STOP"),
[PinBindingSpecialAction.emergency_unlock]: t("UNLOCK"),
[PinBindingSpecialAction.power_off]: t("Shutdown"),
[PinBindingSpecialAction.reboot]: t("Reboot"),
[PinBindingSpecialAction.sync]: t("Sync"),
[PinBindingSpecialAction.read_status]: t("Read Status"),
[PinBindingSpecialAction.take_photo]: t("Take Photo"),
"": t("None")
};
export const specialActionList: DropDownItem[] =
Object.values(PinBindingSpecialAction)
.map((action: PinBindingSpecialAction) =>
({ label: specialActionLabelLookup[action], value: action }));
export const getSpecialActionLabel =
(action: PinBindingSpecialAction | undefined) =>
specialActionLabelLookup[action || ""] || "";
/** Pin numbers for standard buttons. */
export enum ButtonPin {
estop = 16,
unlock = 22,
btn3 = 26,
btn4 = 5,
btn5 = 20,
}
/** Pin numbers used for LED control; cannot be used in a pin binding. */
enum LEDPin {
sync = 24,
connection = 25,
led3 = 12,
led4 = 13,
estop = 17,
unlock = 23,
btn3 = 27,
btn4 = 6,
btn5 = 21,
}
/** Other pins used by FarmBot OS that cannot be used in pin bindings. */
enum SystemPins {
i2c1_sda = 2,
i2c1_scl = 3,
spi0_ce1 = 7,
spi0_ce0 = 8,
spi0_miso = 9,
spi0_mosi = 10,
spi0_sclk = 11,
uart_tx = 14,
uart_rx = 15,
reset_2560 = 19,
}
const toPinNum = (n: string) => parseInt(n);
const sysLedBindings: number[] = Object.values(LEDPin).map(toPinNum);
const otherSysBindings: number[] = Object.values(SystemPins).map(toPinNum);
/** All pin numbers used by FarmBot OS that cannot be used in pin bindings. */
export const sysBindings = sysLedBindings.concat(sysBtnBindings, otherSysBindings);
const piI2c0Pins = [0, 1];
export const piSpi0Pins = [7, 8, 9, 10, 11];
export const piSpi1Pins = [16, 17, 18, 19, 20, 21];
/** Pin numbers used for special purposes by the RPi. (internal pullup, etc.) */
export const reservedPiGPIO = piI2c0Pins;
const GPIO_PIN_LABELS = (): { [x: number]: string } => ({
[ButtonPin.estop]: t("Button {{ num }}: E-STOP", { num: 1 }),
[ButtonPin.unlock]: t("Button {{ num }}: UNLOCK", { num: 2 }),
[ButtonPin.btn3]: t("Button {{ num }}", { num: 3 }),
[ButtonPin.btn4]: t("Button {{ num }}", { num: 4 }),
[ButtonPin.btn5]: t("Button {{ num }}", { num: 5 }),
});
export const generatePinLabel = (pin: number) =>
GPIO_PIN_LABELS()[pin]
? `${t(GPIO_PIN_LABELS()[pin])} (Pi ${pin})`
: `Pi GPIO ${pin}`;
/** Raspberry Pi GPIO pin numbers. */
export const validGpioPins: number[] =
flattenDeep(gpio)
.filter(x => isNumber(x))
.map((x: number) => x);
/** Sort fn for pin numbers using their labels. */
export const sortByNameAndPin = (a: number, b: number) => {
const aLabel = generatePinLabel(a).slice(0, 8);
const bLabel = generatePinLabel(b).slice(0, 8);
// Sort "Button 1", "Button 2", etc.
if (aLabel < bLabel) { return -1; }
if (aLabel > bLabel) { return 1; }
// Sort "GPIO Pi 4", "GPIO Pi 10", etc.
if (a < b) { return -1; }
if (a > b) { return 1; }
return 0;
};
/** Given a list of bound pins, return a list of available pins (DDIs). */
export const RpiPinList = (taken: number[]): DropDownItem[] =>
validGpioPins
.filter(n => !sysBindings.includes(n))
.filter(n => !taken.includes(n))
.filter(n => !reservedPiGPIO.includes(n))
.sort(sortByNameAndPin)
.map(n => ({ label: generatePinLabel(n), value: n }));
/** FarmBot OS default pin binding data used by Pin Bindings widget. */
export const stockPinBindings = [
{
pin_num: ButtonPin.estop,
special_action: PinBindingSpecialAction.emergency_lock,
binding_type: PinBindingType.special,
},
{
pin_num: ButtonPin.unlock,
special_action: PinBindingSpecialAction.emergency_unlock,
binding_type: PinBindingType.special,
},
];