diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 41be82ad..f46f19dc 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -44,7 +44,7 @@ jobs: flatpak build-bundle ${{ github.workspace }}/repo ${{ github.workspace }}/uk.co.piggz.amazfish.flatpak uk.co.piggz.amazfish - name: Upload Flatpak - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: - name: uk.co.piggz.amazfish.flatpak + pattern: uk.co.piggz.amazfish.flatpak path: uk.co.piggz.amazfish.flatpak \ No newline at end of file diff --git a/README.md b/README.md index 2c4b7722..eca1c472 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ These are devices I have, have tested, and will try not to break any functionali * Amazfit GTS * Amazfit GTR2 * Pinetime InfiniTime - * Bangle.js + * Bangle.js - [Android integration](https://gadgetbridge.org/gadgets/wearables/banglejs/) app should be installed ### Silver @@ -151,3 +151,9 @@ Credits to: The Gadgetbridge devs, which gave me a lot of hints and inspiration from their device code. https://codeberg.org/Freeyourgadget/Gadgetbridge + +## Automatic Reconnecting + +Depending on device and operating system if there are problems with pairing or reconnecting you may need to take one action. +Open the bluetooth settings on your phone and head for known devices. There enter the settings for the watch and enable "reconnect automatically" for it. +This should fix pairing and reconnecting issues. \ No newline at end of file diff --git a/daemon/daemon.pro b/daemon/daemon.pro index a817b09e..a51549c6 100644 --- a/daemon/daemon.pro +++ b/daemon/daemon.pro @@ -82,7 +82,7 @@ systemd_services.path = $$PREFIX/lib/systemd/user/ systemd_services.files = $$OUT_PWD/harbour-amazfish.service systemd_services.CONFIG += no_check_exist -chirp.path = $$PREFIX/share/harbour-amazfish/ +chirp.path = $$PREFIX/share/harbour-amazfishd/ chirp.files = chirp.raw #Install appropriate files for each system @@ -265,7 +265,16 @@ HEADERS += \ src/activitycoordinate.h TRANSLATIONS += \ - translations/harbour-amazfishd-cs.ts + translations/harbour-amazfishd-cs.ts \ + translations/harbour-amazfishd-de.ts \ + translations/harbour-amazfishd-es.ts \ + translations/harbour-amazfishd-fr.ts \ + translations/harbour-amazfishd-nl.ts \ + translations/harbour-amazfishd-pl.ts \ + translations/harbour-amazfishd-ru.ts \ + translations/harbour-amazfishd-sv.ts \ + translations/harbour-amazfishd-zh_Hans.ts + flavor_uuitk { DEFINES += TRANSLATION_FOLDER=\\\"/opt/click.ubuntu.com/uk.co.piggz.amazfish/current/translations\\\" diff --git a/daemon/src/deviceinterface.cpp b/daemon/src/deviceinterface.cpp index aefbe022..24531439 100644 --- a/daemon/src/deviceinterface.cpp +++ b/daemon/src/deviceinterface.cpp @@ -696,9 +696,9 @@ void DeviceInterface::findDevice() #ifdef MER_EDITION_SAILFISH - QFile file("/usr/share/harbour-amazfish/chirp.raw"); + QFile file("/usr/share/harbour-amazfishd/chirp.raw"); #else // elif defined(UUITK_EDITION) - QFile file("/opt/click.ubuntu.com/uk.co.piggz.amazfish/current/share/harbour-amazfish/chirp.raw"); + QFile file("/opt/click.ubuntu.com/uk.co.piggz.amazfish/current/share/harbour-amazfishd/chirp.raw"); #endif if(!file.open(QIODevice::ReadOnly)) diff --git a/daemon/src/devices/banglejsdevice.cpp b/daemon/src/devices/banglejsdevice.cpp index 73bba5f3..36dea5ed 100644 --- a/daemon/src/devices/banglejsdevice.cpp +++ b/daemon/src/devices/banglejsdevice.cpp @@ -233,10 +233,10 @@ void BangleJSDevice::sendWeather(CurrentWeather *weather) QJsonObject o; o.insert("t", "weather"); o.insert("temp", weather->temperature()); - o.insert("hum", weather->humidity()); + o.insert("hum", weather->humidity()); o.insert("txt", weather->description()); - o.insert("wind", weather->windSpeed()); - o.insert("wdir", weather->windDeg()); + o.insert("wind", weather->windSpeed()); + o.insert("wdir", weather->windDeg()); o.insert("loc", weather->city()->name()); uart->txJson(o); @@ -291,7 +291,7 @@ void BangleJSDevice::refreshInformation() QString BangleJSDevice::information(Info i) const { - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << i; if (i == INFO_BATTERY) { return QString::number(m_infoBatteryLevel); @@ -332,21 +332,51 @@ void BangleJSDevice::handleRxJson(const QJsonObject &json) m_infoBatteryLevel = json.value("bat").toInt(); emit informationChanged(INFO_BATTERY, QString::number(m_infoBatteryLevel)); } else if (t == "findPhone") { + bool running = json.value("n").toBool(); + qDebug() << "findPhone" << running; + if (running) { + emit deviceEvent(AbstractDevice::EVENT_FIND_PHONE); + } else { + emit deviceEvent(AbstractDevice::EVENT_CANCEL_FIND_PHONE); + } } else if (t == "music") { + QString music_action = json.value("n").toString(); + + if (music_action == "play") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_PLAY); + } else if (music_action == "pause") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_PAUSE); + } else if (music_action == "next") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_NEXT); + } else if (music_action == "previous") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_PREV); + } else if (music_action == "volumeup") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_VOLUP); + } else if (music_action == "volumedown") { + emit deviceEvent(AbstractDevice::EVENT_MUSIC_VOLDOWN); + } +// emit deviceEvent(AbstractDevice::EVENT_APP_MUSIC); - } else if (t == "call") { - - - } else if (t == "notify") { +// } else if (t == "call") { +// } else if (t == "notify") { + } else if (t == "act") { + long ts = json.value("ts").toInt(); // timestamp + int hrm = json.value("hrm").toInt(); // heart rate, + int stp = json.value("stp").toInt(); // steps + int mov = json.value("mov").toInt(); // movement intensity + int rt = json.value("rt").toInt(); - } else if (t == "act") { + qDebug() << "parsed type = act " << ts << hrm << stp << mov << rt; + emit informationChanged(INFO_HEARTRATE, QString("%1").arg(hrm)); + emit informationChanged(INFO_STEPS, QString("%1").arg(stp)); } else { + qDebug() << "Gadgetbridge type " << t; } #if 0 diff --git a/daemon/src/services/uartservice.cpp b/daemon/src/services/uartservice.cpp index 260fa01d..8f06e1b6 100644 --- a/daemon/src/services/uartservice.cpp +++ b/daemon/src/services/uartservice.cpp @@ -56,7 +56,7 @@ void UARTService::handleRx(const QString &json) if (json.contains( "Uncaught ReferenceError: \"gb\" is not defined")) { emit message("Gadgetbridge plugin not installed on Bangle.js"); - } else if (json.at(0)=='{') { + } else if ((json.length() > 0) && (json.at(0)=='{')) { // JSON - we hope! QJsonObject obj = ObjectFromString(json); emit jsonRx(obj); diff --git a/daemon/translations/harbour-amazfishd-de.ts b/daemon/translations/harbour-amazfishd-de.ts index 21dd0cb3..62c489ef 100644 --- a/daemon/translations/harbour-amazfishd-de.ts +++ b/daemon/translations/harbour-amazfishd-de.ts @@ -5,143 +5,143 @@ AbstractDevice Device does not support settings - + Das Gerät unterstützt keine Einstellungen AsteroidOSDevice Stored %1... - + Gespeichert %1... BipDevice Navigation Started - + Navigation gestartet Navigation Stopped - + Navigation gestoppt Progress - + Fortschritt BipFirmwareService An operation is currently running, please try later - + Ein Vorgang wird derzeit ausgeführt, bitte versuchen Sie es später Sending %1... - + %1 wird gesendet... No file selected - + Keine Datei ausgewählt DeviceInterface Device is not valid, it may not be supported - + Das Gerät ist ungültig und wird möglicherweise nicht unterstützt Amazfish - + Amazfish Connected - + Verbunden Phone and watch are connected - + Telefon und Uhr sind verbunden Low Battery - + Schwache Batterie Battery level now - + Akkustand jetzt DfuService An operation is currently running, please try later - + Ein Vorgang wird derzeit ausgeführt, bitte versuchen Sie es später No file selected - + Keine Datei ausgewählt HuamiDevice Navigation Started - + Navigation gestartet Navigation Stopped - + Navigation gestoppt Progress - + Fortschritt MiBandService Firmware is too old to set display items, V0.1.1.14 is required - + Die Firmware ist zu alt, um Anzeigeelemente zu setzen, V0.1.1.14 wird benötigt An operation is currently running, please try later - + Ein Vorgang wird derzeit ausgeführt, bitte versuchen Sie es später QObject About to transfer data from - + Über das Übertragen von Daten aus Finished transferring activity data - + Übergabe der Vorgangsdaten abgeschlossen No data to transfer - + Es müssen keine Daten übertragen werden Update operation failed - + Fehler beim Aktualisierungsvorgang Update operation failed, unexpected metadata - + Fehler beim Updatevorgang, unerwartete Metadaten Update operation complete - + Updatevorgang abgeschlossen Update operation failed, filetype not supported - + Fehler beim Update-Vorgang, Dateityp wird nicht unterstützt File does not seem to be supported - + Datei scheint nicht unterstützt zu werden diff --git a/documentation/build-instructions.md b/documentation/build-instructions.md index 099df9d6..4af10c48 100644 --- a/documentation/build-instructions.md +++ b/documentation/build-instructions.md @@ -9,6 +9,7 @@ build target which are not available by default. To get into the build machine (if started by Sailfish IDE) `ssh -l mersdk localhost -p 2222 -i ~/SailfishOS/vmshare/ssh/private_keys/engine/mersdk` +or `sfdk engine exec` with docker based builder Use the `sb2-config` command to make your ARM target the default diff --git a/qble b/qble index c2ecbff0..eb1177db 160000 --- a/qble +++ b/qble @@ -1 +1 @@ -Subproject commit c2ecbff041b0e6416f04d1af6bf102ced1bc447c +Subproject commit eb1177dbd7aef81b25e8217319afbe754aa17782 diff --git a/rpm/harbour-amazfish.spec b/rpm/harbour-amazfish.spec index 6a5d5217..bbadc16c 100644 --- a/rpm/harbour-amazfish.spec +++ b/rpm/harbour-amazfish.spec @@ -122,6 +122,6 @@ desktop-file-install --delete-original \ %{_datadir}/icons/hicolor/scalable/apps/%{name}-ui.svg %{_userunitdir}/harbour-amazfish.service %{_datadir}/mapplauncherd/privileges.d/harbour-amazfishd.privileges -%{_datadir}/harbour-amazfish/chirp.raw +%{_datadir}/harbour-amazfishd/chirp.raw # >> files # << files diff --git a/ui/qml/pages/FirstPage.qml b/ui/qml/pages/FirstPage.qml index e2964638..6854c27b 100644 --- a/ui/qml/pages/FirstPage.qml +++ b/ui/qml/pages/FirstPage.qml @@ -94,9 +94,8 @@ PagePL { anchors.rightMargin: 2 height: parent.height - 4 } - - } + RowLayout { height: styler.themeItemSizeSmall width: parent.width @@ -149,7 +148,6 @@ PagePL { } } - SectionHeaderPL { text: qsTr("Steps") visible: supportsFeature(Amazfish.FEATURE_STEPS) @@ -158,6 +156,8 @@ PagePL { // steps IconPL { id: imgSteps + anchors.left: parent.left + anchors.leftMargin: styler.themePaddingLarge iconName: styler.iconSteps height: styler.themeIconSizeMedium width: height @@ -208,6 +208,10 @@ PagePL { //Heartrate RowLayout { + anchors.left: parent.left + anchors.leftMargin: styler.themePaddingLarge + anchors.right: parent.right + anchors.rightMargin: styler.themePaddingLarge spacing: styler.themePaddingLarge width: parent.width visible: supportsFeature(Amazfish.FEATURE_HRM) @@ -270,8 +274,6 @@ PagePL { } } } - - } onPageStatusActive: { diff --git a/ui/qml/pages/Settings-app.qml b/ui/qml/pages/Settings-app.qml index d50e22b8..a9513b44 100644 --- a/ui/qml/pages/Settings-app.qml +++ b/ui/qml/pages/Settings-app.qml @@ -27,7 +27,12 @@ PagePL { textRole: "path" label: qsTr("BT Adapter") Component.onCompleted: { - cboLocalAdapter.value = AmazfishConfig.localAdapter; + for (var i = 0; i < adapters.rowCount(); i++) { + if (adapters.get(i).path == AmazfishConfig.localAdapter) { + cboLocalAdapter.currentIndex = i; + return + } + } } } diff --git a/ui/qml/pages/SleepPage.qml b/ui/qml/pages/SleepPage.qml index 0f95e890..9a26af49 100644 --- a/ui/qml/pages/SleepPage.qml +++ b/ui/qml/pages/SleepPage.qml @@ -19,14 +19,23 @@ PagePL { width: parent.width anchors.top: parent.top anchors.margins: styler.themePaddingMedium - spacing: styler.themePaddingLarge + spacing: styler.themePaddingMedium LabelPL { id: lblSleepLastnight - font.pixelSize: styler.themeFontSizeExtraLarge * 3 + font.pixelSize: styler.themeFontSizeExtraLarge * 2 anchors.horizontalCenter: parent.horizontalCenter width: parent.width - text: qsTr("%1 hrs").arg(parseFloat(Math.round(graphSleepSummary.lastY * 100) / 100).toFixed(2)) + text: qsTr("Total %1").arg(decimalToHourMin(graphSleepSummary.lastY + graphSleepSummary.lastZ)) + horizontalAlignment: Text.AlignHCenter + } + + LabelPL { + id: lblLightSleepLastnight + font.pixelSize: styler.themeFontSizeExtraLarge + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + text: qsTr("Light %1").arg(decimalToHourMin(graphSleepSummary.lastY)) horizontalAlignment: Text.AlignHCenter } @@ -35,7 +44,7 @@ PagePL { font.pixelSize:styler.themeFontSizeExtraLarge anchors.horizontalCenter: parent.horizontalCenter width: parent.width - text: qsTr("Deep %1 hrs").arg(parseFloat(Math.round(graphSleepSummary.lastZ * 100) / 100).toFixed(2)) + text: qsTr("Deep %1").arg(decimalToHourMin(graphSleepSummary.lastZ)) horizontalAlignment: Text.AlignHCenter } @@ -79,6 +88,14 @@ PagePL { graphSleepSummary.updateGraph(day); } + function decimalToHourMin(decTime) { + var totalMinutes = Math.round(decTime * 60); + var hours = Math.floor(totalMinutes / 60); + var minutes = (totalMinutes % 60).toString().padStart(2, '0'); + + return hours + ":" + minutes; + } + onPageStatusActive: { pushAttached(Qt.resolvedUrl("HeartratePage.qml")) } diff --git a/ui/qml/pages/SportPage.qml b/ui/qml/pages/SportPage.qml index 3f68e98b..3239f81a 100644 --- a/ui/qml/pages/SportPage.qml +++ b/ui/qml/pages/SportPage.qml @@ -61,6 +61,8 @@ PagePL { Layout.rowSpan: 3 Layout.preferredWidth: styler.themeItemSizeLarge Layout.preferredHeight: styler.themeItemSizeLarge + Layout.alignment: Qt.AlignLeft + Layout.leftMargin: styler.themePaddingLarge iconName: styler.customIconPrefix + "icon-m-" + getKindString(kindstring) + styler.customIconSuffix } diff --git a/ui/qml/pics/devices/asteroidos.png b/ui/qml/pics/devices/asteroidos.png index 46818a3d..e29a4e71 100644 Binary files a/ui/qml/pics/devices/asteroidos.png and b/ui/qml/pics/devices/asteroidos.png differ diff --git a/ui/translations/harbour-amazfish-ui-de.ts b/ui/translations/harbour-amazfish-ui-de.ts index 885e1dc2..01ddec36 100644 --- a/ui/translations/harbour-amazfish-ui-de.ts +++ b/ui/translations/harbour-amazfish-ui-de.ts @@ -73,11 +73,11 @@ BatteryPage Battery - + Batterie %1 % - + %1 % @@ -126,27 +126,27 @@ Address: - Adresse: + Adresse: Serial No: - Serien Nr: + Serien Nr: Hardware Rev: - Hardware Rev: + Hardware Rev: Software Rev: - Software Rev: + Software Rev: Connection State: - Verbindungsstatus: + Verbindungsstatus: GPS Ver: - GPS Ver: + GPS Ver: Test Notification @@ -214,31 +214,31 @@ Request Screenshot - + Bildschirmfoto anfordern Somebody - + Jemand Title - + Titel Hello from Sailfish OS. This is a long message sent over BLE! - + Hallo von Sailfish OS. Dies ist eine lange Nachricht, die über BLE gesendet wurde! Donald Duck - + Donald Duck Hello, this is an email from Sailfish OS! - + Hallo, dies ist eine E-Mail von Sailfish OS! Test Immediate Alert Service - + Testen des Sofortwarndienstes @@ -296,7 +296,7 @@ Enable on boot - + Beim Booten aktivieren @@ -342,7 +342,7 @@ %1 bpm - %1 bpm + %1 bpm @@ -408,7 +408,7 @@ Bluetooth adapter is not available - + Bluetooth-Adapter ist nicht verfügbar @@ -524,70 +524,70 @@ Simulate event reminder support - + Simulieren der Unterstützung von Ereigniserinnerungen Button Actions - + Tasten-Aktionen Refresh weather every (%1) minutes - + Wetter alle (%1) Minuten aktualisieren Refresh calendar every (%1) minutes - + Aktualisieren des Kalenders alle (%1) Minuten Transliterate notifications - + Transkribieren von Benachrichtigungen Settings-button-action Button Actions - + Tasten-Aktionen Double Press Action - + Aktion mit doppelter Pressung Triple Press Action - + Dreifache Druckaktion Quad Press Action - + Quad-Presse-Aktion Save Settings - Einstellungen speichern + Einstellungen speichern No Action - + Keine Aktion Next Track - + Nächster Titel Previous Track - + Vorheriger Track Volume Up - + Lautstärke erhöhen Volume Down - + Lautstärke verringern Custom Script - + Benutzerdefiniertes Skript @@ -682,22 +682,22 @@ Huami Display Items - + Huami-Ausstellungsstücke nl_NL - + nl_NL Realtime HRM measurement - + HRM-Messung in Echtzeit Settings-huami-shortcuts Huami Display Items - + Huami-Ausstellungsstücke Save Settings @@ -793,7 +793,7 @@ Timer - + Zeitschaltuhr @@ -832,7 +832,7 @@ Strava - + Strava @@ -919,15 +919,15 @@ Off - + Aus On - + Auf Schedule - + Zeitplan @@ -951,11 +951,11 @@ %1 hrs - + %1 Std Deep %1 hrs - + Tiefe %1 Std @@ -1034,23 +1034,23 @@ Average Stroke - + Durchschnittlicher Hub Average Stroke/s - + Durchschnittlicher Hub/s Average Lap Pace - + Durchschnittliche Rundenpace Strokes - + Schläge SWOLF Index - + SWOLF Index Swim Style @@ -1058,31 +1058,31 @@ Laps - + Schöße Max Latitude - + Maximaler Breitengrad Min Latitude - + Min Breitengrad Max Longitude - + Max. Längengrad Min Longitude - + Min. Längengrad Max Speed - + Maximale Geschwindigkeit Total Stride - + Gesamtschritt steps @@ -1090,7 +1090,7 @@ seconds - + Nachschlag kcal @@ -1098,39 +1098,39 @@ meters - + Meter seconds/m - + Sekunden/m bpm - + bpm seconds/km - + Sekunden/km cm - + cm strokes/s - + Hübe/s strokes - + Schläge swolf - + Swolf Send to Strava - + An Strava senden @@ -1145,7 +1145,7 @@ Remove - + Entfernen @@ -1159,86 +1159,86 @@ StravaSettingsPage Strava settings - + Strava-Einstellungen Logout - + Abmeldung Login - + Login User Name: - + Benutzername: Country: - + Land: not logged in - + nicht eingeloggt StravaUploadPage Strava Upload - + Strava-Hochladen Activity name for Strava - + Name der Aktivität für Strava Name - + Name Description - + Beschreibung Activity description for Strava - + Aktivitätsbeschreibung für Strava Type (Strava) - + Typ (Strava) Private - + Privat Commute - + Pendeln Upload - + Hochladen Uploading data... - + Daten werden hochgeladen... Checking upload... - + Hochladen wird überprüft... TCX uploaded... - + TCX hochgeladen... Activity upload complete - + Hochladen der Aktivität abgeschlossen An unknown error occurred - + Ein unbekannter Fehler ist aufgetreten diff --git a/ui/ui.pro b/ui/ui.pro index 359241c4..5cdca37c 100644 --- a/ui/ui.pro +++ b/ui/ui.pro @@ -172,6 +172,7 @@ TRANSLATIONS += \ translations/harbour-amazfish-ui-de.ts \ translations/harbour-amazfish-ui-es.ts \ translations/harbour-amazfish-ui-fr.ts \ + translations/harbour-amazfish-ui-nb_NO.ts \ translations/harbour-amazfish-ui-nl.ts \ translations/harbour-amazfish-ui-pl.ts \ translations/harbour-amazfish-ui-ru.ts \