From ac5c229755a66a0c158c0dcf4f613fa9c4f963b6 Mon Sep 17 00:00:00 2001 From: Steve Hansen Date: Tue, 19 Mar 2024 10:47:37 -0400 Subject: [PATCH] Updates --- myadmin-sdk/api/reference/index.html | 1 + myadmin-sdk/api/reference/index.html.gz | Bin 16779 -> 16788 bytes software/api/reference/index.html | 1 + software/api/reference/index.html.gz | Bin 16783 -> 16792 bytes software/guides/data-feed/index.html | 2 +- software/guides/data-feed/index.html.gz | Bin 7460 -> 7468 bytes 6 files changed, 3 insertions(+), 1 deletion(-) diff --git a/myadmin-sdk/api/reference/index.html b/myadmin-sdk/api/reference/index.html index e24aa5d8..2541ed6c 100644 --- a/myadmin-sdk/api/reference/index.html +++ b/myadmin-sdk/api/reference/index.html @@ -1215,6 +1215,7 @@ memberDictionary["Checkmate"]["Database"], memberDictionary["Checkmate"]["ObjectModel"], memberDictionary["Checkmate"]["ObjectModel"]["AddIns"], + memberDictionary["Checkmate"]["ObjectModel"]["Charging"], memberDictionary["Checkmate"]["ObjectModel"]["Engine"], memberDictionary["Checkmate"]["ObjectModel"]["Exceptions"], memberDictionary["Checkmate"]["ObjectModel"]["Files"], diff --git a/myadmin-sdk/api/reference/index.html.gz b/myadmin-sdk/api/reference/index.html.gz index 4fdb7c966c8bed087af1727bed41b9d2525b8b79..b8a34e347968b5d896eeae2287d22853df2422a7 100644 GIT binary patch delta 1477 zcmV;$1v>hRg8`I-0kGsdf5L#+Q`|FjFVHwE+!L&8m+~MT_XF>>kB5!j52)pRHRTU9 zn#Rsz=DW^4LELv1sXKG-2iT9x*iWQC(>)=0Os75`7t1_k?giqhyT|lLgk^k!qEYd>{PcUYaW#uHO7dHo98H~n!U_4w(z<(|ZDjr9$2MH{@ zva~^FTWrOzd>Ck*enkV@@w``;0RJuYT3kEmT5jOGpREFbrk!sh+!AgXnE8o~F_r}- zPW*9TTqzM*ZMMQ=e~SekoCDWQ^tUhU*Thq!@emY!T8^iSYC5tP{7L<5ZX4LUeAYXwv;87#| z80r~-;y`1ve_SkRj8Pp-$vZF{_kle+70%ThcWxrQ;=;lT!j9up;rS zR#ANqUgP6e=9iN!Rav2`M5Y5NPeS*5Ul>uwbsDd6R7_g+Umw{8w$b0Hun@_xR zXUzrVguW&TTfm#8)1WS>QG#9Rn}uf#Jj@ZO)37X&r0?>RDy`CT{2YXnDLZ~I=Lwxl zQx^E_e^2@3X05DI;;N!4ue0#`nGvkd(-+RC8hrO1IYgYl`)-iG%+ApY4l|-O+s@=rdz<2Aj?&- zovW%>!46sQ3=mCQ(F?hzmqWldtR~`$VV;T;f4e!IvrHq|OKgr@WzkqcA7)k_^z5v~ ztIBlZ#!(QMwdq2kZV;iU&dX3VQneLeJfXm9bHVyVgz08FZk7(!!$h;<52X)@Z54sVwM#}kA~K1 zf3$RGc)DJN+zJt&4Y)gI=7r_NsqdD&vYt(%2*+um&WNXZ+Q+6Mi<|zYm8nd4G{*U{?Wa%Eye*F2T zlb0`kJAOZ&GEAQ@lf_N~>Koc@Ola>N9gtHR&)L35v53bsbwx>cqs2{(!L<6W)YM7- z?rP?zw9ihO-`$sQ$+wu`DcKmVJ3l6TW4Y`YycfU?id@-IcxS@(+noV6Ka@+;WRS;( f9O*^gQgqIHv$jVE6w4oX)M{@jC$kyM^wO delta 1468 zcmV;t1w;Cjg8_?!0kGsdf8vdIPq40C%EM~h54_ht9uIaupqBSV{2ypEjh)5Jcb$8J zxbG}dcjnv=upgJPpGXg+dqVJ-PJKM!mHD*X3&c~$opCbWb2~E);Z}f7Xo_RkZSlBE z!7j8}dec7p%h%pOjNB>m2&@a5Zm>0Wx*j zMy$NM6p?L-*h_9gmu-t!S9eOV*H%v}C}b3)D%gg=H@d|yf51<70vmRpx|#cfLMpVo z6kbU3A#2wz!?un*g%?|M$Q*lCU8yafjQ7X7PzhWGX(i41I%AQ#b?y4;n=h=YU*Q+C zeN~qkKb4zUebP3!rj@7sJh!?wh6(LU773Is0r9HLsN+kgQrj8u;xx@?JIK<`P3RYz^dxM%F!A} z-VGp?Nao_CW7sGsJMPwnn_@6xRw>a6>{PX+Yg+uqe@ikarvyM?MdInIqWT`Z#>cPB zlSWthGDvN#F+4OOnvaqD1a)!q0oIyP1${&?#7JTH0jHXg_tf1npLplanhVGYeN7U! zfHzC0L0wRz1iR8V3(puTm?Kc9VOb(c-{ogZTBQZ_IS40HcKlw>6FQfsEb!T%^2yCw zS);^te?U`SXW{oVvsIs`FPtbf`0hJ$h&X@u-5`INorCW&xyb8G$ zeTwPs3k7oxv zLSqgRF;gGNSfxBt>8_l?qgF-u9(Vrt-|7P?Lx;L2_B4v7z`qDy(qiBZ){~!Zrf=U3 zH?B6W-$j?N|GD+s_T^PS+WUR-&+C2ffAP<6XE&$Ot6=(aoD3GrF?70MCyb&6QmusD zQS4tj?hQGLKtX7W<6wT{pxL;ec%KJ;n8uN}WW*nkUAZ6VTSbIU(G7(U*--k-dEm;U3 znY3<+sMQ8j=k<@_>whlZ?7!O@zow6Fewtlu&$svdANPaF(mkI2`14OEFJJt2{C+%T zm_A=7i=712H?-N9(B3;bAg45*vz>}!*^O!HijwX|i<=n3U-ez7sgwNO)yz+6pPdcA zyD#68Z!y7BvN2qLO!!uC*)e!8GJqQtxw511&V(zjI|FQfD3_+mAdlueU_0RLi)2^n WdDww*P63+0?*9XtQs`czI{^S%zVmbd diff --git a/software/api/reference/index.html b/software/api/reference/index.html index c36706e4..2d6964d7 100644 --- a/software/api/reference/index.html +++ b/software/api/reference/index.html @@ -1215,6 +1215,7 @@ memberDictionary["Checkmate"]["Database"], memberDictionary["Checkmate"]["ObjectModel"], memberDictionary["Checkmate"]["ObjectModel"]["AddIns"], + memberDictionary["Checkmate"]["ObjectModel"]["Charging"], memberDictionary["Checkmate"]["ObjectModel"]["Engine"], memberDictionary["Checkmate"]["ObjectModel"]["Exceptions"], memberDictionary["Checkmate"]["ObjectModel"]["Files"], diff --git a/software/api/reference/index.html.gz b/software/api/reference/index.html.gz index 517c7f2b2b542357b79870dc75ea606b10df6d54..39a3324596e0db8abc0d4c2735ddacd29fda750c 100644 GIT binary patch delta 1476 zcmV;#1v~nWg8`U>0kG*ie=s2S1osTx3pCCO_XO+4r94Q-{lI(e<6&d>18Q+!P5A?j zCb2W0`mS?N5D%Pr>Q0^e0ruk}_7myPbWaGL(20-7#WD|>dx3c7xKmEXdv0f@Z`=yd zDNS)Cye%GgDcFTJOPB4lzl@!0CIGa`PvsS#Jl|IP5wgBl0HY~be?(rY(Sg*=tLQ)l zs0|8GDRViz3#c?Q@_(IyMSAGr3C3))tegb(VtMG5!D!3}#>1rq{O6*e;&BA~kifDl zOB-am%~t%%hk@4VS2VC4&wF(R@ZUnO#kGU3`!szIh(f~i*d2ZN! z>g)gy3aQYFQ+OfChpb(@sM|V@6<%xwBXbj4b=|jo&fXvEkR@;xq?I)1tCmIT*0t-W zZ@#dqeuZDm_ElZ9{8VmY^-0^@npU3h)8Xpc7^cTBSzJ-Jpv0>(rH+RJ`5MFlj~d~} zP|pAq2O5*be|%13jOt(_#~T5nXkt}xIbXlv=P~ob$nKsfwy+`g1D2I-h!qLsPFUTj zgdrvcEh-fvadcgSGf!|5T?4|O(4$H;hp0vgQAja`6#NCW7(9IvM?ZHuYhRhm$*0!H z0ajISSdP{x@|J*9BAJVmj$xym6S-Fxyo$kyS*1iPf3P#!lCEhf9WTk8oDu+m6^UoH zit2mt8XvzhzZ_lV%OJIp%kT(>Xf{Ib6V%163|MPM74$g4fF*^!44i64-c$G5eBzxu zYc3!s^fgJ?0^Tg026aJ=66{LfEIec2VU9qZhGmH)eV3n9X_c1aXCRzR+3|ZhPv~5k zvcPA5f5Im>Yh{fRR~1cpow?u7j9`79zHmO(;Jfe05#s#acZ2+8cE*OXo*s>f&~x(> z#Qp)w^B87FIXoV6J%VgdyIw*pCt%U7sE1Ykn$nlv7xIF zxW2xI9?y=6gvJ~sVx~TjkxzNt(>*zZN3DwR9rOI}ztsm)h7NU4>`4?&fPWFZq{YA+ zY$QJ|CvV@aZ(eWSyo;`0|8x7dovZ79f3*Mm_@6fi-s7L&PM2rVt6=hSlnmyJ5p=p> zH;ke=QmusDaqM3??vflwpdhrxaWGptXoT)3-sgcIrg7vg81V;WPwp-{efjr$tnuak zlmB#|{QS$&bmsi#U3yR6O`gR6-1d(S*B@`)9E{(-OMiWNdi;3v>^}$8g8|-9f8|#& zTz*J!YvClOOj@@@)M|sN^ZLi|^*`rt4&H5#Ueia*pQe{Pvz>ka$Ae(Ja8IT`{`}MF z%NM_$ydO;%rq372d^Z904Q)0iwD*q>$r+7jY~Q0;#ABMeqNKagd>Laft-dQYb&|ik zp86^6vyEIupLJTy_lJ3*ZJtuIwnhGvWH}?f{z~%B5*C$YVnf e*nWEZGTBpl9(G`yQ-CJ0_x}JLsv^JbI{^SJ1?ipu delta 1467 zcmV;s1w{Iog8`3&0kG*ie|Y2F6RaDT@~|5B1Mjtu$AjGusKtE|{|6dPVrM?}UFV)4 z9ys&VojUge?8imyC(;Ayo)A2t6CV$FWj-zU0`bgor<{!U+|EoxxD}vNn&Q}XTRiSk zunTRLF572+89Udw%}=kcR9^Av?rrrIA)R{#Fq(oztfU&PMa{g5f7Vif+Mu$OGM59g zfD$5O_1Bq1q)#25In1WF%GpgXmWN&$jAp`bJPu00e=Z6t9w4v}2`sy^7(u4nY>lpb zd}p0TL<8ILyjNEM|1I=dwDxx`H}KuhRslfMUNsRQ37!0>eqv)(WI>5je-s$kHbhpN zt;yJ8Nd{-FH6PF@e}W4(7OoAAf(TH>r6KmpFq5P}W{UNE$+xf8ZFl=Bt&E!9V&JI^wt8AYA)^>o!8QcG(Jg)fe}1|X*s%N5&DZ3!9DiX-OtGZDMgF*^gR4PQ` z=(+}Hp5P?9282JM50q#QQH>I!kYWlc_zP$;c={v`YwmQ`zA`6~Ppy#ytg8O29Ia90 zEdi-SG8ZQu!$vvTaj!1i6oV17N{Lorr>Z4g)8aQ?f08*lB>(~|5>HnZ)%V~vK7M7M zG`h-{L26@-;h_o9Y=qn=sEeBqu-1$!=p%w5Mhd$RIMs~2r|ypV#5;G^TtH6fYm%@9 zyjeO8>Vg_2*p=TIPf#GaSYlD)*{f5=sqc@^|wX5~T8&RV>xOeby}1%X+c zE)?np5sK=(3`HYVTLH!s3amC0tWQK>ZKmU9=}L%eIT zA0?c*K0D0U{8Z#9r?B|)wOGWir4_bHPV77G7Y}`-0&jUY9V z%=yi`^q#z%Jc<9g?H?VkKi;}I7{7g&{`&It`0?i1e-5Yz1H7TiuVA?Rkl<#(e@RT4 zv~G#0)do}N^^f7}f6m_=yxShVrjM3CO)qz5JNy2R2f=vZo=kuI`KQyDFMd0DKbkO1 zpD&X6ZUX8X+H6c{?;jtMGaAp>PDQco#x!+BNq3|9GRE*%eOGGgB!723^;6nsXT$Fu z$hYKMOz@O!u5Uahd@H!@7`zw2F%61b*-?0B!WGxu0X9FBOVebKM{^#q9q{&LvZwSs V?7%pu08L=;{{f4y+t!~u0RY8a-%|hp diff --git a/software/guides/data-feed/index.html b/software/guides/data-feed/index.html index b2347eae..29dd9fd7 100644 --- a/software/guides/data-feed/index.html +++ b/software/guides/data-feed/index.html @@ -5,4 +5,4 @@ })(window,document,'script','dataLayer','GTM-5V5GBX4');Data Feed | Geotab Developers
Edit on GitHub Ask developers in the Community

Data Feed

The data feed is the primary method used to synchronize data from the telematics system to another system using the API. The GetFeed method can be polled at intervals to get new and updated data from the system. The feed API works with a token that is passed on every request and sent back with the payload on every response. This allows Geotab to track “up to which point in time” we have already sent the receiver data. It also allows the receiver to stop and seamlessly resume the data feed.

Lightweight Incremental Poll

The feed API is designed to be lightweight and scalable. There is virtually no cost on Geotab’s side for a poll request that yields no data. For example, a poll request when the round trip has no GPS coordinates will return no payload data. The requests themselves, the amount of processing time taken, and the amount of data returned via the internet are all extremely small.

Here is a small trace showing < 100 bytes for an empty poll request with response time of 19ms. The last request contains a payload with 2 GPS coordinates.

data feed image

The polling frequency is dictated by the requirements of the integration. It could be as infrequent as once a day or as frequent as every few seconds.

Dealing with Volume

In each request the caller can specify the maximum number of data points that can be returned in a request. This allows the caller to have control over the maximum size of the responses. This value can be adjusted down from the default of 50,000 — with fewer data points yielding a faster response time. When the limit is reached, the response will be returned with the payload and a token which can be used to specify the point in time from which the next request should start.

The request-response approach also allows for incremental processing. For example, if there were a large backlog of data, the caller would be able to process the chunks of data at its own rate until the backlog of data has been cleared.

The API can be consumed by small and large customers alike. Larger customers can consume tens of millions of records per day via the API.

Searching

The data feed was designed to be an efficient means of getting a continuous feed of new data from a given token. When a feed is first started it is possible to provide search criteria with a “from date” argument. This specifies the token that will be used to start the feed. This will guarantee that the feed will start at a point that will include any data that is at or after the “from date” argument, but may also include data timestamped before the “from date” argument. For example when performing a “TripSearch” and setting “IncludeOverlappedTrips” to True.

While “from date” is supported, “to date” is not. The feed is not designed to return data within discrete dates. If you wish to obtain data in a particular date range, then use the standard Get methods associated with the entity search objects. If a version is specified, then the argument “from date” is ignored.

Do not pass a search to any feed unless it specifically is mentioned in the GetFeed method documentation.

Caching to Improve Performance

It may be required to populate nested entities of data retrieved via the feed. Entities that are static or semi-static will respond well to caching.

For example, status data and diagnostics are separate entities in the system. Status data references a diagnostic. Status data returned by the feed will only have the ID property of the diagnostic populated. If the diagnostic is required by your process then you must get the diagnostic in a separate API call and populate it in the status data record.

This is a good example of where caching can be implemented to improve efficiency, as diagnostic data rarely changes. A cache of diagnostics can be held in memory, refreshed at some interval of your choosing (24 hours, 12 hours, etc.) and may vary depending on the entity type being cached. Entities that may respond well to caching include Unit of Measure, Diagnostic, Source, Device and User.

