fw param export pop-up
parent
e8a410f217
commit
a7cd5e7767
|
@ -5,11 +5,13 @@ import {
|
|||
TaggedTool, TaggedUser, TaggedWebcamFeed,
|
||||
TaggedPlantPointer, TaggedGenericPointer, TaggedPeripheral, TaggedFbosConfig,
|
||||
TaggedWebAppConfig,
|
||||
TaggedSensor
|
||||
TaggedSensor,
|
||||
TaggedFirmwareConfig
|
||||
} from "../../resources/tagged_resources";
|
||||
import { ExecutableType } from "../../farm_designer/interfaces";
|
||||
import { fakeResource } from "../fake_resource";
|
||||
import { emptyToolSlot } from "../../tools/components/empty_tool_slot";
|
||||
import { FirmwareConfig } from "../../config_storage/firmware_configs";
|
||||
|
||||
export let resources: Everything["resources"] = buildResourceIndex();
|
||||
let idCounter = 1;
|
||||
|
@ -201,3 +203,101 @@ export function fakeWebAppConfig(): TaggedWebAppConfig {
|
|||
discard_unsaved: false
|
||||
});
|
||||
}
|
||||
|
||||
export function fakeFirmwareConfig(): TaggedFirmwareConfig {
|
||||
return fakeResource("FirmwareConfig", {
|
||||
device_id: 1,
|
||||
created_at: "",
|
||||
updated_at: "",
|
||||
encoder_enabled_x: 0,
|
||||
encoder_enabled_y: 0,
|
||||
encoder_enabled_z: 0,
|
||||
encoder_invert_x: 0,
|
||||
encoder_invert_y: 0,
|
||||
encoder_invert_z: 0,
|
||||
encoder_missed_steps_decay_x: 5,
|
||||
encoder_missed_steps_decay_y: 5,
|
||||
encoder_missed_steps_decay_z: 5,
|
||||
encoder_missed_steps_max_x: 5,
|
||||
encoder_missed_steps_max_y: 5,
|
||||
encoder_missed_steps_max_z: 5,
|
||||
encoder_scaling_x: 56,
|
||||
encoder_scaling_y: 56,
|
||||
encoder_scaling_z: 56,
|
||||
encoder_type_x: 0,
|
||||
encoder_type_y: 0,
|
||||
encoder_type_z: 0,
|
||||
encoder_use_for_pos_x: 0,
|
||||
encoder_use_for_pos_y: 0,
|
||||
encoder_use_for_pos_z: 0,
|
||||
movement_axis_nr_steps_x: 0,
|
||||
movement_axis_nr_steps_y: 0,
|
||||
movement_axis_nr_steps_z: 0,
|
||||
movement_enable_endpoints_x: 0,
|
||||
movement_enable_endpoints_y: 0,
|
||||
movement_enable_endpoints_z: 0,
|
||||
movement_home_at_boot_x: 0,
|
||||
movement_home_at_boot_y: 0,
|
||||
movement_home_at_boot_z: 0,
|
||||
movement_home_spd_x: 50,
|
||||
movement_home_spd_y: 50,
|
||||
movement_home_spd_z: 50,
|
||||
movement_home_up_x: 0,
|
||||
movement_home_up_y: 0,
|
||||
movement_home_up_z: 1,
|
||||
movement_invert_endpoints_x: 0,
|
||||
movement_invert_endpoints_y: 0,
|
||||
movement_invert_endpoints_z: 0,
|
||||
movement_invert_motor_x: 0,
|
||||
movement_invert_motor_y: 0,
|
||||
movement_invert_motor_z: 0,
|
||||
movement_keep_active_x: 0,
|
||||
movement_keep_active_y: 0,
|
||||
movement_keep_active_z: 1,
|
||||
movement_max_spd_x: 400,
|
||||
movement_max_spd_y: 400,
|
||||
movement_max_spd_z: 400,
|
||||
movement_min_spd_x: 50,
|
||||
movement_min_spd_y: 50,
|
||||
movement_min_spd_z: 50,
|
||||
movement_secondary_motor_invert_x: 1,
|
||||
movement_secondary_motor_x: 1,
|
||||
movement_step_per_mm_x: 5,
|
||||
movement_step_per_mm_y: 5,
|
||||
movement_step_per_mm_z: 25,
|
||||
movement_steps_acc_dec_x: 300,
|
||||
movement_steps_acc_dec_y: 300,
|
||||
movement_steps_acc_dec_z: 300,
|
||||
movement_stop_at_home_x: 0,
|
||||
movement_stop_at_home_y: 0,
|
||||
movement_stop_at_home_z: 0,
|
||||
movement_stop_at_max_x: 0,
|
||||
movement_stop_at_max_y: 0,
|
||||
movement_stop_at_max_z: 0,
|
||||
movement_timeout_x: 120,
|
||||
movement_timeout_y: 120,
|
||||
movement_timeout_z: 120,
|
||||
param_config_ok: 0,
|
||||
param_e_stop_on_mov_err: 0,
|
||||
param_mov_nr_retry: 3,
|
||||
param_test: 0,
|
||||
param_use_eeprom: 1,
|
||||
param_version: 1,
|
||||
pin_guard_1_active_state: 1,
|
||||
pin_guard_1_pin_nr: 0,
|
||||
pin_guard_1_time_out: 60,
|
||||
pin_guard_2_active_state: 1,
|
||||
pin_guard_2_pin_nr: 0,
|
||||
pin_guard_2_time_out: 60,
|
||||
pin_guard_3_active_state: 1,
|
||||
pin_guard_3_pin_nr: 0,
|
||||
pin_guard_3_time_out: 60,
|
||||
pin_guard_4_active_state: 1,
|
||||
pin_guard_4_pin_nr: 0,
|
||||
pin_guard_4_time_out: 60,
|
||||
pin_guard_5_active_state: 1,
|
||||
pin_guard_5_pin_nr: 0,
|
||||
pin_guard_5_time_out: 60,
|
||||
api_migrated: false
|
||||
} as FirmwareConfig);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,8 @@ export class API {
|
|||
get webAppConfigPath() { return `${this.baseUrl}/api/web_app_config/`; }
|
||||
/** /api/fbos_config */
|
||||
get fbosConfigPath() { return `${this.baseUrl}/api/fbos_config/`; }
|
||||
/** /api/firmware_config */
|
||||
get firmwareConfigPath() { return `${this.baseUrl}/api/firmware_config/`; }
|
||||
/** /api/sensor_readings */
|
||||
get sensorReadingPath() { return `${this.baseUrl}/api/sensor_readings`; }
|
||||
/** /api/sensor_readings */
|
||||
|
|
|
@ -219,7 +219,8 @@ export function urlFor(tag: ResourceName) {
|
|||
Log: API.current.logsPath,
|
||||
WebcamFeed: API.current.webcamFeedPath,
|
||||
FbosConfig: API.current.fbosConfigPath,
|
||||
WebAppConfig: API.current.webAppConfigPath
|
||||
WebAppConfig: API.current.webAppConfigPath,
|
||||
FirmwareConfig: API.current.firmwareConfigPath,
|
||||
};
|
||||
const url = OPTIONS[tag];
|
||||
if (url) {
|
||||
|
@ -230,7 +231,8 @@ export function urlFor(tag: ResourceName) {
|
|||
}
|
||||
}
|
||||
|
||||
const SINGULAR_RESOURCE: ResourceName[] = ["WebAppConfig", "FbosConfig"];
|
||||
const SINGULAR_RESOURCE: ResourceName[] =
|
||||
["WebAppConfig", "FbosConfig", "FirmwareConfig"];
|
||||
|
||||
/** Shared functionality in create() and update(). */
|
||||
function updateViaAjax(payl: AjaxUpdatePayload) {
|
||||
|
|
|
@ -228,6 +228,20 @@ a {
|
|||
text-align: center;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.fa-download {
|
||||
margin-top: -20px;
|
||||
float: right;
|
||||
color: $dark_gray !important;
|
||||
}
|
||||
}
|
||||
|
||||
.firmware-setting-export-menu {
|
||||
button {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
ul {
|
||||
font-size: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.change-ownership-form {
|
||||
|
|
|
@ -25,7 +25,8 @@ describe("<Devices/>", () => {
|
|||
dispatch: jest.fn(),
|
||||
resources: buildResourceIndex(FAKE_RESOURCES).index,
|
||||
sourceFbosConfig: jest.fn(),
|
||||
shouldDisplay: jest.fn()
|
||||
shouldDisplay: jest.fn(),
|
||||
firmwareConfig: undefined,
|
||||
});
|
||||
|
||||
it("renders relevant panels", () => {
|
||||
|
|
|
@ -5,6 +5,7 @@ const mockImages: TaggedImage | undefined = fakeImage();
|
|||
|
||||
jest.mock("../../resources/selectors_by_kind", () => ({
|
||||
getFbosConfig: () => mockFbosConfig,
|
||||
getFirmwareConfig: () => undefined,
|
||||
selectAllImages: () => [mockImages],
|
||||
}));
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import * as React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import { HardwareSettings } from "../hardware_settings";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import { HardwareSettings, FwParamExportMenu } from "../hardware_settings";
|
||||
import { HardwareSettingsProps } from "../../interfaces";
|
||||
import { Actions } from "../../../constants";
|
||||
import { bot } from "../../../__test_support__/fake_state/bot";
|
||||
import { panelState } from "../../../__test_support__/control_panel_state";
|
||||
import { fakeFirmwareConfig } from "../../../__test_support__/fake_state/resources";
|
||||
|
||||
describe("<HardwareSettings />", () => {
|
||||
beforeEach(() => {
|
||||
|
@ -19,12 +20,13 @@ describe("<HardwareSettings />", () => {
|
|||
dispatch: jest.fn(),
|
||||
sourceFbosConfig: (x) => {
|
||||
return { value: bot.hardware.configuration[x], consistent: true };
|
||||
}
|
||||
},
|
||||
firmwareConfig: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
it("renders", () => {
|
||||
const wrapper = mount(<HardwareSettings {...fakeProps() } />);
|
||||
const wrapper = mount(<HardwareSettings {...fakeProps()} />);
|
||||
["expand all", "x axis", "motors"].map(string =>
|
||||
expect(wrapper.text().toLowerCase()).toContain(string));
|
||||
});
|
||||
|
@ -57,4 +59,25 @@ describe("<HardwareSettings />", () => {
|
|||
checkDispatch("h4", 1, "motors",
|
||||
Actions.TOGGLE_CONTROL_PANEL_OPTION, "motors");
|
||||
});
|
||||
|
||||
it("shows param export menu", () => {
|
||||
const p = fakeProps();
|
||||
p.firmwareConfig = fakeFirmwareConfig().body;
|
||||
p.firmwareConfig.api_migrated = true;
|
||||
const wrapper = shallow(<HardwareSettings {...p} />);
|
||||
expect(wrapper.find("Popover").length).toEqual(1);
|
||||
});
|
||||
|
||||
it("doesn't show param export menu", () => {
|
||||
const wrapper = shallow(<HardwareSettings {...fakeProps()} />);
|
||||
expect(wrapper.find("Popover").length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("<FwParamExportMenu />", () => {
|
||||
it("lists all params", () => {
|
||||
const config = fakeFirmwareConfig().body;
|
||||
const wrapper = mount(<FwParamExportMenu firmwareConfig={config} />);
|
||||
expect(wrapper.text()).toContain("movement_max_spd_");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,6 +14,22 @@ import {
|
|||
HomingAndCalibration
|
||||
} from "./hardware_settings/homing_and_calibration";
|
||||
import { SpecialStatus } from "../../resources/tagged_resources";
|
||||
import { Popover, Position } from "@blueprintjs/core";
|
||||
import { FirmwareConfig } from "../../config_storage/firmware_configs";
|
||||
import { pickBy } from "lodash";
|
||||
|
||||
export const FwParamExportMenu = (props: { firmwareConfig: FirmwareConfig }) => {
|
||||
const filteredConfig = pickBy(props.firmwareConfig, (value, key) =>
|
||||
!["id", "device_id", "api_migrated", "created_at", "updated_at",
|
||||
"param_test", "param_version"]
|
||||
.includes(key));
|
||||
return <div className={"firmware-setting-export-menu"}>
|
||||
<ul>
|
||||
{Object.entries(filteredConfig).map(([param, value]) =>
|
||||
<li key={param}>{param}: {value}</li>)}
|
||||
</ul>
|
||||
</div>;
|
||||
};
|
||||
|
||||
export class HardwareSettings extends
|
||||
React.Component<HardwareSettingsProps, {}> {
|
||||
|
@ -41,12 +57,17 @@ export class HardwareSettings extends
|
|||
className={"fb-button gray no-float"}
|
||||
onClick={() => dispatch(bulkToggleControlPanel(true))}>
|
||||
{t("Expand All")}
|
||||
</button>
|
||||
</button>
|
||||
<button
|
||||
className={"fb-button gray no-float"}
|
||||
onClick={() => dispatch(bulkToggleControlPanel(false))}>
|
||||
{t("Collapse All")}
|
||||
</button>
|
||||
</button>
|
||||
{this.props.firmwareConfig &&
|
||||
<Popover position={Position.BOTTOM_RIGHT}>
|
||||
<i className="fa fa-download" />
|
||||
<FwParamExportMenu firmwareConfig={this.props.firmwareConfig} />
|
||||
</Popover>}
|
||||
<MustBeOnline
|
||||
networkState={this.props.botToMqttStatus}
|
||||
syncStatus={sync_status}
|
||||
|
|
|
@ -85,7 +85,8 @@ export class Devices extends React.Component<Props, {}> {
|
|||
dispatch={this.props.dispatch}
|
||||
bot={this.props.bot}
|
||||
botToMqttStatus={botToMqttStatus}
|
||||
sourceFbosConfig={this.props.sourceFbosConfig} />
|
||||
sourceFbosConfig={this.props.sourceFbosConfig}
|
||||
firmwareConfig={this.props.firmwareConfig} />
|
||||
{this.props.bot.hardware.gpio_registry &&
|
||||
<PinBindings
|
||||
dispatch={this.props.dispatch}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { WD_ENV } from "../farmware/weed_detector/remote_env/interfaces";
|
|||
import { ConnectionStatus, ConnectionState, NetworkState } from "../connectivity/interfaces";
|
||||
import { IntegerSize } from "../util";
|
||||
import { WebAppConfig } from "../config_storage/web_app_configs";
|
||||
import { FirmwareConfig } from "../config_storage/firmware_configs";
|
||||
|
||||
export interface Props {
|
||||
userToApi: ConnectionStatus | undefined;
|
||||
|
@ -31,6 +32,7 @@ export interface Props {
|
|||
resources: ResourceIndex;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
shouldDisplay: ShouldDisplay;
|
||||
firmwareConfig: FirmwareConfig | undefined;
|
||||
}
|
||||
|
||||
export type SourceFbosConfig = (config: ConfigurationName) =>
|
||||
|
@ -190,6 +192,7 @@ export interface HardwareSettingsProps {
|
|||
botToMqttStatus: NetworkState;
|
||||
bot: BotState;
|
||||
sourceFbosConfig: SourceFbosConfig;
|
||||
firmwareConfig: FirmwareConfig | undefined;
|
||||
}
|
||||
|
||||
export interface ControlPanelState {
|
||||
|
|
|
@ -3,17 +3,23 @@ import { Props } from "./interfaces";
|
|||
import {
|
||||
selectAllImages,
|
||||
getDeviceAccountSettings,
|
||||
maybeGetDevice
|
||||
maybeGetDevice,
|
||||
getFirmwareConfig
|
||||
} from "../resources/selectors";
|
||||
import { sourceFbosConfigValue } from "./components/source_fbos_config_value";
|
||||
import { getFbosConfig } from "../resources/selectors_by_kind";
|
||||
import { determineInstalledOsVersion, shouldDisplay } from "../util";
|
||||
|
||||
export function mapStateToProps(props: Everything): Props {
|
||||
const conf = getFbosConfig(props.resources.index);
|
||||
const { hardware } = props.bot;
|
||||
const fbosConfig = (conf && conf.body && conf.body.api_migrated)
|
||||
? conf.body : undefined;
|
||||
const maybeFbosConfig = getFbosConfig(props.resources.index);
|
||||
const fbosConfig = maybeFbosConfig && maybeFbosConfig.body.api_migrated
|
||||
? maybeFbosConfig.body
|
||||
: undefined;
|
||||
const maybeFirmwareConfig = getFirmwareConfig(props.resources.index);
|
||||
const firmwareConfig = maybeFirmwareConfig && maybeFirmwareConfig.body.api_migrated
|
||||
? maybeFirmwareConfig.body
|
||||
: undefined;
|
||||
const installedOsVersion = determineInstalledOsVersion(
|
||||
props.bot, maybeGetDevice(props.resources.index));
|
||||
return {
|
||||
|
@ -28,5 +34,6 @@ export function mapStateToProps(props: Everything): Props {
|
|||
resources: props.resources.index,
|
||||
sourceFbosConfig: sourceFbosConfigValue(fbosConfig, hardware.configuration),
|
||||
shouldDisplay: shouldDisplay(installedOsVersion, props.bot.minOsFeatureData),
|
||||
firmwareConfig,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
TaggedSensor,
|
||||
TaggedPeripheral,
|
||||
TaggedWebAppConfig,
|
||||
TaggedFirmwareConfig,
|
||||
} from "./tagged_resources";
|
||||
import { sortResourcesById } from "../util";
|
||||
import { error } from "farmbot-toastr";
|
||||
|
@ -76,9 +77,9 @@ export const selectAllWebcamFeeds =
|
|||
(i: ResourceIndex) => findAll<TaggedWebcamFeed>(i, "WebcamFeed");
|
||||
export const getAllSavedPeripherals =
|
||||
(input: ResourceIndex) => selectAllPeripherals(input).filter(isSaved);
|
||||
export const getFbosConfig =
|
||||
(i: ResourceIndex): TaggedFbosConfig | undefined => findAll<TaggedFbosConfig>(i, "FbosConfig")[0];
|
||||
|
||||
export const getWebAppConfig = (i: ResourceIndex): TaggedWebAppConfig | undefined => {
|
||||
return findAll<TaggedWebAppConfig>(i, "WebAppConfig")[0];
|
||||
};
|
||||
export const getFbosConfig = (i: ResourceIndex): TaggedFbosConfig | undefined =>
|
||||
findAll<TaggedFbosConfig>(i, "FbosConfig")[0];
|
||||
export const getWebAppConfig = (i: ResourceIndex): TaggedWebAppConfig | undefined =>
|
||||
findAll<TaggedWebAppConfig>(i, "WebAppConfig")[0];
|
||||
export const getFirmwareConfig = (i: ResourceIndex): TaggedFirmwareConfig | undefined =>
|
||||
findAll<TaggedFirmwareConfig>(i, "FirmwareConfig")[0];
|
||||
|
|
|
@ -16,6 +16,7 @@ import { WebAppConfig } from "../config_storage/web_app_configs";
|
|||
import { Session } from "../session";
|
||||
import { FbosConfig } from "../config_storage/fbos_configs";
|
||||
import { FarmwareInstallation } from "../farmware/interfaces";
|
||||
import { FirmwareConfig } from "../config_storage/firmware_configs";
|
||||
|
||||
export interface ResourceReadyPayl {
|
||||
name: ResourceName;
|
||||
|
@ -44,6 +45,7 @@ export function fetchSyncData(dispatch: Function) {
|
|||
fetch<WebcamFeed>("WebcamFeed", API.current.webcamFeedPath);
|
||||
fetch<FbosConfig>("FbosConfig", API.current.fbosConfigPath);
|
||||
fetch<WebAppConfig>("WebAppConfig", API.current.webAppConfigPath);
|
||||
fetch<FirmwareConfig>("FirmwareConfig", API.current.firmwareConfigPath);
|
||||
fetch<FarmEvent[]>("FarmEvent", API.current.farmEventsPath);
|
||||
fetch<Image[]>("Image", API.current.imagesPath);
|
||||
fetch<Log[]>("Log", API.current.logsPath);
|
||||
|
|
Loading…
Reference in New Issue