Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MEATER support #120

Merged
merged 1 commit into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 141 additions & 38 deletions de1plus/bluetooth.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,41 @@ proc decentscale_tare {} {
userdata_append "decentscale : tare" [list ble write $::de1(scale_device_handle) $::de1(suuid_decentscale) $::sinstance($::de1(suuid_decentscale)) $::de1(cuuid_decentscale_write) $::cinstance($::de1(cuuid_decentscale_write)) $tare] 0
}

### Meater

proc meater_enable_notifications {} {
if {$::de1(thermometer_device_handle) == 0 || $::settings(thermometer_bluetooth_type) != "apptionmeater"} {
return
}

if {[ifexists ::sinstance($::de1(suuid_decentscale))] == ""} {
Mimoja marked this conversation as resolved.
Show resolved Hide resolved
msg "meater not connected, cannot enable weight notifications"
return
}

userdata_append "enable meater notifications" [list ble enable $::de1(thermometer_device_handle) $::de1(suuid_meater) $::sinstance($::de1(suuid_meater)) $::de1(cuuid_meater) $::cinstance($::de1(cuuid_meater))] 1
}

proc meater_parse_response { value } {
binary scan $value a2 raw
set temp [expr $raw / 16]

msg "Meater temperature is $temp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully PR #114 (Logging for v1.35) will be merged soon.

Would it be reasonable to put the MEATER-specific code into ::device::meater in device_meater.tcl or something similar?

This msg -DEBUG makes sense for early development, but probably needs a flag to disable or to be removed later on.

Passing in event_time, even if unused, means that later processing can know when the packet arrived for processing. Depending on how much is inline code of the handlers from previous packets, it can be delayed by 100-250 ms or more. I didn't convert all of the existing calls in bluetooth.tcl due to the number of changes. Right now, it's on a packet-by-packet basis, but I can definitely see puling events off the ble callback and onto the event queue if I can't get potentially slow things like skins_page_change_due_to_de1_state_change out of the BLE handler and onto the appropriate queue.

(Reminds me to try to get that onto an event. When I last tried, the GUI failed to render. Hmmm, now it works.)

(and you ruin a coffee because the timestamp fetch is done blocking and locks up the machine for 30 seconds)

In bluetooth.tcl:

   1194 proc de1_ble_handler { event data } {
   1195         #msg "de1 ble_handler '$event' [convert_string_to_hex $data]"
   1196         #set ::de1(wrote) 0
   1197 
   1198         set event_time [expr { [clock milliseconds] / 1000.0 }]

In device_scale.tcl:

    193         proc process_weight_update {reported_weight {event_time 0}} {
    194 
    195                 if { $event_time == 0 } {set event_time [expr { [clock milliseconds] / 1000.0 }]}

process_temperature_value $temp
}


### MISC

proc process_temperature_value {value} {
if {[::de1::state::current_substate] == "Steaming")} {
if {$value >= $::settings(target_milk_temperature)} {
msg -NOTICE [format "Steaming stopped for temperature at %.1f for target %.1f" $value $::settings(target_milk_temperature)
start_idle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To help prevent puzzles
msg -NOTICE [format "Steaming stopped for temperature at %.1f for target %.1f" $value $::settings(target_milk_temperature)

}
}
}

proc close_all_ble_and_exit {} {
::bt::msg -NOTICE close_all_ble_and_exit

Expand Down Expand Up @@ -723,6 +758,12 @@ proc close_all_ble_and_exit {} {
}
}

msg "Closing thermometer"
if {$::de1(scale_device_handle) != 0} {
catch {
ble close $::de1(thermometer_device_handle)
}
}

catch {
if {$::settings(ble_unpair_at_exit) == 1} {
Expand Down Expand Up @@ -1106,28 +1147,70 @@ proc ble_connect_to_scale {} {

}

proc append_to_scale_bluetooth_list {address name type} {
::bt::msg -NOTICE append_to_scale_bluetooth_list

set ::scale_types($address) $type
set ::currently_connecting_thermometer_handle 0
proc ble_connect_to_thermometer {} {

foreach { entry } $::scale_bluetooth_list {
if {$::de1(thermometer_device_handle) != 0} {
msg "Already connected to a thermometer, don't try again"
return
}

if {[ifexists ::de1(in_fw_update_mode)] == 1} {
msg "in_fw_update_mode : ble_connect_to_thermometer"
return
}


if {$::settings(thermometer_bluetooth_address) == ""} {
msg "No Thermometer BLE address in settings, so not connecting to it"
return
}

if {$::currently_connecting_thermometer_handle != 0} {
msg "Already trying to connect to Thermometer, so don't try again"
return
}

if {[llength $::de1(cmdstack)] > 2} {
msg -INFO "Too much backpressure, waiting with the connect"
after 300 ble_connect_to_thermometer
return
}

if {[catch {
set ::currently_connecting_thermometer_handle [ble connect [string toupper $::settings(thermometer_bluetooth_address)] de1_ble_handler false]
msg "Connecting to thermometer on $::settings(thermometer_bluetooth_address)"
set retcode 0
} err] != 0} {
set ::currently_connecting_thermometer_handle 0
set retcode 1
msg "Failed to start to BLE connect to scale because: '$err'"
}
return $retcode
}


proc append_to_peripheral_list {address name connectiontype devicetype devicefamily} {

::bt::msg -NOTICE append_to_peripheral_list
foreach { entry } $::peripheral_device_list {
if { [dict get $entry address] eq $address} {
return
}
}

if { $name == "" } {
set name $type
set name $devicefamily
}

set newlist $::scale_bluetooth_list
lappend newlist [dict create address $address name $name type $type]
set newlist $::peripheral_device_list
lappend newlist [dict create address $address name $name type $connectiontype devicetype $devicetype devicefamily $devicefamily]

::bt::msg -INFO "Scan found recognized scale at: $address ($type)"
set ::scale_bluetooth_list $newlist
::bt::msg -INFO "Scan found $connectiontype peripheral: $address ($type:$devicefamily)"
set ::peripheral_device_list $newlist
catch {
fill_ble_scale_listbox
fill_peripheral_listbox
}
}

Expand Down Expand Up @@ -1251,7 +1334,7 @@ proc de1_ble_handler { event data } {
}
}
} elseif {[string first Skale $name] == 0} {
append_to_scale_bluetooth_list $address $name "atomaxskale"
append_to_peripheral_list $address $name "ble" "scale" "atomaxskale"

if {$address == $::settings(scale_bluetooth_address)} {
if {$::currently_connecting_scale_handle == 0} {
Expand All @@ -1261,7 +1344,7 @@ proc de1_ble_handler { event data } {
}

} elseif {[string first "Decent Scale" $name] == 0} {
append_to_scale_bluetooth_list $address $name "decentscale"
append_to_peripheral_list $address $name "ble" "scale" "decentscale"

if {$address == $::settings(scale_bluetooth_address)} {
if {$::currently_connecting_scale_handle == 0} {
Expand All @@ -1270,7 +1353,7 @@ proc de1_ble_handler { event data } {
}
}
} elseif {[string first "FELICITA" $name] == 0} {
append_to_scale_bluetooth_list $address $name "felicita"
append_to_peripheral_list $address $name "ble" "scale" "felicita"

if {$address == $::settings(scale_bluetooth_address)} {
if {$::currently_connecting_scale_handle == 0} {
Expand All @@ -1279,7 +1362,7 @@ proc de1_ble_handler { event data } {
}
}
} elseif {[string first "HIROIA JIMMY" $name] == 0} {
append_to_scale_bluetooth_list $address $name "hiroiajimmy"
append_to_peripheral_list $address $name "ble" "scale" "hiroiajimmy"

if {$address == $::settings(scale_bluetooth_address)} {
if {$::currently_connecting_scale_handle == 0} {
Expand All @@ -1294,14 +1377,21 @@ proc de1_ble_handler { event data } {
if { [string first "PROCH" $name] != -1 } {
set ::settings(force_acaia_heartbeat) 1
}
append_to_scale_bluetooth_list $address $name "acaiascale"
append_to_peripheral_list $address $name "ble" "scale" "acaiascale"

if {$address == $::settings(scale_bluetooth_address)} {
if {$::currently_connecting_scale_handle == 0} {
::bt::msg -INFO "Not currently connecting to scale, so trying now"
ble_connect_to_scale
}
}
} elseif {[string first "MEATER" $name] == 0} {
if {$address == $::settings(thermometer_bluetooth_address)} {
if {$::currently_connecting_thermometer_handle == 0} {
msg "Not currently connecting to scale, so trying now"
ble_connect_to_thermometer
}
}
} else {
#
}
Expand All @@ -1313,6 +1403,14 @@ proc de1_ble_handler { event data } {

de1_disconnect_handler $handle

} elseif {$address == $::settings(scale_bluetooth_address)} {
catch {
ble close $::currently_connecting_thermometer_handle
}
set ::currently_connecting_thermometer_handle 0
if {$handle == $::de1(thermometer_device_handle)} {
set ::de1(thermometer_device_handle) 0
}
} elseif {$address == $::settings(scale_bluetooth_address)} {

#set ::de1(scale_type) ""
Expand Down Expand Up @@ -1345,7 +1443,6 @@ proc de1_ble_handler { event data } {

::device::scale::event::apply::on_disconnect_callbacks $event_dict


# john 1-11-19 automatic reconnection attempts eventually kill the bluetooth stack on android 5.1
# john might want to make this happen automatically on Android 8, though. For now, it's a setting, which might
# eventually get auto-set as per the current Android version, if we can trust that to give us a reliable BLE stack.
Expand All @@ -1365,10 +1462,6 @@ proc de1_ble_handler { event data } {
ble_connect_to_de1
}

#if {$::de1(scale_device_handle) == 0 && $::settings(scale_bluetooth_address) != "" && $::currently_connecting_scale_handle == 0} {
#userdata_append "connect to scale" ble_connect_to_scale
#ble_connect_to_scale
#}
}
set ::scanning 0
} elseif {$state eq "discovery"} {
Expand All @@ -1383,17 +1476,29 @@ proc de1_ble_handler { event data } {

de1_connect_handler $handle $address "DE1"

if {$::de1(scale_device_handle) != 0} {
if {$::de1(scale_device_handle) != 0 && $::de1(thermometer_device_handle) != 0 } {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a higher level, does it make sense to have a "check for" list somewhere so that the scanner can be stopped, at least at boot? Maybe stop if started from boot (or wake) if configured devices are all found?

I haven't watched in a lot of detail, but it seems that at least DSx dumps the whole set of shot frames and settings onto the BLE queue at load time, often even before the DE1 is connected. Maybe that's a different problem to resolve.

# if we're connected to both the scale and the DE1, stop scanning (or if there is not scale to connect to and we're connected to the de1)
stop_scanner
}

} elseif {$::de1(thermometer_device_handle) == 0 && $address == $::settings(thermometer_bluetooth_address)} {
set ::de1(thermometer_device_handle) $handle

} elseif {$::de1(scale_device_handle) == 0 && $address == $::settings(scale_bluetooth_address)} {
if {$::de1(device_handle) != 0 && $::de1(scale_device_handle) != 0} {
# if we're connected to both the scale and the DE1, stop scanning
stop_scanner
}

msg "thermometer '$::settings(thermometer_bluetooth_name)' connected $::settings(thermometer_bluetooth_address) $handle - $event $data"

if {$::settings(thermometer_bluetooth_type) == "apptionmeater"} {
append_to_peripheral_list $address $::settings(thermometer_bluetooth_name) "ble" "thermometer" "apptionmeater"
meater_enable_notifications
}

set ::currently_connecting_thermometer_handle 0

#append_to_scale_bluetooth_list $address [ifexists ::scale_types($address)]
#append_to_scale_bluetooth_list $address $::settings(scale_type)
} elseif {$::de1(scale_device_handle) == 0 && $address == $::settings(scale_bluetooth_address)} {

set ::de1(wrote) 0
set ::de1(scale_device_handle) $handle
Expand All @@ -1408,9 +1513,8 @@ proc de1_ble_handler { event data } {
set ::settings(scale_type) "atomaxskale"
}

#set ::de1(scale_type) [ifexists ::scale_types($address)]
if {$::settings(scale_type) == "decentscale"} {
append_to_scale_bluetooth_list $address $::settings(scale_bluetooth_name) "decentscale"
append_to_peripheral_list $address $::settings(scale_bluetooth_name) "ble" "scale" "decentscale"
#after 500 decentscale_enable_lcd
decentscale_tare

Expand All @@ -1421,20 +1525,20 @@ proc de1_ble_handler { event data } {
#after 5000 decentscale_timer_off

} elseif {$::settings(scale_type) == "atomaxskale"} {
append_to_scale_bluetooth_list $address $::settings(scale_bluetooth_name) "atomaxskale"
append_to_peripheral_list $address $::settings(scale_bluetooth_name) "ble" "scale" "atomaxskale"
#set ::de1(scale_type) "atomaxskale"
skale_enable_lcd
after 1000 skale_enable_weight_notifications
after 2000 skale_enable_button_notifications
after 3000 skale_enable_lcd
} elseif {$::settings(scale_type) == "felicita"} {
append_to_scale_bluetooth_list $address $::settings(scale_bluetooth_name) "felicita"
append_to_peripheral_list $address $::settings(scale_bluetooth_name) "ble" "scale" "felicita"
after 2000 felicita_enable_weight_notifications
} elseif {$::settings(scale_type) == "hiroiajimmy"} {
append_to_scale_bluetooth_list $address $::settings(scale_bluetooth_name) "hiroiajimmy"
append_to_peripheral_list $address $::settings(scale_bluetooth_name) "ble" "scale" "hiroiajimmy"
after 200 hiroia_enable_weight_notifications
} elseif {$::settings(scale_type) == "acaiascale"} {
append_to_scale_bluetooth_list $address $::settings(scale_bluetooth_name) "acaiascale"
append_to_peripheral_list $address $::settings(scale_bluetooth_name) "ble" "scale" "acaiascale"
acaia_send_ident
after 500 acaia_send_config
after 1000 acaia_enable_weight_notifications
Expand All @@ -1444,7 +1548,7 @@ proc de1_ble_handler { event data } {
}
set ::currently_connecting_scale_handle 0

if {$::de1(device_handle) != 0} {
if {$::de1(device_handle) != 0 && $::de1(thermometer_device_handle) != 0} {
# if we're connected to both the scale and the DE1, stop scanning
stop_scanner
}
Expand Down Expand Up @@ -1795,6 +1899,9 @@ proc de1_ble_handler { event data } {
} elseif {$cuuid eq $::de1(cuuid_hiroiajimmy_status)} {
# hiroia jimmy scale
hiroia_parse_response $value
} elseif {$cuuid eq $::de1(cuuid_meater)} {
# meater thermometer
meater_parse_response $value
} elseif {$cuuid eq $::de1(cuuid_skale_EF82)} {
set t0 {}
#set t1 {}
Expand Down Expand Up @@ -2079,7 +2186,7 @@ proc scanning_state_text {} {
}

#return [translate "Tap to select"]
if {[ifexists ::de1_needs_to_be_selected] == 1 || [ifexists ::scale_needs_to_be_selected] == 1} {
if {[ifexists ::de1_needs_to_be_selected] == 1 || [ifexists ::peripheral_needs_to_be_selected] == 1} {
return [translate "Tap to select"]
}

Expand All @@ -2095,13 +2202,9 @@ proc scanning_restart {} {

# insert enough dummy devices to overfill the list, to test whether scroll bars are working
set ::de1_device_list [list [dict create address "12:32:16:18:90" name "ble3" type "ble"] [dict create address "10.1.1.20" name "wifi1" type "wifi"] [dict create address "12:32:56:78:91" name "dummy_ble2" type "ble"] [dict create address "12:32:56:78:92" name "dummy_ble3" type "ble"] [dict create address "ttyS0" name "dummy_usb" type "usb"] [dict create address "192.168.0.1" name "dummy_wifi2" type "wifi"]]
set ::scale_bluetooth_list [list [dict create address "51:32:56:78:90" name "ACAIAxxx" type "ble"] [dict create address "92:32:56:78:90" name "Skale2" type "ble"] [dict create address "12:32:56:78:92" name "ACAIA2xxx" type "ble"] [dict create address "12:32:56:78:93" name "Skale2b" type "ble"] ]

set ::scale_types(12:32:56:78:90) "decentscale"
set ::scale_types(32:56:78:90:12) "decentscale"
set ::scale_types(56:78:90:12:32) "atomaxskale"
set ::peripheral_device_list [list [dict create address "51:32:56:78:90" name "ACAIAxxx" type "ble" devicetype "scale" devicefamily "acaiascale"] [dict create address "12:32:56:78:93" name "MEATER" type "ble" devicetype "thermometer" devicefamily "apptionmeater"] ]

after 200 fill_ble_scale_listbox
after 200 fill_peripheral_listbox
after 400 fill_ble_listbox

set ::scanning 1
Expand Down
15 changes: 8 additions & 7 deletions de1plus/machine.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ array set ::de1 {
device_handle 0
language_rtl 0
scale_device_handle 0
thermometer_device_handle 0
decentscale_device_handle 0
suuid "0000A000-0000-1000-8000-00805F9B34FB"
sinstance 12
Expand Down Expand Up @@ -73,6 +74,8 @@ array set ::de1 {
suuid_hiroiajimmy "06C31822-8682-4744-9211-FEBC93E3BECE"
cuuid_hiroiajimmy_cmd "06C31823-8682-4744-9211-FEBC93E3BECE"
cuuid_hiroiajimmy_status "06C31824-8682-4744-9211-FEBC93E3BECE"
suuid_meater "A75CC7FC-C956-488F-AC2A-2DBC08B63A04"
cuuid_meater "7EDDA774-045E-4BBF-909B-45D1991A2876"
cinstance 0
fan_threshold 0
tank_temperature_threshold 0
Expand Down Expand Up @@ -347,6 +350,9 @@ array set ::settings {
scale_bluetooth_name {}
skale_bluetooth_address {}
bluetooth_address {}
thermometer_bluetooth_name {}
thermometer_bluetooth_address {}
thermometer_bluetooth_type {}
water_max_vol 500
water_temperature 85
final_desired_shot_weight 36
Expand Down Expand Up @@ -442,6 +448,7 @@ array set ::settings {
last_version "1.34"

create_legacy_shotfiles 0
target_milk_temperature 65
}

# default de1plus skin
Expand All @@ -458,12 +465,6 @@ if { $settings(bluetooth_address) != ""} {
append_to_de1_list $settings(bluetooth_address) "DE1" "ble"
}


#error "atomaxscale"
# initial filling of BLE scale list
#set ::scale_bluetooth_list $::settings(scale_bluetooth_address)


array set ::de1_state {
Sleep \x00
GoingToSleep \x01
Expand Down Expand Up @@ -517,7 +518,7 @@ array set ::de1_num_state {



set ::scale_bluetooth_list ""
set ::peripheral_device_list ""
array set ::de1_num_state_reversed [reverse_array ::de1_num_state]


Expand Down
Loading