Active vs Calculated

There are two types of data that can be retrieved using a data feed: active data and calculated data.

Active data are records that are received from a source, usually a Go device or user input. They are not created based off of other data. These records are static; once received, they are typically not updated and will not be removed by the system. For example, as new GPS (LogRecord) data arrives from a device, it is stored by the system.

Calculated data are records generated automatically by the system, usually in response to active data that has recently been received. These records are dynamic; an existing calculated data record can be edited and removed by the system automatically, based on new active data that was received. This processing happens in real-time as new active data is received by the system. For example, as new GPS and engine data arrives from a device, it is processed to create new ExceptionEvents or edit/remove existing ExceptionEvents.

Active Data Feeds (Only new data.)

  • AnnotationLog

  • Audit

  • CustomData

  • DVIRLog

  • DebugData

  • Device

  • Diagnostic

  • DriverChange

  • DutyStatusLog

  • FaultData

  • FillUp

  • FuelUsed

  • IoxAddOn

  • LogRecord

  • Route

  • Rule

  • ShipmentLog

  • StatusData

  • TextMessage

  • Trailer

  • TrailerAttachment

  • User

  • Zone

Calculated data feeds (New data and updated data from the past.)

  • ExceptionEvent

  • FuelTaxDetail

  • Trip

Invalidated Data

