M5Stack, wifi name and password being written successfully to M5stack

This commit is contained in:
Johan Degraeve 2019-10-17 00:32:29 +02:00
parent 7644a92587
commit 8ae5b2479e
9 changed files with 107 additions and 48 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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 ";

View File

@ -1 +1,3 @@
"screenTitle" = "M5Stack List";
"m5StackSoftWareHelpCellText" = "Where to find M5Stack software ?";
"m5StackSoftWareHelpText" = "Go to";

View File

@ -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")
}()
}

View File

@ -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'")
}()
}

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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])
}
}
}