# TeltonikaCodec
[](https://hex.pm/packages/teltonika_codec)
[](https://github.com/neilberkman/teltonika_codec/actions/workflows/elixir.yml)
Teltonika GPS tracker protocol parser for Elixir. Decodes Codec 8, Codec 8 Extended, and Codec 16 binary protocols used by Teltonika devices (TAT141, FMB920, FMC130, TMT250, etc.).
## Installation
Add `teltonika_codec` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:teltonika_codec, "~> 0.1.0"}
]
end
```
## Usage
### Parse IMEI handshake
```elixir
{:ok, imei} = TeltonikaCodec.parse_imei(data)
# {:ok, "352093085698206"}
```
### Parse data packet
Auto-detects the codec (8, 8 Extended, or 16) and returns parsed AVL records:
```elixir
{:ok, records} = TeltonikaCodec.parse_packet(packet)
Enum.each(records, fn record ->
IO.inspect(record.latitude) # 42.373737
IO.inspect(record.longitude) # 42.373737
IO.inspect(record.speed) # 0
IO.inspect(record.timestamp) # ~U[2024-01-15 14:30:00.000Z]
IO.inspect(record.io_elements) # %{elements_1b: %{21 => 3}, ...}
end)
```
### TCP buffer management
Use `check_packet/1` to accumulate TCP data until a complete frame arrives:
```elixir
case TeltonikaCodec.check_packet(buffer) do
{:complete, packet, rest} ->
{:ok, records} = TeltonikaCodec.parse_packet(packet)
# Send ACK so the device stops retransmitting
:gen_tcp.send(socket, TeltonikaCodec.ack(length(records)))
# Continue with remaining buffer
handle_data(rest)
:incomplete ->
# Wait for more data
{:noreply, state}
end
```
### IMEI accept/reject
```elixir
:gen_tcp.send(socket, TeltonikaCodec.imei_accept()) # <<0x01>>
:gen_tcp.send(socket, TeltonikaCodec.imei_reject()) # <<0x00>>
```
## Supported Codecs
| Codec | ID | IO ID Size | IO Count Size | Variable IO | Generation Type |
| ----- | ---- | ---------- | ------------- | ----------- | --------------- |
| 8 | 0x08 | 1 byte | 1 byte | No | No |
| 8 Ext | 0x8E | 2 bytes | 2 bytes | Yes (NX) | No |
| 16 | 0x10 | 2 bytes | 1 byte | No | Yes |
## AVL Record Fields
Each parsed record contains:
| Field | Type | Description |
| ------------- | ------------------------- | ---------------------- |
| `timestamp` | `DateTime.t()` | GPS fix time |
| `latitude` | `float` | Decimal degrees |
| `longitude` | `float` | Decimal degrees |
| `altitude` | `integer` | Meters |
| `heading` | `integer` | Degrees (0-360) |
| `speed` | `integer` | km/h |
| `satellites` | `integer` | Visible GPS satellites |
| `priority` | `:low \| :high \| :panic` | Record priority |
| `io_elements` | `map` | I/O element groups |
## Protocol Reference
Based on the [Teltonika Codec](https://wiki.teltonika-gps.com/view/Codec) documentation.
## License
Apache-2.0