As calculated data is processed in real time, the state of the data can change causing it to become invalidated. There are a few reasons why calculated data can become invalid or need to be updated by the system.

  • A trip or exception is in progress

  • The system receives new data that invalidates previous data

  • Manual reprocessing was triggered

Trips

Trips are calculated data. As new data arrives for a trip currently in progress, the older data for the trip is dropped from the database. The dropped data is then replaced with the newer, more current trip data. The updated trip data will have a different trip ID than the previous record of the trip. Thus the “unique trip ID” cannot be used to match an updated trip to an earlier state.

The unique “key” (used to associate the earlier “version” of the trip in progress to the updated trip) consists of the deviceId and the trip’s stop date. Most of the time, a trip which is in progress will have its stop date continuously updated until the trip has actually ceased (ignition off). An old trip will be replaced with a new trip if:

  • the trips’ deviceId are the same AND
  • the start dates are the same AND
  • the stop dates are different AND
  • the new trip’s stop duration is 0

Exception Events

Like trips, exception events are calculated data. As the system receives updated device data, that data is processed and evaluated against the Rules set up in the system. Exception events that are in progress will be updated by the system and will retain the same unique id. Exception events can be invalidated and dropped from the database when a manual process is triggered. Reprocessed exception events will have a new unique id.

HOS and DVIR Feeds

The HOS and DVIR related objects under the “Active data feeds” (DutyStatusLog, DVIRLog, AnnotationLog, ShipmentLog) are likely to be edited on a frequent basis. An example is a “DutyStatusLog” that was created (Add) at the beginning of the day with an “ON” duty status, and then edited (Set) to add the “verifyDateTime” at the end of the day.

Each time one of these data records is manipulated, it will retain its original unique GUID “Id” but will receive an incremented “version”. This way you can match new feed records to existing data you obtained from an earlier feed request.

