Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing serial terminal with menu #336

Merged
merged 4 commits into from
Oct 12, 2023
Merged

Replacing serial terminal with menu #336

merged 4 commits into from
Oct 12, 2023

Conversation

ryan-summers
Copy link
Member

@ryan-summers ryan-summers commented Oct 11, 2023

This PR refactors the serial port menu to use menu, which implements a lot of the things we want without having to maintain them here.

Ultimately, it may be nice to abstract the various concepts here to make this menu usable in Stabilizer as well and reduce some of the redundant code.

PS C:\Users\rsummers> python -m serial COM14
--- Miniterm on COM14  9600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
> help
AVAILABLE ITEMS:
  reset
  dfu
  service
  read [ <property> ]
  write <property> <value>
  help [ <command> ]

> help read
SUMMARY:
  read [ <property> ]

PARAMETERS:
  <property>
    The name of the property to read. If not specified, all properties are read



DESCRIPTION:
Read a property from the device:

Available Properties:
* id: The MQTT ID of the device
* mac: The MAC address of the device
* broker: The MQTT broker IP address
* gateway: The internet gateway address (Unused when DHCP is enabled)
* ip: The static IP address of Booster (0.0.0.0 indicates DHCP usage)
* netmask: The netmask to use when DHCP is disabled
* fan_speed: The duty cycle of fans when channels are enabled

> help write
SUMMARY:
  write <property> <value>

PARAMETERS:
  <property>
    The name of the property to write: [broker, gateway, ip, netmask, id, fan_speed]

  <value>
    Specifies the value to be written to the property. The format of the value depends on the property to be written.



DESCRIPTION:
Updates the value of a property on the device.

Notes:
* Netmasks must contain only leading data. E.g. 255.255.0.0
* Fan speeds specify the default fan speed duty cycle, and is specified as [0, 1.0]
* MQTT client IDs must be 23 or less ASCII characters.

Examples:
    # Use DHCP for IP address allocation
    write ip "0.0.0.0"

    # Set fans to 45% duty cycle
    write fan_speed 0.45

    # Update the Booster MQTT ID
    write id "my-booster-01"

> read
ip                  : "0.0.0.0"
netmask             : "254.0.0.0"
gateway             : "10.35.20.1"
broker              : "10.35.20.1"
fan_speed           : 0.0
id                  : "80-1f-12-66-60-1b"
mac                 : 80-1f-12-66-60-1b

>

@ryan-summers ryan-summers requested a review from jordens October 11, 2023 12:22
Copy link
Member

@jordens jordens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not (as suggested) use a miniconf tree for read/write?

The two issues I see have acceptable trade offs:

  • read-only mac: intercept seems doable
  • User needs to write json: "1.2.3.4" instead of 1.2.3.4

@ryan-summers
Copy link
Member Author

Miniconf would indeed simplify a lot of this! That would be a nice way to remove a lot of the redundancy. I'll take a stab at this

@ryan-summers
Copy link
Member Author

ryan-summers commented Oct 11, 2023

Why not (as suggested) use a miniconf tree for read/write?

The two issues I see have acceptable trade offs:

  • read-only mac: intercept seems doable
  • User needs to write json: "1.2.3.4" instead of 1.2.3.4

I've been playing around with it, and while it's indeed possible, there's a number of difficulties:

  1. Many of our property types do not implement Serialize/Deserialize (i.e. smoltcp::wire::IpCidr, smoltcp::wire::Ipv4Address)
  2. The underlying settings structure needs to still encode / decode to a bytes layer to get written to EEPROM, and we currently use encdec to do this, which is separate from serde

Thus, we could make a separate miniconf-enabled tree and then copy the contents into the struct that gets serialized to EEPROM later, but we still have to fight (1) above as well.

If we juse used i.e. raw byte arrays for the leaves of the tree, the user would need to write write ip-address [1, 2, 3, 4], which seems bad. We could wrap our own types, but then there's a ton of glue code for converting types again, which also doesn't seem like a better solution.

I'm not opposed to refactoring this, but it would be a fair amount of thrash in the settings code.

@jordens
Copy link
Member

jordens commented Oct 11, 2023

Why does encdec conflict with serde here?

For ser/de on external structs we can use #[serde(with=...)]

@ryan-summers
Copy link
Member Author

I did some hacking and with a few wrapper types and support libs, I got around the most painful issues I mentioned above and am using Miniconf now.

@ryan-summers ryan-summers requested a review from jordens October 12, 2023 10:17
pub gateway: IpAddr,
pub broker: IpAddr,
pub fan_speed: f32,
pub id: String<23>,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a separate struct from BoosterMainBoardData so that we can hide away implementation details from miniconf (like the fact we have an id_len u32 and id is actually an array of bytes, etc.

Copy link
Member

@jordens jordens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.
I thought that there should be a way to make BoosterMainBoardData and Properties the same thing by impl Encode/Decode for IpAddrandString`, no?
But that can also become a later refactor.

@ryan-summers
Copy link
Member Author

We could combine them, but we would need a way to hide the semver version from miniconf as well. I'll defer this to the future for now as I suspect we may need to update miniconf to add new macro flags.

@ryan-summers ryan-summers added this pull request to the merge queue Oct 12, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Oct 12, 2023
@jordens
Copy link
Member

jordens commented Oct 12, 2023

Ah right. Might be easier to add a #[tree(skip)] to miniconf than to impl Serialize/Deserialize for everything and intercept.

quartiq/miniconf#182

@ryan-summers ryan-summers added this pull request to the merge queue Oct 12, 2023
Merged via the queue into main with commit a164204 Oct 12, 2023
5 checks passed
@ryan-summers ryan-summers deleted the feature/menu branch October 12, 2023 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants