openambitproject / openambit

openambit
277 stars 82 forks source link

wrong read if memory is near limit #273

Open fmoerl-real opened 3 years ago

fmoerl-real commented 3 years ago

Due to incapability of a sync to movescount, my Ambit 2 did not get the flag, that activities were synchronised. Now, almost 95% of memory usage, the last read of an activity by openambit-cli results in a mix of current and old data, almost 1/3 of my activity was flawed. I can provide the activity if necessary.

To solve this problem, my only option was to use another computer with suuntolink. Sunntolink read the data correctly. So my request is to implement a sync-flag for removing the "please sync to movescount" message, and, more important, to resolve the wrong reading error.

Gerold-R commented 3 years ago

Normally activities are marked as synced using the command 0x0B 0x1B. No parameter is needed and all activities without the sync flag set are marked as synced. Before calling this command, I usually put the watch into sync mode ("M sync" is shown in the display) using the command 0x0B 0x1A with parameter 0x0001 (to disable sync mode: 0x0000).

Since a couple of days syncing activities results in gateway timeouts. Even with the app key from SuuntoLink. So it's not possible anymore to sync to Movescount. Does OpenAmbit call the command 0x0B 0x1B even if there are errors after sending an activity to Movescount?

Maybe you can write a small program to mark all logs as synced. All commands you need are:

0x00 0x00 - Get device information 0x0B 0x1A - Enable sync mode (parameter 0x0001) 0x0B 0x1B - Mark all logs as synced 0x0B 0x1A - Disable sync mode (parameter 0x0000)

fmoerl-real commented 3 years ago

Hi Gerold, just for a better understanding: The commands would be options while using openambit-cli or options for new code for openambit-cli?

Gerold-R commented 3 years ago

No these are the commands send to watch inside the USB reports. You're just using another format in OpenAmbit as I do in my Delphi programs.

You can find the commands in protocol.h

enum ambit_commands_e { ambit_command_device_info = 0x0000, ambit_command_lock_set = 0x0b1a, ambit_command_write_start = 0x0b1b, // Really!? Just a guess...

and the function which uses these commands int libambit_protocol_command(... in protocol.c

fmoerl-real commented 3 years ago

OK, thanks for the hint. If I find some motivation, I try to change some code and try it out on my watch. This will not resolve the wrong reading, if the memory of the watch is near limit. Further, the initial developers are off, that is, this project is near dead?

centic9 commented 3 years ago

I am not the intial devleoper, but plan to support the project as long as I use the Suunto Ambit 2 watches myself. Mostly smaller fixes and useful PRs, maybe some more functionality to the cli-tool over time as I mostly stopped using the GUI myself.

As I don't not much about the actual communicatoin-protocol to the watch, I cannot offer much there, but will accept patches and suggestions if I can.

So if you can provide patches for fixes for the memory issues I will surely apply them. Also if there is a way to reproduce the problem a bit more easily, I can see if I can spend some time to narrow down issues.

fmoerl-real commented 3 years ago

Hi centic, so is my impression, as long there is usage of the watch, there is motivation to do something on this project.

I am familiar with C/C++ and Qt too, the time before Movescount, I wrote a prototype to read data from the Suunto T6, the process to send bytes to the watch is comparable to the process openambit is handling the ambit watches. But, currently, I have only a very brief overview of the code, it is alway hard to understand someone others programs. Gerolds hint to protocol.c seems to be a beginning, the correct command for a "this move is synced" may resolve the wrong reading error.

Is there any possibility for a personal communication?

centic9 commented 3 years ago

We can continue discussion here as well, but I think my email address is in my github profile if you need to contact me directly.

paddy-hack commented 3 years ago

As I don't not much about the actual communicatoin-protocol to the watch, [...]

A few years ago, I started documenting the device protocol but got side-tracked. If there is interest, I might revive that project and get it to publish a static site documenting what is known about the protocol.

Now that Movescount is a goner, at least as far as uploading moves is concerned, I have become a bit more concerned about the status of this project (as well as related ones like openmoves) and may want to contribute again.

Gerold-R commented 3 years ago

@paddy-hack

This is the USB HID report format we use in our Delphi programs:

USB HID Report format:
======================

Report-Header:
- ReportID          BYTE    0x3F
- ReportSize        BYTE    Max. 64 Bytes (value fom USB Descriptor)
Packet-Header:
- PacketID          BYTE    $5D for the first packet, $5E for subsequent packets
- PacketSize        BYTE    Size of Packet Data without Packet-Header and Frame-CRC
- PacketPartNo      WORD    No of packets for the first packet and current number for
                subsequent packets (Ex.: 10 and then 1..9)
- Header-CRC        WORD    CRC-16/CCITT-FALSE of Packet Header
Packet-Data:
- MsgID             BYTE    Command ID
- MsgSubId          BYTE    Command Sub-ID
- Flags             BYTE    Flags like "Packet origin" etc.
- ErrorFlags        BYTE    Error-Flags for response packets
- ConnectionId      WORD    0 for the QueryDevice-Report, than the value for
                ConnectionID from the QueryDevice Response
- PacketNo          WORD    Current PacketNo (increased for each WRITE)
- DataSize          DWORD   Size of data to send or received
- Data                  May be splitted into several packets
Packet-Frame CRC:
- Frame-CRC         WORD    CRC-16/CCITT-FALSE of Packet Header (w/o CRC) and Packet Data

Get USB Descriptor for Ambit 2S:
$ lsusb -vd 1493:001a

ConnectionID:
-------------
QueryDevice command (MsgID 0x00, MsgSubId 0x00) with ConnectionId 0 should be the first report 
send to the device and the ConnectionId from the response is used for all other reports send to 
the device.

Flags:
------
CMD_FLAG_PC           = 0x01 Set by PC (for reports to send)
CMD_FLAG_DEVICE       = 0x02 Set by Device (in received reports)
CMD_FLAG_REQUIRE_ACK  = 0x04 PC asks for ACK (for reports to send)
CMD_FLAG_ACK          = 0x08 ACK from Device (in received reports)

ErrorFlags:
-----------
ERROR_FLAG_NONE          = 0x00 OK
ERROR_FLAG_FAILED        = 0x01 Command execution failed
ERROR_FLAG_NOT_SUPPORTED = 0x02 Command not supported
ERROR_FLAG_RETRY         = 0x04 Command retry required

Report example to get the battery status (MsgID 0x03, MsgSubId 0x06):
---------------------------------------------------------------------

Request send to the device:

       RSize PktSize  HdrCRC   SubId ErrFlags PacketNo
       |     |        |        |     |        |
    3F 14 5D 0C 01 00 2D 8E 03 06 05 00 09 00 04 00 00 00 00 00 7E 52
    |     |     |           |     |     |           |           |
    RId   PktId PktPartNo   Id    Flags ConId       DataSize    FrameCRC

RSize    0x14   = 20 Bytes after the ReportHeader
PktSize  0x0C   = 12 Bytes after the PacketHeader w/o Packet-Frame CRC
Flags    0x05   = CMD_FLAG_PC + CMD_FLAG_REQUIRE_ACK
ConId    0x0009 = Value from QueryDevice response
PacketNo 0x0004 = Current packet number
DataSize 0

Response from the device:

       RSize PktSize  HdrCRC   SubId ErrFlags PacketNo          Data
       |     |        |        |     |        |                 |
    3F 18 5D 10 01 00 2F B8 03 06 0A 00 09 00 04 00 04 00 00 00 01 64 2D 01 A2 76
    |     |     |           |     |     |           |                       |
    RId   PktId PktPartNo   Id    Flags ConId       DataSize                FrameCRC

RSize    0x18       = 24 Bytes after the ReportHeader
PktSize  0x10       = 16 Bytes after the PacketHeader w/o Packet-Frame CRC
Flags    0x0A       = CMD_FLAG_DEVICE + CMD_FLAG_ACK
ErrFlags 0x00       = No errors during execution
ConId    0x0009     = Connection Id
PacketNo 0x0004     = Must match with the one from the request
DataSize 0x00000004 = 4 Bytes of data received
Data     0x01 = Battery is fully charged; 0x64 = 100% charged; 0x012D = 301 times fully charged

The format of the data received is not always easy to understand. Ambit 3 series users do have an advantage here, cause the command MsgId 0x11 MsgSubId 0x04 returns the descriptors for many data-id's stored in "SBEM0102" format. Together with command MsgId 0x12 MsgSubId 0x00 it's possible to read these data.

Example for getting the steps made for the last 30 days from the device:

Data-ID: 0x12F / 303
<QRY>
<PTH>sml.DeviceHistory.Histories.History.ActivitySummary.LastDays.Steps

[DEBUG] Sending report to device...
[DEBUG] Report sent. Size: 32 with data-id 0x012F (0xFF 0x2F 0x01)
[DEBUG] 3F 28 5D 20 01 00 8A 7D 12 00 05 00 09 00 09 00 14 00 00 00 00 00 00 00 01 00 0C 00 53 42 45 4D 30 31 30 32 FF 2F 01 00 93 F7
[DEBUG] Report received. Size: 54
[DEBUG] 3F 3E 5D 36 03 00 2B EA 12 00 0A 00 09 00 09 00 8A 00 00 00 00 00 00 00 01 00 53 42 45 4D 30 31 30 32 FF 2E 01 78 FF FF FF FF FF FF FF FF 75 38 00 00 86 2C 00 00 00 00 00 00 00 00 00 00 33 8F
[DEBUG] Report received. Size: 54
[DEBUG] 3F 3E 5E 36 01 00 95 17 3B 3B 00 00 00 00 00 00 24 35 00 00 39 30 00 00 01 2E 00 00 47 2F 00 00 1C 24 00 00 D9 4D 00 00 A4 21 00 00 5A 37 00 00 FF 49 00 00 6D 32 00 00 31 52 00 00 41 31 E4 6A
[DEBUG] Report received. Size: 42
[DEBUG] 3F 32 5E 2A 02 00 C4 74 00 00 AC 54 00 00 C6 3C 00 00 75 30 00 00 38 2F 00 00 00 00 00 00 21 42 00 00 00 00 00 00 3B 2E 00 00 00 00 00 00 00 00 00 00 99 E7

Size of received data: 0x78 = 120 bytes => 30 * DWORD (Steps for the last 30 days)

FF FF FF FF -> Initial value?
FF FF FF FF
75 38 00 00
86 2C 00 00
00 00 00 00
00 00 00 00
3B 3B 00 00
00 00 00 00
24 35 00 00
39 30 00 00
01 2E 00 00
47 2F 00 00
1C 24 00 00
D9 4D 00 00
A4 21 00 00
5A 37 00 00
FF 49 00 00
6D 32 00 00
31 52 00 00
41 31 00 00
AC 54 00 00
C6 3C 00 00
75 30 00 00
38 2F 00 00
00 00 00 00
21 42 00 00
00 00 00 00
3B 2E 00 00 -> $00002E3B -> 11835 Steps (value from the display just before midnight)
00 00 00 00
00 00 00 00

I am still using an Ambit 2 series, so not very helpfull in my case.

rnorris commented 3 years ago

Just for point of reference - my Ambit 3 Multisport has been showing a "please sync to movescount" message as the memory is full. However I have not encountered any data loss (of the new recording)/corruption - it seems to carry on recording - overwriting the oldest log. But I do use the GUI, not the CLI - presumably this shouldn't make a difference.