Next Steps

Once you have a basic understanding of how the Data Feed works you can read more about the GetFeed method and it’s parameters in the API Reference or try out the JavaScript and .Net data feed examples.

FAQ

Why do I have to poll data, can’t you push it to me?

A push-based approach would require Geotab to connect to another organization and this invariably means firewall traversal is required. To accomplish this, network administrators will need to be involved and will be required to maintain the process. This is very often a cumbersome process and sometimes disallowed due to security risks. Geotab wants to provide a zero configuration solution. The poll-based approach avoids these issues because all traffic is initiated from within your network, secured via SSL. No certificates need to be installed, no firewalls configured, and no other onerous security requirements are necessary.

There are definitely advantages and disadvantages to both approaches. However, in our experience, we have found the polling based approach is scalable, solves practical network problems, requires zero configuration, and meets the needs of our customers.

\ No newline at end of file + }
Edit on GitHub Ask developers in the Community

Data Feed

The data feed is the primary method used to synchronize data from the telematics system to another system using the API. The GetFeed method can be polled at intervals to get new and updated data from the system. The feed API works with a token that is passed on every request and sent back with the payload on every response. This allows Geotab to track “up to which point in time” we have already sent the receiver data. It also allows the receiver to stop and seamlessly resume the data feed.

Lightweight Incremental Poll

The feed API is designed to be lightweight and scalable. There is virtually no cost on Geotab’s side for a poll request that yields no data. For example, a poll request when the round trip has no GPS coordinates will return no payload data. The requests themselves, the amount of processing time taken, and the amount of data returned via the internet are all extremely small.

Here is a small trace showing < 100 bytes for an empty poll request with response time of 19ms. The last request contains a payload with 2 GPS coordinates.

data feed image

The polling frequency is dictated by the requirements of the integration. It could be as infrequent as once a day or as frequent as every few seconds.

Dealing with Volume

In each request the caller can specify the maximum number of data points that can be returned in a request. This allows the caller to have control over the maximum size of the responses. This value can be adjusted down from the default of 50,000 — with fewer data points yielding a faster response time. When the limit is reached, the response will be returned with the payload and a token which can be used to specify the point in time from which the next request should start.

The request-response approach also allows for incremental processing. For example, if there were a large backlog of data, the caller would be able to process the chunks of data at its own rate until the backlog of data has been cleared.

The API can be consumed by small and large customers alike. Larger customers can consume tens of millions of records per day via the API.

Searching

The data feed was designed to be an efficient means of getting a continuous feed of new data from a given token. When a feed is first started it is possible to provide search criteria with a “from date” argument. This specifies the token that will be used to start the feed. This will guarantee that the feed will start at a point that will include any data that is at or after the “from date” argument, but may also include data timestamped before the “from date” argument. For example when performing a “TripSearch” and setting “IncludeOverlappedTrips” to True.

While “from date” is supported, “to date” is not. The feed is not designed to return data within discrete dates. If you wish to obtain data in a particular date range, then use the standard Get methods associated with the entity search objects. If a version is specified, then the argument “from date” is ignored.

Do not pass a search to any feed unless it specifically is mentioned in the GetFeed method documentation.

Caching to Improve Performance

It may be required to populate nested entities of data retrieved via the feed. Entities that are static or semi-static will respond well to caching.

For example, status data and diagnostics are separate entities in the system. Status data references a diagnostic. Status data returned by the feed will only have the ID property of the diagnostic populated. If the diagnostic is required by your process then you must get the diagnostic in a separate API call and populate it in the status data record.

This is a good example of where caching can be implemented to improve efficiency, as diagnostic data rarely changes. A cache of diagnostics can be held in memory, refreshed at some interval of your choosing (24 hours, 12 hours, etc.) and may vary depending on the entity type being cached. Entities that may respond well to caching include Unit of Measure, Diagnostic, Source, Device and User.

Active vs Calculated

There are two types of data that can be retrieved using a data feed: active data and calculated data.

Active data are records that are received from a source, usually a Go device or user input. They are not created based off of other data. These records are static; once received, they are typically not updated and will not be removed by the system. For example, as new GPS (LogRecord) data arrives from a device, it is stored by the system.

