-
-
Notifications
You must be signed in to change notification settings - Fork 22
/
import_data.sh
251 lines (231 loc) · 13.2 KB
/
import_data.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/bin/bash
# Version Info
echo -e "\n============================================="
echo -e "Export 2 Garmin Connect v2.2 (import_data.sh)"
echo -e "=============================================\n"
# Blocking multiple instances of same script process
timenow() {
date +%d.%m.%Y-%H:%M:%S
}
remove_lock() {
rm -f "/dev/shm/export.lock"
}
another_instance() {
echo "$(timenow) SYSTEM * Another import_data.sh instance running"
exit 1
}
lockfile -r 0 -l 60 "/dev/shm/export.lock" || another_instance
trap remove_lock EXIT
# Create a loop, "-l" parameter executes loop indefinitely
path=$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)
source <(grep switch_ $path/user/export2garmin.cfg)
loop_count=1
found_count=0
[[ $1 == "-l" ]] && loop_count=0
i=0
while [[ $loop_count -eq 0 ]] || [[ $i -lt $loop_count ]] ; do
((i++))
# Verifying correct working of BLE, restart bluetooth service and device via miscale_ble.py
if [[ $switch_miscale == "on" && $switch_mqtt == "off" ]] || [[ $switch_omron == "on" ]] ; then
unset $(compgen -v | grep '^ble_')
echo "$(timenow) SYSTEM * BLE adapter enabled in export2garmin.cfg, check if available"
ble_check=$(python3 -B $path/miscale/miscale_ble.py)
if echo $ble_check | grep -q "failed" ; then
echo "$(timenow) SYSTEM * BLE adapter not working, skip scanning check if temp.log exists"
else ble_status=ok
hci_mac=$(echo $ble_check | grep -o 'h.\{21\})' | head -n 1)
echo "$(timenow) SYSTEM * BLE adapter $hci_mac working, check if temp.log exists"
fi
else echo "$(timenow) SYSTEM * BLE adapter not enabled or incorrect configuration in export2garmin.cfg, check if temp.log exists"
fi
# Create temp.log file if it exists cleanup after last startup
if [[ $switch_miscale == "on" ]] || [[ $switch_omron == "on" ]] ; then
if [[ ! -f /dev/shm/temp.log ]] ; then
echo "$(timenow) SYSTEM * Creating temp.log file, go to modules"
echo > /dev/shm/temp.log
else echo "$(timenow) SYSTEM * temp.log file exists, go to modules"
> /dev/shm/temp.log
fi
fi
# Mi Body Composition Scale 2
if [[ $switch_miscale == "on" ]] ; then
miscale_backup=$path/user/miscale_backup.csv
echo "$(timenow) MISCALE * Module is on"
# Creating miscale_backup.csv file
if [[ ! -f $miscale_backup ]] ; then
miscale_header="Data Status;Unix Time;Date [dd.mm.yyyy];Time [hh:mm];Weight [kg];Change [kg];BMI;Body Fat [%];Skeletal Muscle Mass [kg];Bone Mass [kg];Body Water [%];Physique Rating;Visceral Fat;Metabolic Age [years];BMR [kCal];LBM [kg];Ideal Wieght [kg];Fat Mass To Ideal [type:mass kg];Protein [%];Impedance;Email User;Upload Date [dd.mm.yyyy];Upload Time [hh:mm];Difference Time [s]"
[[ $switch_mqtt == "on" ]] && miscale_header="$miscale_header;Battery [V];Battery [%]"
echo "$(timenow) MISCALE * Creating miscale_backup.csv file, checking for new data"
echo $miscale_header > $miscale_backup
else echo "$(timenow) MISCALE * miscale_backup.csv file exists, checking for new data"
fi
# Importing raw data from source (BLE or MQTT)
if [[ $switch_mqtt == "on" ]] ; then
source <(grep miscale_mqtt_ $path/user/export2garmin.cfg)
echo "$(timenow) MISCALE * Importing data from an MQTT broker"
miscale_read=$(mosquitto_sub -h localhost -t 'data' -u "$miscale_mqtt_user" -P "$miscale_mqtt_passwd" -C 1 -W 10)
miscale_unixtime=$(echo $miscale_read | cut -d ";" -f 1)
if [[ -z $miscale_unixtime ]] ; then
echo "$(timenow) MISCALE * No MQTT data, check connection to MQTT broker or ESP32"
fi
elif [[ $ble_status == "ok" ]] ; then
echo "$(timenow) MISCALE * Importing data from a BLE adapter"
if echo $ble_check | grep -q "incomplete" ; then
echo "$(timenow) MISCALE * Reading BLE data incomplete, repeat weighing"
else miscale_read=$(echo $ble_check | awk '{sub(/.*BLE scan/, ""); print substr($1,1)}')
miscale_unixtime=$(echo $miscale_read | cut -d ";" -f 1)
fi
fi
# Check time synchronization between scale and OS
if [[ -n $miscale_unixtime ]] ; then
source <(grep miscale_time_ $path/user/export2garmin.cfg)
miscale_os_unixtime=$(date +%s)
miscale_time_zone=$(date +%z | cut -c1-3)
miscale_offset_unixtime=$(( $miscale_unixtime + $miscale_time_zone * 3600 + $miscale_time_offset ))
miscale_time_shift=$(( $miscale_os_unixtime - $miscale_offset_unixtime ))
miscale_absolute_shift=${miscale_time_shift#-}
if (( $miscale_absolute_shift < $miscale_time_unsync )) ; then
miscale_found_entry=false
# Check for duplicates, similar raw data in miscale_backup.csv file
while IFS=";" read -r _ unix_time _ ; do
if [[ $unix_time =~ ^[0-9]+$ ]] ; then
miscale_time_dif=$(($miscale_offset_unixtime - $unix_time))
miscale_time_dif=${miscale_time_dif#-}
if (( $miscale_time_dif < $miscale_time_check )) ; then
miscale_found_entry=true
break
fi
fi
done < $miscale_backup
# Save raw data to miscale_backup.csv file
if [[ $miscale_found_entry == "false" ]] ; then
echo "$(timenow) MISCALE * Saving import $miscale_offset_unixtime to miscale_backup.csv file"
miscale_offset_row=${miscale_read/${miscale_unixtime}/to_import;${miscale_offset_unixtime}}
echo $miscale_offset_row >> $miscale_backup
else echo "$(timenow) MISCALE * $miscale_time_dif s time difference, same or similar data already exists in miscale_backup.csv file"
fi
else echo "$(timenow) MISCALE * $miscale_time_shift s time difference, synchronize date and time scale"
echo "$(timenow) MISCALE * Time offset is set to $miscale_offset s"
fi
fi
# Calculating data and upload to Garmin Connect, print to temp.log file
if grep -q "failed\|to_import" $miscale_backup ; then
python3 -B $path/miscale/miscale_export.py > /dev/shm/temp.log 2>&1
miscale_import=$(awk -F ": " '/MISCALE /*/ Import data:/{print substr($2,1,10)}' /dev/shm/temp.log)
echo "$(timenow) MISCALE * Calculating data from import $miscale_import, upload to Garmin Connect"
fi
# Handling errors from temp.log file
if [[ -z $miscale_import ]] ; then
echo "$(timenow) MISCALE * There is no new data to upload to Garmin Connect"
elif grep -q "MISCALE \* There" /dev/shm/temp.log ; then
echo "$(timenow) MISCALE * There is no user with given weight or undefined user email@email.com, check users section in export2garmin.cfg"
echo "$(timenow) MISCALE * Deleting import $miscale_import from miscale_backup.csv file"
sed -i "/$miscale_import/d" $miscale_backup
elif grep -q "Err" /dev/shm/temp.log ; then
echo "$(timenow) MISCALE * Upload to Garmin Connect has failed, check temp.log for error details"
sed -i "s/to_import;$miscale_import/failed;$miscale_import/" $miscale_backup
else echo "$(timenow) MISCALE * Data upload to Garmin Connect is complete"
# Save calculated data to miscale_backup.csv file
echo "$(timenow) MISCALE * Saving calculated data from import $miscale_import to miscale_backup.csv file"
miscale_import_data=$(awk -F ": " '/MISCALE /*/ Import data:/{print $2}' /dev/shm/temp.log)
miscale_calc_data=$(awk -F ": " '/MISCALE /*/ Calculated data:/{print $2}' /dev/shm/temp.log)
miscale_import_diff=$(echo $miscale_calc_data | cut -d ";" -f 1-3)
miscale_check_line=$(wc -l < $miscale_backup)
sed -i "s/failed;$miscale_import_data/uploaded;$miscale_import;$miscale_calc_data;$miscale_time_shift/; s/to_import;$miscale_import_data/uploaded;$miscale_import;$miscale_calc_data;$miscale_time_shift/" $miscale_backup
if [[ $miscale_check_line == "2" ]] ; then
sed -i "s/$miscale_import;$miscale_import_diff/$miscale_import;$miscale_import_diff;0.0/" $miscale_backup
else miscale_email_user=$(echo $miscale_calc_data | cut -d ";" -f 18)
miscale_weight_last=$(grep $miscale_email_user $miscale_backup | sed -n 'x;$p' | cut -d ";" -f 5)
miscale_weight_import=$(echo $miscale_calc_data | cut -d ";" -f 3)
miscale_weight_diff=$(echo $miscale_weight_import - $miscale_weight_last | bc | sed "s/^-\./-0./; s/^\./0./")
sed -i "s/$miscale_import;$miscale_import_diff/$miscale_import;$miscale_import_diff;$miscale_weight_diff/; s/;0;/;0.0;/" $miscale_backup
fi
fi
unset $(compgen -v | grep '^miscale_')
else echo "$(timenow) MISCALE * Module is off"
fi
# Omron blood pressure
if [[ $switch_omron == "on" ]] ; then
omron_backup=$path/user/omron_backup.csv
echo "$(timenow) OMRON * Module is on"
# Creating omron_backup.csv file
if [[ ! -f $omron_backup ]] ; then
echo "Data Status;Unix Time;Date [dd.mm.yyyy];Time [hh:mm];SYStolic [mmHg];DIAstolic [mmHg];Heart Rate [bpm];Category;MOV;IHB;Email User;Upload Date [dd.mm.yyyy];Upload Time [hh:mm];Difference Time [s]" > $omron_backup
echo "$(timenow) OMRON * Creating omron_backup.csv file, checking for new data"
else echo "$(timenow) OMRON * omron_backup.csv file exists, checking for new data"
fi
# Importing raw data from source (BLE)
if [[ $ble_status == "ok" ]] ; then
echo "$(timenow) OMRON * Importing data from a BLE adapter"
coproc ble { bluetoothctl; }
while true ; do
source <(grep omron_omblepy_ $path/user/export2garmin.cfg)
omron_hci=$(echo $ble_check | grep -o 'hci.' | head -n 1)
omron_omblepy_check=$(timeout ${omron_omblepy_time}s python3 -B $path/omron/omblepy.py -a $omron_hci -p -d $omron_omblepy_model 2> /dev/null)
if echo $omron_omblepy_check | grep -q $omron_omblepy_mac ; then
# Adding an exception for selected models
if [[ $omron_omblepy_model == "hem-6232t" ]] || [[ $omron_omblepy_model == "hem-7530t" ]] ; then
omron_omblepy_flags="-n"
else omron_omblepy_flags="-n -t"
fi
if [[ $omron_omblepy_debug == "on" ]] ; then
python3 -B $path/omron/omblepy.py -a $omron_hci -d $omron_omblepy_model --loggerDebug -m $omron_omblepy_mac
elif [[ $omron_omblepy_all == "on" ]] ; then
python3 -B $path/omron/omblepy.py -a $omron_hci -d $omron_omblepy_model -m $omron_omblepy_mac >/dev/null 2>&1
else python3 -B $path/omron/omblepy.py $omron_omblepy_flags -a $omron_hci -d $omron_omblepy_model -m $omron_omblepy_mac >/dev/null 2>&1
fi
else exec {ble[0]}>&-
exec {ble[1]}>&-
wait $ble_PID
break
fi
done
if [[ -f "/dev/shm/omron_user1.csv" ]] || [[ -f "/dev/shm/omron_user2.csv" ]] ; then
source <(grep omron_export_user $path/user/export2garmin.cfg)
echo "$(timenow) OMRON * Prepare data for omron_backup.csv file"
awk -F ';' 'NR==FNR{a[$2];next}!($2 in a)' $omron_backup /dev/shm/omron_user1.csv > /dev/shm/omron_users.csv
awk -F ';' 'NR==FNR{a[$2];next}!($2 in a)' $omron_backup /dev/shm/omron_user2.csv >> /dev/shm/omron_users.csv
sed -i "s/ /;/g; s/user1/$omron_export_user1/; s/user2/$omron_export_user2/" /dev/shm/omron_users.csv
grep -q "email@email.com" /dev/shm/omron_users.csv && echo "$(timenow) OMRON * Deleting records with undefined user email@email.com, check users section in export2garmin.cfg" && sed -i "/email@email\.com/d" /dev/shm/omron_users.csv
cat /dev/shm/omron_users.csv >> $omron_backup
rm /dev/shm/omron_user*.csv
fi
fi
# Upload to Garmin Connect, print to temp.log file
if grep -q "failed\|to_import" $omron_backup ; then
if [[ $switch_miscale == "on" ]] ; then
python3 -B $path/omron/omron_export.py >> /dev/shm/temp.log 2>&1
else python3 -B $path/omron/omron_export.py > /dev/shm/temp.log 2>&1
fi
omron_import=$(awk -F ": " '/OMRON /*/ Import data:/{print substr($2,1,10)}' /dev/shm/temp.log)
echo "$(timenow) OMRON * Calculating data from import $omron_import, upload to Garmin Connect"
fi
# Handling errors, save data to omron_backup.csv file
if [[ -z $omron_import ]] ; then
echo "$(timenow) OMRON * There is no new data to upload to Garmin Connect"
else omron_import_data=$(awk -F ": " '/OMRON /*/ Import data:/{print $2}' /dev/shm/temp.log)
omron_cut_data=$(echo $omron_import_data | cut -d ";" -f 1-6)
omron_calc_data=$(awk -F ": " '/OMRON /*/ Calculated data:/{print $2}' /dev/shm/temp.log)
omron_os_unixtime=$(date +%s)
omron_time_shift=$(( $omron_os_unixtime - $omron_import ))
if grep -q "Err" /dev/shm/temp.log ; then
if grep -q "MISCALE \* Upload" /dev/shm/temp.log ; then
echo "$(timenow) OMRON * Upload to Garmin Connect has failed, check temp.log for error details"
sed -i "s/to_import;$omron_import/failed;$omron_import/" $omron_backup
elif grep -q "OMRON \* Upload" /dev/shm/temp.log ; then
echo "$(timenow) OMRON * Data upload to Garmin Connect is complete"
echo "$(timenow) OMRON * Saving calculated data from import $omron_import to omron_backup.csv file"
sed -i "s/failed;$omron_import_data/uploaded;omron_cut_data;$omron_calc_data;$omron_time_shift/; s/to_import;$omron_import_data/uploaded;$omron_cut_data;$omron_calc_data;$omron_time_shift/" $omron_backup
else echo "$(timenow) OMRON * Upload to Garmin Connect has failed, check temp.log for error details"
sed -i "s/to_import;$omron_import/failed;$omron_import/" $omron_backup
fi
else echo "$(timenow) OMRON * Data upload to Garmin Connect is complete"
echo "$(timenow) OMRON * Saving calculated data from import $omron_import to omron_backup.csv file"
sed -i "s/failed;$omron_import_data/uploaded;omron_cut_data;$omron_calc_data;$omron_time_shift/; s/to_import;$omron_import_data/uploaded;$omron_cut_data;$omron_calc_data;$omron_time_shift/" $omron_backup
fi
fi
unset $(compgen -v | grep '^omron_')
else echo "$(timenow) OMRON * Module is off"
fi
[[ $loop_count -eq 1 ]] && break
done