The Soil Mate App

This is a reply to a question in the Dart API wrapper thread about the Soil Mate app. I wanted to separate it out to keep the other thread topic related.


There are several answers to this question:

Data Structures

The Soil Mate apps design will be such that it should be flexible enough to capture any type of soil data. Instead of reinventing the wheel, I thought I’d just use the same structure that is used in FarmOS (taxonomies/assets/logs) and matching keys. I think that if the AgTech industry is to move towards a future of cross-platform capabilities and integrations, we are going to need some sort of standards. The farmOS API seems like a good place to start. Plus it’s open-source, so it philosophically aligns.

At the moment, the app captures soil textures (clay, loam, sandy-loam, etc…) but we have a client who wants to add soil ground cover observations as well. I foresee that as the app continues to get uptake the demand for new features will increase and I want to make sure it scales (eg soil samples, soil attributes, weeds, etc…). The FarmOS taxonomy_terms is a really logical way to structure it. The vision is to update the taxonomy_term.json (saved in the app) file and the UI will automatically add an observation/survey type.

Saving data

We believe that farm data is precious and that the user should have full control over their data. The default method the export the data is to attach a .csv to an email (or app of your choosing); no server required.

These are, however, limitations to this; including:

  • not being able to change the device
  • not being able to share data between users
  • limitations on the size of the data (no hi-res images)

I want to give the user the option to add a FarmOS server by simply adding in the settings. Something like:

Sync with a FarmOS server

And as a bonus, they can use the FarmOS UI to manage their data.


I also have other projects that I plan to user FarmOS as the DB/data management system.


This is great! I’d be great if you connected with Will Gardiner and Dan TerAvest, they are working on a soil sampling app as well called SoilStack. It works with SurveyStack and doesn’t push directly to farmOS, but SurveyStack can so it’s a bit roundabout but there. Work is described here: ESMC Design and Soil Sampling App (&67) · Epics · our-sci · GitLab, repo is here: our-sci / software / Soil Client · GitLab.

I’d love to see if there’s points of collaboration or swap lessons.


Stated doing our models the FarmOS way. Should help us scale as we add more survey types:

@HiveType(typeId: 0)
class TaxonomyTerm {
  final int tid;
  final String name;
  final String description;
  final List<dynamic> parent; // TODO type these
  final List<dynamic> parents_all; // TODO type these

//  @HiveField(5)
//  final String url;
//  @HiveField(6)
//  final int node_count;
//  @HiveField(7)
//  final int weight;
//  @HiveField(8)
//  final List<Map<String, dynamic>> vocabulary;

  TaxonomyTerm({this.tid,, this.description, this.parent, this.parents_all});

  Map<String, dynamic> toMap(){
      "tid": tid,
      "name": name,
      "description": description,
      "parent": parent,
      "parents_all": parents_all


@HiveType(typeId: 1)
class GeoField{
  final double lat;
  final double lon;

  GeoField({, this.lon});

  Map<String, double> toMap(){
      "lat": lat,
      "lon": lon,


@HiveType(typeId: 2)
class Quantity{
  final String measure;
  final double value;
  final TaxonomyTerm units;
  final String label;

  Quantity({this.measure, this.value, this.units, this.label});

  Map<String, dynamic> toMap(){
      "measure": measure,
      "value": value,
      "units": units.toMap(),
      "label": label

@HiveType(typeId: 3)
class Log{
  int id;
  String name;
  String type; // "farm_soil_test"
  String timestamp;  // from taxonomies
  String notes;
  GeoField geofield;
  List<TaxonomyTerm> log_category;
  List<Quantity> quantity;// with keys lat lon

  Log({,, this.type, this.timestamp, this.notes, this.geofield, this.log_category, this.quantity});

  Map<String, dynamic> toMap(){
      "id": id,
      "name": name,
      "type": type,
      "timestamp": timestamp,
      "notes": notes,
      "geofield": geofield.toMap(),
      "log_category": => t.toMap()),
      "quantity": => e.toMap()),


The soil attribute measurements look like this:

Quantity clay = Quantity(measure: "value", value: 30.0, units: percentTaxonomy, label: "clay")
1 Like

That’s awesome @Kipling !

Just a heads up… there are a few changes in the farmOS 2.x data model that you should be aware of, looking ahead. Specifically “Areas” will be migrated into new types of Assets (Land, Structure, and Water assets), instead of being represented as taxonomy terms. Also, some field names are changing. For example geofield is becoming geometry (to make it less Drupal-specific).

A full list of changes (from the perspective of API consumers) is available here: Changes - farmOS 2.x Docs

1 Like

Oh also “Quantities” are their own entity type, which are referenced by Logs: Changes - farmOS 2.x Docs - So you technically need to create the Quantity first, then reference it from the Log. We’ve been brainstorming some ways to improve that process: Add support for subrequests · Issue #43 · farmOS/ · GitHub

Thanks for the heads up! I just created a TODO

I’ll try and make tomorrows meeting too.


For those interested in the Soil Mate app see here to download: Soil Mate

And the repo if you want to compile it yourself: soil_mate


Version 0.3.4 of the app has just been released. There may be some breaking changes so it might pay to uninstall the app before getting the updates Soil LogR

Changes include:

  • some minor UI fixes
  • better handling of location permissions (@mstenta it’s a not perfect UX but at least there is a workaround)
  • Adding images to logs
  • Ground cover survey
  • New name “Soil LogR”. Turns out “Soil Mate” is already trademarked (fml).

Future upcoming features include:

  • The ability to add custom survey types via a BYO taxonomy_terms.json which will auto-populate the input UI
  • the ability to sync with your FarmOS server by adding url, user and password in the settings.