Mit diesem Client können Sie die MyJohnDeere-API verbinden, ohne Ihren eigenen oAuth-Prozess, API-Anfragen und Paginierung programmieren zu müssen.
get
, create
, put
und delete
Methoden für einfache, authentifizierte und direkte API-Aufrufeeach
, map
“ usw. rufen bei Bedarf neue Datenseiten ab. Wir stellen RDoc-Dokumentation zur Verfügung, aber hier ist eine hilfreiche Anleitung für den Einstieg. Da der Gem-Name lang ist, gehen alle Beispiele von dieser Abkürzung aus:
JD = MyJohnDeereApi
Wenn Sie also Folgendes sehen:
JD :: Authorize
Es bedeutet wirklich:
MyJohnDeereApi :: Authorize
Diese Bibliothek ist als Juwel erhältlich. Um es zu verwenden, installieren Sie einfach das Gem:
gem install my_john_deere_api
Wenn Sie Bundler verwenden (und warum nicht?), dann fügen Sie den Gem zu Ihrer Gem-Datei hinzu:
gem 'my_john_deere_api'
und führe aus:
bundle install
Dies ist der einfachste Weg zur Autorisierung, allerdings muss Ihr Benutzer einen zusätzlichen Hürden nehmen und Ihnen den Bestätigungscode geben:
# Create an authorize object, using your app's API key and secret. You can
# pass an environment (`:live` or `:sandbox`), which default to `:live`.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Retrieve a valid authorization url from John Deere, where you can send
# your user for authorizing your app to the JD platform.
url = authorize . authorize_url
# Verify the code given to the user during the authorization process, and
# turn this into access credentials for your user.
authorize . verify ( code )
In der Realität müssen Sie das Autorisierungsobjekt wahrscheinlich erneut instanziieren, wenn der Benutzer zurückkehrt, und das funktioniert ohne Probleme:
# Create an authorize object, using your app's API key and secret.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Retrieve a valid authorization url from John Deere.
url = authorize . authorize_url
# Queue elevator music while your app serves other users...
# Re-create the authorize instance in a different process
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Proceed as normal
authorize . verify ( code )
In einer Web-App möchten Sie, dass Ihr Benutzer keine Bestätigungscodes kopieren/einfügen muss. Sie können also eine :oauth_callback-URL übergeben. Wenn der Benutzer Ihre App bei John Deere autorisiert, wird er zu der von Ihnen angegebenen URL weitergeleitet, mit dem Parameter „oauth_verifier“, der den Bestätigungscode enthält, sodass der Benutzer ihn nicht angeben muss.
# Create an authorize object, using your app's API key and secret.
authorize = JD :: Authorize . new (
API_KEY ,
API_SECRET ,
environment : :sandbox ,
oauth_callback : 'https://example.com'
)
# Retrieve a valid authorization url from John Deere.
# This will contain the callback url encoded into the
# query string for you.
url = authorize . authorize_url
# Queue elevator music while your app serves other users...
# Re-create the authorize instance in a different process.
# It's not necessary to re-initialize with the callback url.
authorize = JD :: Authorize . new ( API_KEY , API_SECRET , environment : :sandbox )
# Inside a Rails controller, you might do this:
authorize . verify ( params [ :oauth_verifier ] )
Nach Abschluss der Autorisierung stellt das Client
Objekt den größten Teil der Schnittstelle für diese Bibliothek bereit. Ein Client kann mit oder ohne Benutzeranmeldeinformationen verwendet werden, da einige API-Aufrufe spezifisch für die Beziehung Ihrer Anwendung zu John Deere und nicht für die Ihres Benutzers sind. Bei den meisten Interaktionen handelt es sich jedoch um Benutzerdaten. So instanziieren Sie einen Client:
client = JD :: Client . new (
# the application's API key
API_KEY ,
# the application's API secret
API_SECRET ,
# the chosen environment (:sandbox or :live)
environment : :sandbox ,
# optional contribution_definition_id. This is needed for some requests,
# but the client can be created without it, in order to find it.
contribution_definition_id : CONTRIBUTION_DEFINITION_ID ,
# the user's access credentials
access : [ ACCESS_TOKEN , ACCESS_SECRET ]
)
Sobald Sie verbunden sind, funktioniert der Client wie eine vereinfachte Version von ActiveRecord. JSON-Hashes von der API werden in Objekte konvertiert, um die Arbeit zu erleichtern. Sammlungen von Dingen, wie z. B. Organisationen, übernehmen die Paginierung für Sie. Iterieren Sie einfach mit each
, map
usw. und neue Seiten werden nach Bedarf abgerufen.
Dieser Client ist in Arbeit. Sie können derzeit die folgenden Dinge tun, ohne auf API-Aufrufe zurückgreifen zu müssen:
client
├── contribution_products
| ├── count
| ├── all
| ├── first
| └── find(contribution_product_id)
| └── contribution_definitions
| ├── count
| ├── all
| ├── first
| └── find(contribution_definition_id)
└── organizations
├── count
├── all
├── first
└── find(organization_id)
├── assets(attributes)
| ├── create(attributes)
| ├── count
| ├── all
| ├── first
| └── find(asset_id)
| ├── save
| ├── update(attributes)
| └── locations
| ├── create(attributes)
| ├── count
| ├── all
| └── first
└── fields
├── count
├── all
├── first
└── find(field_id)
└── flags
├── count
├── all
└── first
Beitragsproduktsammlungen funktionieren wie eine Liste. Zusätzlich zu allen über das Enumerable-Modul von Ruby enthaltenen Methoden unterstützen Beitragsproduktsammlungen die folgenden Methoden:
Ein einzelnes Beitragsprodukt unterstützt die folgenden Methoden und Assoziationen:
client . contribution_products
# => collection of contribution products under this client
client . contribution_products . count
# => 1
client . contribution_products . first
# => an individual contribution product
contribution_product = client . contribution_products . find ( 1234 )
# => an individual contribution product, fetched by ID
contribution_product . market_place_name
# => 'Market Place Name'
contribution_product . contribution_definitions
# => collection of contribution definitions belonging to this contribution product
Verarbeitet die Beitragsdefinitionen eines Beitragsprodukts. Beitragsdefinitionssammlungen unterstützen die folgenden Methoden:
Eine individuelle Beitragsdefinition unterstützt die folgenden Methoden und Zuordnungen:
contribution_product . contribution_definitions
# => collection of contribution definitions under this contribution product
client . contribution_definitions . count
# => 1
client . contribution_definitions . first
# => an individual contribution definition
contribution_definition = contribution_product . contribution_definitions . find ( 1234 )
# => an individual contribution definition, fetched by ID
contribution_definition . name
# => 'Contribution Definition Name'
Verwaltet die Organisationen eines Kontos. Organisationssammlungen unterstützen die folgenden Methoden:
Eine einzelne Organisation unterstützt die folgenden Methoden und Verbände:
Die count
erfordert nur das Laden der ersten Ergebnisseite, daher ist es ein relativ kostengünstiger Aufruf. Andererseits erzwingt all
das Laden der gesamten Sammlung über die API von John Deere. Verwenden Sie diese Funktion daher mit Vorsicht. Organisationen können nicht über die API erstellt werden, daher gibt es für diese Sammlung keine create
.
client . organizations
# => collection of organizations under this client
client . organizations . count
# => 15
client . organizations . first
# => an individual organization object
organization = client . organizations . find ( 1234 )
# => an individual organization object, fetched by ID
organization . name
# => 'Smith Farms'
organization . type
# => 'customer'
organization . member?
# => true
organization . links
# => {
# 'self' => 'https://sandboxapi.deere.com/platform/organizations/1234',
# 'machines' => 'https://sandboxapi.deere.com/platform/organizations/1234/machines',
# 'wdtCapableMachines' => 'https://sandboxapi.deere.com/platform/organizations/1234/machines?capability=wdt'
# }
organization . assets
# => collection of assets belonging to this organization
organization . fields
# => collection of fields belonging to this organization
Verwaltet die Vermögenswerte einer Organisation. Asset-Sammlungen unterstützen die folgenden Methoden:
Ein einzelnes Asset unterstützt die folgenden Methoden und Zuordnungen:
organization = client . organizations . first
# => the first organization returned by the client
organization . assets
# => collection of assets belonging to this organization
asset = organization . assets . find ( 123 )
# => an individual asset object, fetched by ID
asset . title
# => 'AgThing Water Device'
asset . category
# => 'DEVICE'
asset . type
# => 'SENSOR'
asset . sub_type
# => 'OTHER'
asset . links
# => a hash of API urls related to this asset
Die Methode create
erstellt das Asset auf der John Deere-Plattform und gibt den neu erstellten Datensatz zurück.
asset = organization . assets . create (
title : 'Asset Title' ,
asset_category : 'DEVICE' ,
asset_type : 'SENSOR' ,
asset_sub_type : 'ENVIRONMENTAL'
)
asset . title
# => 'Asset Title'
Die update
-Methode aktualisiert das lokale Objekt und auch das Asset auf der John Deere-Plattform. Nur der Titel eines Assets kann aktualisiert werden.
asset . update ( title : 'New Title' )
asset . title
# => 'New Title', also John Deere record is updated
Die save
aktualisiert John Deere mit allen vorgenommenen lokalen Änderungen.
asset . title = 'New Title'
asset . save
# => Successful Net::HTTPNoContent object
Verwaltet die Standorte einer Anlage. Asset Location-Sammlungen unterstützen die folgenden Methoden:
Ein einzelner Standort unterstützt die folgenden Methoden:
asset = organizations . assets . first
# => the first asset returned by the organization
asset . locations
# => collection of locations belonging to this asset
location = asset . locations . first
# => the first location returned by the asset. Note that locations do not have their own id's
# in the JD platform, and therefore cannot be requested individually via a "find" method.
location . timestamp
# => "2019-11-11T23:00:00.000Z"
# John Deere includes 3 decimal places in the format, but does not actually
# store fractions of a second, so it will always end in ".000". This is
# important, because timestamps must be unique.
location . geometry
# => a GeoJSON formatted hash, for example:
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
location . measurement_data
# => the status details of this location, for example:
# [
# {
# "@type"=>"BasicMeasurement",
# "name"=>"[Soil Temperature](http://example.com/current_temperature)",
# "value"=>"21.0",
# "unit"=>"°C"
# }
# ]
Die Methode create
erstellt den Standort auf der John Deere-Plattform und gibt das neu erstellte Objekt von John Deere zurück. Es werden jedoch keine neuen Informationen angezeigt, da keine eindeutige ID generiert wird. Der übermittelte Zeitstempel (der standardmäßig „jetzt“ lautet) wird auf die nächste Sekunde gerundet.
locaton = asset . locatons . create (
# You can pass fractional seconds, but they will be truncated by JD.
timestamp : "2019-11-11T23:00:00.123Z" ,
# JD requires more complicated JSON geometry, but this client will convert a simple
# set of lat/long coordinates into the larger format automatically.
geometry : [ - 95.123456 , 40.123456 ] ,
# This is a list of "measurements"
measurement_data : [
{
name : 'Temperature' ,
value : '68.0' ,
unit : 'F'
}
]
)
location . timestamp
# => "2019-11-11T23:00:00.000Z"
# Note that the timestamp's fractional second is truncated by John Deere, though they
# still return the record with three digits of precision.
location . geometry
# => a GeoJSON formatted hash in its larger format
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
location . measurement_data
# [
# {
# "@type"=>"BasicMeasurement",
# "name"=>"Temperature",
# "value"=>"68.0",
# "unit"=>"F"
# }
# ]
Es erfolgt keine Aktualisierung oder Löschung eines Standorts. Der neueste Standortdatensatz dient immer als Status für das jeweilige Asset und wird in der Kartenansicht angezeigt.
Beachten Sie, dass Standorte bei John Deere als „Asset-Standorte“ bezeichnet werden, der Kürze halber nennen wir die Zuordnung jedoch „Standorte“, wie in asset.locations
.
Behandelt die Felder einer Organisation. Feldsammlungen unterstützen die folgenden Methoden:
Ein einzelnes Feld unterstützt die folgenden Methoden und Zuordnungen:
Die count
erfordert nur das Laden der ersten Ergebnisseite, daher ist es ein relativ kostengünstiger Aufruf. Andererseits erzwingt all
das Laden der gesamten Sammlung über die API von John Deere. Verwenden Sie diese Funktion daher mit Vorsicht. Felder können über die API erstellt werden, es gibt jedoch noch keine create
für diese Sammlung.
organization . fields
# => collection of fields under this organization
organization . fields . count
# => 15
organization . fields . first
# => an individual field object
field = organization . fields . find ( 1234 )
# => an individual field object, fetched by ID
field . name
# => 'Smith Field'
field . archived?
# => false
field . links
# => a hash of API urls related to this field
field . flags
# => collection of flags belonging to this field
Behandelt die Flags eines Feldes. Flag-Sammlungen unterstützen die folgenden Methoden. Beachten Sie, dass John Deere keinen Endpunkt zum Abrufen einer bestimmten Flagge anhand der ID bereitstellt:
Eine einzelne Flagge unterstützt die folgenden Methoden und Zuordnungen:
Die count
erfordert nur das Laden der ersten Ergebnisseite, daher ist es ein relativ kostengünstiger Aufruf. Andererseits erzwingt all
das Laden der gesamten Sammlung über die API von John Deere. Verwenden Sie diese Funktion daher mit Vorsicht. Flags können über die API erstellt werden, es gibt jedoch noch keine create
für diese Sammlung.
field . flags
# => collection of flags under this field
field . flags . count
# => 15
flag = field . flags . first
# => an individual flag object
flag . notes
# => 'A big rock on the left after entering the field'
flag . geometry
# => a GeoJSON formatted hash, for example:
# {
# "type"=>"Feature",
# "geometry"=>{
# "geometries"=>[
# {
# "coordinates"=>[-95.123456, 40.123456],
# "type"=>"Point"
# }
# ],
# "type"=>"GeometryCollection"
# }
# }
field . archived?
# => false
field . proximity_alert_enabled?
# => true
field . links
# => a hash of API urls related to this flag
Während das Ziel des Clients darin besteht, die Notwendigkeit zu beseitigen, Aufrufe an die John Deere API zu tätigen/interpretieren, ist es wichtig, Aufrufe durchführen zu können, die vom Client noch nicht vollständig unterstützt werden. Oder manchmal müssen Sie eine Fehlerbehebung durchführen.
GET-Anfragen erfordern nur einen Ressourcenpfad.
client . get ( '/organizations' )
Gekürzte Beispielantwort:
{
"links" : [ " ... " ],
"total" : 1 ,
"values" : [
{
"@type" : " Organization " ,
"name" : " ABC Farms " ,
"type" : " customer " ,
"member" : true ,
"id" : " 123123 " ,
"links" : [ " ... " ]
}
]
}
Dadurch werden keine Client-Extras wie Paginierung oder Validierung bereitgestellt, aber der zurückgegebene JSON wird analysiert.
POST-Anfragen erfordern einen Ressourcenpfad und einen Hash für den Anfragetext. Der Client kamelisiert die Schlüssel und konvertiert sie in JSON.
client . post (
'/organizations/123123/assets' ,
{
"title" => "i like turtles" ,
"assetCategory" => "DEVICE" ,
"assetType" => "SENSOR" ,
"assetSubType" => "ENVIRONMENTAL" ,
"links" => [
{
"@type" => "Link" ,
"rel" => "contributionDefinition" ,
"uri" => "https://sandboxapi.deere.com/platform/contributionDefinitions/CONTRIBUTION_DEFINITION_ID"
}
]
}
)
Die Standardantwort von John Deere ist ein HTTP-Statuscode 201 mit der Meldung „Erstellt“. Diese Methode gibt die vollständige Net::HTTP-Antwort zurück.
PUT-Anfragen erfordern einen Ressourcenpfad und einen Hash für den Anfragetext. Der Client kamelisiert die Schlüssel und konvertiert sie in JSON.
client . put (
'/assets/123123' ,
{
"title" => "i REALLY like turtles" ,
"assetCategory" => "DEVICE" ,
"assetType" => "SENSOR" ,
"assetSubType" => "ENVIRONMENTAL" ,
"links" => [
{
"@type" => "Link" ,
"rel" => "contributionDefinition" ,
"uri" => "https://sandboxapi.deere.com/platform/contributionDefinitions/CONTRIBUTION_DEFINITION_ID"
}
]
}
)
Die Standardantwort von John Deere ist ein HTTP-Statuscode 204 mit der Meldung „Kein Inhalt“. Diese Methode gibt die vollständige Net::HTTP-Antwort zurück.
DELETE-Anfragen erfordern nur einen Ressourcenpfad.
client . delete ( '/assets/123123' )
Die Standardantwort von John Deere ist ein HTTP-Statuscode 204 mit der Meldung „Kein Inhalt“. Diese Methode gibt die vollständige Net::HTTP-Antwort zurück.
Benutzerdefinierte Fehler helfen dabei, Probleme bei der Verwendung des Clients eindeutig zu identifizieren:
:sandbox
oder :production
.Markieren Sie dieses Juwel auf GitHub. Es hilft Entwicklern, dieses Juwel zu finden und anderen, die es möglicherweise gibt, vorzuziehen. Unseres Wissens nach gibt es keine anderen Juwelen von John Deere, die aktiv gepflegt werden.
Der einfachste Weg, einen Beitrag zu leisten, ist:
vcr_setup
vorbespielt werdenvcr_setup
.