Calculated data are records generated automatically by the system, usually in response to active data that has recently been received. These records are dynamic; an existing calculated data record can be edited and removed by the system automatically, based on new active data that was received. This processing happens in real-time as new active data is received by the system. For example, as new GPS and engine data arrives from a device, it is processed to create new ExceptionEvents or edit/remove existing ExceptionEvents.

Active Data Feeds (Only new data.)

  • AnnotationLog

  • Audit

  • CustomData

  • DVIRLog

  • DebugData

  • Device

  • Diagnostic

  • DriverChange

  • DutyStatusLog

  • FaultData

  • IoxAddOn

  • LogRecord

  • Route

  • Rule

  • ShipmentLog

  • StatusData

  • TextMessage

  • Trailer

  • TrailerAttachment

  • User

  • Zone

Calculated data feeds (New data and updated data from the past.)

  • ChargeEvent

  • ExceptionEvent

  • FillUp

  • FuelTaxDetail

  • FuelUsed

  • Trip

Invalidated Data

As calculated data is processed in real time, the state of the data can change causing it to become invalidated. There are a few reasons why calculated data can become invalid or need to be updated by the system.

  • A trip or exception is in progress

  • The system receives new data that invalidates previous data

  • Manual reprocessing was triggered

Trips

Trips are calculated data. As new data arrives for a trip currently in progress, the older data for the trip is dropped from the database. The dropped data is then replaced with the newer, more current trip data. The updated trip data will have a different trip ID than the previous record of the trip. Thus the “unique trip ID” cannot be used to match an updated trip to an earlier state.

The unique “key” (used to associate the earlier “version” of the trip in progress to the updated trip) consists of the deviceId and the trip’s stop date. Most of the time, a trip which is in progress will have its stop date continuously updated until the trip has actually ceased (ignition off). An old trip will be replaced with a new trip if:

  • the trips’ deviceId are the same AND
  • the start dates are the same AND
  • the stop dates are different AND
  • the new trip’s stop duration is 0

Exception Events

Like trips, exception events are calculated data. As the system receives updated device data, that data is processed and evaluated against the Rules set up in the system. Exception events that are in progress will be updated by the system and will retain the same unique id. Exception events can be invalidated and dropped from the database when a manual process is triggered. Reprocessed exception events will have a new unique id.

HOS and DVIR Feeds

The HOS and DVIR related objects under the “Active data feeds” (DutyStatusLog, DVIRLog, AnnotationLog, ShipmentLog) are likely to be edited on a frequent basis. An example is a “DutyStatusLog” that was created (Add) at the beginning of the day with an “ON” duty status, and then edited (Set) to add the “verifyDateTime” at the end of the day.

Each time one of these data records is manipulated, it will retain its original unique GUID “Id” but will receive an incremented “version”. This way you can match new feed records to existing data you obtained from an earlier feed request.

Next Steps

Once you have a basic understanding of how the Data Feed works you can read more about the GetFeed method and it’s parameters in the API Reference or try out the JavaScript and .Net data feed examples.

FAQ

Why do I have to poll data, can’t you push it to me?

A push-based approach would require Geotab to connect to another organization and this invariably means firewall traversal is required. To accomplish this, network administrators will need to be involved and will be required to maintain the process. This is very often a cumbersome process and sometimes disallowed due to security risks. Geotab wants to provide a zero configuration solution. The poll-based approach avoids these issues because all traffic is initiated from within your network, secured via SSL. No certificates need to be installed, no firewalls configured, and no other onerous security requirements are necessary.

There are definitely advantages and disadvantages to both approaches. However, in our experience, we have found the polling based approach is scalable, solves practical network problems, requires zero configuration, and meets the needs of our customers.

\ No newline at end of file diff --git a/software/guides/data-feed/index.html.gz b/software/guides/data-feed/index.html.gz index c6aef81eafe27f38cfb53cc1e6f203338438f322..4d58f79b8d30eada59cf3fe12cc5fb58b1e94dc7 100644 GIT binary patch literal 7468 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