Suggestions on setting up ODK to handle site inspections

Hello, I’ve managed to set up a server with ODK and ran through the tutorial and successfully created a form. Now I’m trying to figure out how to make it work to meet my needs.

I have a large number of tower sites (150+) with over 50 assets at each tower site that need to be inspected. Each asset has the same data to be collected (manufacturer, model, serial #, physical condition, operational condition, photos, comments).

Ideally, the field inspectors would be able to open a form for a site and see a checklist of assets to inspect. They then click on an asset and a form takes them through the process of verify/rating it (same form is used for all assets). As they inspect those assets, the item is checked off on the list. Once all items are checked, they then have the ability to submit the form. I’m also hoping to use the API to extract the data from the forms to incorporate into my own database, but I’m ok with spreadsheets/csv files to transfer data.

I have an existing database of sites, their assets, and associated asset data that I would like to use to populate the project for the inspector to verify and rate (I can export the data to spreadsheets/csv)

I don’t need the inspectors to be able to create new assets since the engineers working in the database handle that part. As new assets get added, deleted, or updated, I need to be able to update what’s in the ODK app (spreadsheets fine)

Is something like this doable with ODK? If so, any thoughts and recommendations on how to start would be appreciated…

Well done with getting started and welcome to the forum.

I think you’ve come to a good place and probably a good time… If you can invest the time to learn about entities, they are very powerful for site inspection uses. Once you have your workflow mapped out, you should be able to generate an inspection form to collect your required data. You could then, for example, create an entity list for your tower sites - the assets at these sites would be a separate (but obviously linked) entity list - think of them as relational database tables, so you can filter your big asset list (150 x 50) by site reference. You can import your existing dataset(s) as entity lists too - if you can generate them as csv files, you can import them via the API - create the list and populate it in one go.

The form(s) to do the inspections can be set up to allow the inspector to select the entity they are inspecting and record it’s current status - pretty much as you describe it is a standard workflow using ‘select_one’ questions, which can also presented as objects on a map or a diagram (e.g. SVG). The form can also update the entity (asset) to show when it was last inspected, and any other changes that are relevant - so, for example, you could effectively hide assets that have already been inspected…

And the Central API can be used to extract the submissions (inspection records). You can use R or python tools to manipulate the OData output. There are plugins / connectors for lots of other tools worth looking out for.

All of this is now pretty stable within ODK

Best place to start? The documentation! Honestly. But if you’ve run through one of the tutorials, you’re on the way…

I have tended to develop the inspection type forms first, get them working satisfactorily, then added the entity functionality. Kind of walking before flying…But it’s good to know there are a set of wings… waiting in the wings…

Good luck - the forum is a friendly place for getting specific advice, the more general ‘how might I go about this?’ doesn’t always get picked up :slight_smile:

Thanks for the reply. I did manage to accomplish what I was looking to do (99% of it) just using a form without entities. I basically created a single form for one our big sites with 108 assets as a test. I listed all the assets in a choice list and then used the method from Hide the choices - #3 by Mtyszler to hide the assets once their rating was finished. Am I proud of having an if statement that has 108 “ands” in it? No, but the performance on my phone seems to works well. We’re going to test it at an actual site and make sure it works all the way through, including photos and uploading to the server. If it works, I’ll write a script that produces the individual site forms for me from our database.

I’ll definitely be digging into the entities and API to see if I can do it better, but my big concern was that there wasn’t any way to do it and I now know there’s at least one hacky way to do it.

I’m pretty happy with things at the moment. I’m glad I stumbled upon ODK.

John

:rofl: we've all been there.
As @seewhy mentioned, entities will make your life much easier with aspects like this. Before entities if you wanted to filter out items offline from submission to submission you had to build an ever growing string using last-saved and contains/selected. But in your case if you were inspecting every asset in one form via a repeat (probably a bad idea!) there are neater ways than that monster if.

When looking at existing examples, think of things like village:site :: household:asset to remap workflows/filtering.

Two things I’m trying to do (or avoid)…

First, I’m trying to avoid having the user open, complete, and submit different 108 forms (one per asset) as they do a site visit. The best way I see to accomplish using a single form per site is to use a repeat since the information to be collected is the same for each asset.

Second, I want to provide the user with a checklist of items to inspect. Using that big “if” statement following the method I linked to above allowed me to create a checklist using a select_one so that as soon as an asset has been assessed, it disappears from the list. The checklist is organized in a logical manner for them to complete so they likely will be selecting as asset at or near the top of the list as they proceed with the inspection (I don’t want to dictate a precise order). I was concerned about the huge repeat loop and performance but I ran through a test last night and did the assessment taking about 35 photos (they only are to take photos of something in poor condition) and it ran fine, uploaded to the server quickly, and I was able to download the zip file with csv/media with no issue.

This is a copy of one of the forms. Any thoughts are appreciated on how to do it better. From what I understand, ODK’s flow control is limited so things like branching, etc. aren’t possible.

site_w_cr.xlsx (596.2 KB)

given your inspection is so basic, having many repeats isn't impossible, but it does put all your eggs in one basket, with one large submission with all data & photos (I'm not suggesting ODK is unstable, (it's anything but), but users can accidentally delete records and devices get broken). As @seewhy will attest, often more, flatter, records are easier to handle.

Entities will allow items to have updated labels / a filterable field set upon submission, so from one submission to the next, even offline, items can either update like 'Access Road' --> 'Access Road :white_check_mark: ' or just be filtered out of the list. It can be done without entities but it's much fussier.

You can set relevance on questions / repeats / groups with simple / complicated logic to open/close different survey paths.

Here's a few:

  • Remove the 109x calculates, replace the monster if with a not(selected()) expression, set the repeat count dynamically to the count of assets
    • The change doesn't care how many assets there are, before you had to manually add/remove calculate/if entries and update the repeat count
    • You can now add other sites to this form and add a site selection at the start and include that in the filtering/counting
    • It also brings the size of your form submission down by >90%
  • Modify the appearance for the asset selection, columns is still awkward at this number, a minimal autocomplete is probably best here.
  • Give your assets better name values than 1, 2, 3..., unless you intentionally obfuscated them for the example form.
  • Label the groups to represent the asset within for easier table of contents navigation on review
  • Add hint values to guide your inspector ('Only take a photo if item is in poor condition', 'If default value is incorrect, update' etc)

site_w_cr_mod.xlsx (584.7 KB)

1 Like

Wow! Thank you very much. I don't think I would have come up with this on my own anytime soon.

I'm struggling to understand how the choice_filter works:

name = current()/. or not(selected(join(' ', /data/repeat_group/content/facility_asset), name))

Does the not(...) statement returnfalse if the asset has already been inspected? Is the current()/. needed?

Yes.

Try changing the choice filter and see what happens, you'll learn what each part does. And calculate the join and display it in a note to see what is being evaluated.

. is shorthand for the value of the current field

selected is usually used to test if a particular selection has been chosen in a select one/multiple ( documentation), but can be used for other purposes like this. The docs might get updated to elaborate on this I'm guessing @LN?

Thanks. Figured out the current(). is needed for the back button to work. You've given me a great starting point, much appreciated.