M5Stack, wifi name and password being written successfully to M5stack
This commit is contained in:
parent
7644a92587
commit
8ae5b2479e
|
@ -13,6 +13,9 @@ enum ConstantsM5Stack {
|
|||
/// default text color
|
||||
static let defaultTextColor = M5StackTextColor.white
|
||||
|
||||
/// github url with repository for M5Stack that supports bluetooth
|
||||
static let githubURLM5Stack = "https://github.com/JohanDegraeve/M5_NightscoutMon"
|
||||
|
||||
}
|
||||
|
||||
enum M5StackTextColor:UInt16, CaseIterable {
|
||||
|
|
|
@ -482,9 +482,23 @@ extension M5StackManager: M5StackBluetoothDelegate {
|
|||
|
||||
/// did the app successfully authenticate towards M5Stack
|
||||
///
|
||||
/// in case of failure, then user should set the correct password in the M5Stack ini file, or, in case there's no password set in the ini file, switch off and on the M5Stack
|
||||
func authentication(success: Bool, forM5Stack m5Stack:M5Stack) {
|
||||
trace("in authentication with success = %{public}@", log: self.log, type: .info, success.description)
|
||||
|
||||
// if authentication not successful then disconnect and don't reconnect, user should verify password or reset the M5Stack, disconnect and set shouldconnect to false, permenantly (ie store in core data)
|
||||
// disconnection is done because maybe another device is trying to connect to the M5Stack, need to make it free
|
||||
if !success {
|
||||
|
||||
// device should not reconnect after disconnecting
|
||||
m5Stack.shouldconnect = false
|
||||
|
||||
// save in coredata
|
||||
save()
|
||||
|
||||
// disconnect
|
||||
disconnect(fromM5stack: m5Stack)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// there's no ble password set, user should set it in the settings
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
"notConnected" = "not connected";
|
||||
"alwaysconnect" = "Always Connect";
|
||||
"donotconnect" = "Don't connect";
|
||||
"authenticationFailureWarning" = "Authentication to M5Stack Failed, either set the pre-configured password in the Settings, or, if the M5Stack does not have a preconfigured password then reset the M5Stack";
|
||||
"authenticationFailureWarning" = "Authentication to M5Stack Failed, either set the pre-configured password in the Settings, or, if the M5Stack does not have a preconfigured password then reset the M5Stack. M5Stack will disconnect now. You can make a new attempt by clicking ";
|
||||
"blePasswordMissingWarning" = "You need to set the password in the Settings";
|
||||
"m5StackResetRequiredWarning" = "M5Stack must be reset in order to generate a new temporary password";
|
||||
"m5StackAlias" = "Alias";
|
||||
"selectAliasText" = "Choose a name for this M5Stack, the name will be shown in the app and is easier for you to recognize";
|
||||
"userdefinedNameAlreadyExists" = "There is already an M5Stack with this name";
|
||||
"userdefinedNameAlreadyExists" = "Do you want to delete M5Stack with ";
|
||||
"confirmDeletionM5Stack" = "Do you want to delete M5Stack with ";
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
"screenTitle" = "M5Stack List";
|
||||
"m5StackSoftWareHelpCellText" = "Where to find M5Stack software ?";
|
||||
"m5StackSoftWareHelpText" = "Go to";
|
||||
|
|
|
@ -33,7 +33,7 @@ class Texts_M5StackView {
|
|||
}()
|
||||
|
||||
static let authenticationFailureWarning: String = {
|
||||
return NSLocalizedString("authenticationFailureWarning", tableName: filename, bundle: Bundle.main, value: "Authentication to M5Stack Failed, either set the pre-configured password in the Settings, or, if the M5Stack does not have a preconfigured password then reset the M5Stack", comment: "in case M5Stack authentication failed")
|
||||
return NSLocalizedString("authenticationFailureWarning", tableName: filename, bundle: Bundle.main, value: "Authentication to M5Stack Failed, either set the pre-configured password in the Settings, or, if the M5Stack does not have a preconfigured password then reset the M5Stack. M5Stack will disconnect now. You can make a new attempt by clicking ", comment: "in case M5Stack authentication failed")
|
||||
}()
|
||||
|
||||
static let blePasswordMissingWarning: String = {
|
||||
|
@ -56,8 +56,8 @@ class Texts_M5StackView {
|
|||
return NSLocalizedString("userdefinedNameAlreadyExists", tableName: filename, bundle: Bundle.main, value: "There is already an M5Stack with this name", comment: "M5Stack view, when user clicks userdefinedname (alias) field")
|
||||
}()
|
||||
|
||||
//confirmDeletionM5Stack
|
||||
static let confirmDeletionM5Stack: String = {
|
||||
return NSLocalizedString("userdefinedNameAlreadyExists", tableName: filename, bundle: Bundle.main, value: "Do you want to delete M5Stack with ", comment: "M5Stack view, when user clicks the trash button - this is not the complete sentence, it will be followed either by 'name' or 'alias', depending on the availability of a userdefined name")
|
||||
return NSLocalizedString("confirmDeletionM5Stack", tableName: filename, bundle: Bundle.main, value: "Do you want to delete M5Stack with ", comment: "M5Stack view, when user clicks the trash button - this is not the complete sentence, it will be followed either by 'name' or 'alias', depending on the availability of a userdefined name")
|
||||
}()
|
||||
|
||||
}
|
||||
|
|
|
@ -7,4 +7,13 @@ class Texts_M5StacksView {
|
|||
static let screenTitle: String = {
|
||||
return NSLocalizedString("screenTitle", tableName: filename, bundle: Bundle.main, value: "M5Stack List", comment: "when M5 stack list is shown, title of the view")
|
||||
}()
|
||||
|
||||
static let m5StackSoftWareHelpCellText: String = {
|
||||
return NSLocalizedString("m5StackSoftWareHelpCellText", tableName: filename, bundle: Bundle.main, value: "Where to find M5Stack software ?", comment: "In list of M5Stacks, the last line allows to show info where to find M5Stack software, this is the text in the cell")
|
||||
}()
|
||||
|
||||
static let m5StackSoftWareHelpText: String = {
|
||||
return NSLocalizedString("m5StackSoftWareHelpText", tableName: filename, bundle: Bundle.main, value: "Go to", comment: "this is the text shown when clicking the cell 'where to find M5Stack software'")
|
||||
}()
|
||||
|
||||
}
|
||||
|
|
|
@ -157,58 +157,48 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter, BluetoothTransmit
|
|||
/// - name : the wifi name or ssid, if nil then nothing is sent
|
||||
/// - number : the wifi number (1 to 10)
|
||||
/// - returns: true if successfully called writeDataToPeripheral, doesn't mean it's been successfully received by the M5Stack
|
||||
func writeWifiName(name: String?, number: UInt8) -> Bool {
|
||||
///
|
||||
/// byte 0 will be opcode, byte 1 and 2 packetnumber and number of packets respectively, byte 3 will number of the wifi converted to string, next bytes are the actually name
|
||||
func writeWifiName(name: String?, number: UInt8) -> Bool {
|
||||
|
||||
guard let stringAsData = name?.data(using: .utf8) else {
|
||||
trace(" failed to create data from wifiname, value is probably nil, I'm not sending wifiName of zero length to the M5Stack", log: log, type: .info)
|
||||
guard let name = name else {
|
||||
trace(" name is nil", log: log, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialize dataToSend
|
||||
var dataToSend = Data()
|
||||
|
||||
// add wifi number
|
||||
dataToSend.append(number.data)
|
||||
// we will send the number as a string followed by the actual wifiname
|
||||
let numberAndName = number.description + name
|
||||
|
||||
// add wifi name
|
||||
dataToSend.append(stringAsData)
|
||||
|
||||
// write the data
|
||||
return writeDataToPeripheral(data: dataToSend, opCode: .writeWlanSSIDTx)
|
||||
// use writeStringToPeripheral to send it
|
||||
return writeStringToPeripheral(text: numberAndName, opCode: .writeWlanSSIDTx)
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// writes a wifi password
|
||||
/// - parameters:
|
||||
/// - password : the wifi password, if nil then nothing is sent
|
||||
/// - number : the wifi number (1 to 10)
|
||||
/// - returns: true if successfully called writeDataToPeripheral, doesn't mean it's been successfully received by the M5Stack
|
||||
func writeWifiPassword(password: String?, number: UInt8) -> Bool {
|
||||
///
|
||||
/// byte 0 will be opcode, byte 1 and 2 packetnumber and number of packets respectively, byte 3 will number of the wifi converted to string, next bytes are the actually password
|
||||
func writeWifiPassword(password: String?, number: UInt8) -> Bool {
|
||||
|
||||
guard let stringAsData = password?.data(using: .utf8) else {
|
||||
trace(" failed to create data from password, value is probably nil, I'm not sending password of zero length to the M5Stack", log: log, type: .info)
|
||||
guard let password = password else {
|
||||
trace(" password is nil", log: log, type: .info)
|
||||
return false
|
||||
}
|
||||
|
||||
// initialize dataToSend
|
||||
var dataToSend = Data()
|
||||
|
||||
// add wifi number
|
||||
dataToSend.append(number.data)
|
||||
|
||||
// add wifi name
|
||||
dataToSend.append(stringAsData)
|
||||
|
||||
// write the data
|
||||
return writeDataToPeripheral(data: dataToSend, opCode: .writeWlanPassTx)
|
||||
// we will send the number as a string followed by the actual password
|
||||
let numberAndPassword = number.description + password
|
||||
|
||||
return writeStringToPeripheral(text: numberAndPassword, opCode: .writeWlanPassTx)
|
||||
}
|
||||
|
||||
|
||||
/// writes bloodglucose unit to M5Stack
|
||||
/// - returns: true if successfully called writeDataToPeripheral, doesn't mean it's been successfully received by the M5Stack
|
||||
func writeBloodGlucoseUnit(isMgDl: Bool) -> Bool {
|
||||
|
||||
return writeStringToPeripheral(string: isMgDl ? "true":"false", opCode: .writemgdlTx)
|
||||
return writeStringToPeripheral(text: isMgDl ? "true":"false", opCode: .writemgdlTx)
|
||||
}
|
||||
|
||||
/// writes nightscout url to M5Stack
|
||||
|
@ -218,7 +208,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter, BluetoothTransmit
|
|||
func writeNightScoutUrl(url: String?) -> Bool {
|
||||
|
||||
if let url = url {
|
||||
return writeStringToPeripheral(string: url, opCode: .writeNightScoutUrlTx)
|
||||
return writeStringToPeripheral(text: url, opCode: .writeNightScoutUrlTx)
|
||||
} else {return false}
|
||||
}
|
||||
|
||||
|
@ -229,7 +219,7 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter, BluetoothTransmit
|
|||
func writeNightScoutAPIKey(apiKey: String?) -> Bool {
|
||||
|
||||
if let apiKey = apiKey {
|
||||
return writeStringToPeripheral(string: apiKey, opCode: .writeNightScoutAPIKeyTx)
|
||||
return writeStringToPeripheral(text: apiKey, opCode: .writeNightScoutAPIKeyTx)
|
||||
} else {return false}
|
||||
}
|
||||
|
||||
|
@ -414,9 +404,6 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter, BluetoothTransmit
|
|||
/// local time = UTC time + offset /// UTC time = local time - offset
|
||||
private func sendLocalTimeAndUTCTimeOffSetInSecondsToM5Stack() {
|
||||
|
||||
// NOTE : why creating multiple packets (splitTextInBLEPackets) even though it will all fit in one packet ?
|
||||
// goal is to be able to send longer strings, to M5 Stack. Then we could create one string which contains the timestamp and offset (split by blanc). But then for sure there will be multiple packets, and I didn't yet develop the logic to reconcatenate strings in the M5Stack
|
||||
|
||||
// create local time in seconds as Int64
|
||||
let localTimeInSeconds = Date().toSecondsAsInt64Local()
|
||||
|
||||
|
@ -486,14 +473,29 @@ final class M5StackBluetoothTransmitter: BluetoothTransmitter, BluetoothTransmit
|
|||
|
||||
}
|
||||
|
||||
private func writeStringToPeripheral(string: String, opCode : M5StackTransmitterOpCodeTx) -> Bool {
|
||||
private func writeStringToPeripheral(text: String, opCode : M5StackTransmitterOpCodeTx) -> Bool {
|
||||
|
||||
guard let stringAsData = string.data(using: .utf8) else {
|
||||
trace(" failed to create data from string", log: log, type: .error)
|
||||
// create packets to send with offset
|
||||
guard let packetsWithOffset = M5StackUtilities.splitTextInBLEPackets(text: text, maxBytesInOneBLEPacket: ConstantsM5Stack.maximumMBLEPacketsize, opCode: opCode.rawValue) else {
|
||||
trace(" failed to create packets for sending string", log: log, type: .error)
|
||||
return false
|
||||
}
|
||||
|
||||
return writeDataToPeripheral(data: stringAsData, opCode: opCode)
|
||||
// initialize result
|
||||
var success = true
|
||||
|
||||
// send the packets
|
||||
for packet in packetsWithOffset {
|
||||
if !writeDataToPeripheral(data: packet, type: .withoutResponse) {
|
||||
trace(" failed to send packet", log: log, type: .error)
|
||||
success = false
|
||||
break
|
||||
} else {
|
||||
trace(" successfully sent packet to M5Stack", log: log, type: .info)
|
||||
}
|
||||
}
|
||||
|
||||
return success
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -599,7 +599,14 @@ extension M5StackViewController: M5StackBluetoothDelegate {
|
|||
func authentication(success: Bool, forM5Stack m5Stack: M5Stack) {
|
||||
|
||||
if !success {
|
||||
UIAlertController(title: Texts_Common.warning, message: Texts_M5StackView.authenticationFailureWarning, actionHandler: nil).presentInOwnWindow(animated: true, completion: nil)
|
||||
|
||||
// show warning, inform that user should set password or reset M5Stack
|
||||
UIAlertController(title: Texts_Common.warning, message: Texts_M5StackView.authenticationFailureWarning + " " + Texts_M5StackView.alwaysConnect, actionHandler: {
|
||||
|
||||
// by the time user clicks 'ok', the M5stack will be disconnected by the M5StackManager (see authentication in M5StackManager)
|
||||
self.shouldConnectTemporaryValue = m5Stack.shouldconnect
|
||||
|
||||
}).presentInOwnWindow(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -140,13 +140,25 @@ final class M5StacksViewController: UIViewController {
|
|||
extension M5StacksViewController: UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return m5Stacks.count
|
||||
|
||||
// add 1 for the row that will show help info
|
||||
return m5Stacks.count + 1
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: SettingsTableViewCell.reuseIdentifier, for: indexPath) as? SettingsTableViewCell else { fatalError("Unexpected Table View Cell") }
|
||||
|
||||
// the last row is the help info
|
||||
if indexPath.row == m5Stacks.count {
|
||||
|
||||
cell.textLabel?.text = Texts_M5StacksView.m5StackSoftWareHelpCellText
|
||||
cell.detailTextLabel?.text = nil
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
return cell
|
||||
|
||||
}
|
||||
|
||||
// textLabel should be the userdefinedname of the M5Stack, or if userdefinedname == nil, then the address
|
||||
cell.textLabel?.text = m5Stacks[indexPath.row].m5StackName?.userDefinedName
|
||||
if cell.textLabel?.text == nil {
|
||||
|
@ -178,7 +190,17 @@ extension M5StacksViewController: UITableViewDataSource, UITableViewDelegate {
|
|||
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
|
||||
self.performSegue(withIdentifier: M5StackViewController.SegueIdentifiers.M5StacksToM5StackSegueIdentifier.rawValue, sender: m5Stacks[indexPath.row])
|
||||
// the last row is the help info
|
||||
if indexPath.row == m5Stacks.count {
|
||||
|
||||
UIAlertController(title: Texts_HomeView.info, message: Texts_M5StacksView.m5StackSoftWareHelpText + " " + ConstantsM5Stack.githubURLM5Stack, actionHandler: nil).presentInOwnWindow(animated: true, completion: nil)
|
||||
|
||||
} else {
|
||||
|
||||
self.performSegue(withIdentifier: M5StackViewController.SegueIdentifiers.M5StacksToM5StackSegueIdentifier.rawValue, sender: m5Stacks[indexPath.row])
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue