Epson ePOS SDK checking for printer status real-time - printing

How do I check for epson receipt printer status in real-time?
Currently, I am using a scheduled timer to run the Epos2Discovery.start every 10 seconds to check for printer availability.
printerCheckTimer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(checkPrinter), userInfo: nil, repeats: true)
// Listen for printer connection
#objc func checkPrinter() {
// Stop previous epson printer discovery if any, and reset scanned epson printers array
var result = EPOS2_SUCCESS.rawValue
result = Epos2Discovery.stop()
// Search for epson printers
result = Epos2Discovery.start(filterOption, delegate: self)
if result != EPOS2_SUCCESS.rawValue {
print(result)
}
}
// Delegate for epson printer discovery
func onDiscovery(_ deviceInfo: Epos2DeviceInfo!) {
// Loop all the connected epson printers port, and see if they exists in the nearby ports
for (printerId, connectedPrinterPort) in self.connectedEpsonPrinters {
if connectedPrinterPort == deviceInfo.target {
onlineEpsonPrinters[printerId] = Int(Date().timeIntervalSince1970)
}
}
}
This solution work perfectly fine for older TM-T82 (Serial: UEHF...). However, for the newer revision of TM-T82 (Serial: X4XQ...), this seems to be problematic.
The number of concurrent devices running the Epos2Discovery.start timer seems to be affecting the performance of the print.
When using 1 device, it will work just fine, and print out just as fast. However, for 2 devices, the print became slower (Probably 5s slower).
When using 3 devices, the printer status will flicker between online and offline status, and half of the prints will end up with a failed print error prompt. It seems that the running Epos2Discovery concurrently on multiple devices with a recurring timer is causing an issue with the detection of printer.
This only happen on newer revision of the TM model, it's working perfectly fine for my old printers that I bought previously (TM-T88, TM-U220B, TM-T81).
I am wondering if there is any other ways to check for printer status in real-time?

Related

Connecting bluetooth headphones while app is recording in the background causes the recording to stop

I am facing the following issue and hoping someone else encountered it and can offer a solution:
I am using AVAudioEngine to access the microphone. Until iOS 12.4, every time the audio route changed I was able to restart the AVAudioEngine graph to reconfigure it and ensure the input/output audio formats fit the new input/output route. Due to changes introduced in iOS 12.4 it is no longer possible to start (or restart for that matter) an AVAudioEngine graph while the app is backgrounded (unless it's after an interruption).
The error Apple now throw when I attempt this is:
2019-10-03 18:34:25.702143+0200 [1703:129720] [aurioc] 1590: AUIOClient_StartIO failed (561145187)
2019-10-03 18:34:25.702528+0200 [1703:129720] [avae] AVAEInternal.h:109 [AVAudioEngineGraph.mm:1544:Start: (err = PerformCommand(*ioNode, kAUStartIO, NULL, 0)): error 561145187
2019-10-03 18:34:25.711668+0200 [1703:129720] [Error] Unable to start audio engine The operation couldn’t be completed. (com.apple.coreaudio.avfaudio error 561145187.)
I'm guessing Apple closed a security vulnerability there. So now I removed the code to restart the graph when an audio route is changed (e.g. bluetooth headphones are connected).
It seems like when an I/O audio format changes (as happens when the user connects a bluetooth device), an .AVAudioEngingeConfigurationChange notification is fired, to allow the integrating app to react to the change in format. This is really what I should've used to handle changes in I/O formats from the beginning, instead of brute forcing restarting the graph. According to the Apple documentation - “When the audio engine’s I/O unit observes a change to the audio input or output hardware’s channel count or sample rate, the audio engine stops, uninitializes itself, and issues this notification.” (see the docs here). When this happens while the app is backgrounded, I am unable to start the audio engine with the correct audio i/o formats, because of point #1.
So bottom line, it looks like by closing a security vulnerability, Apple introduced a bug in reacting to audio I/O format changes while the app is backgrounded. Or am I missing something?
I'm attaching a code snippet to better describe the issue. For a plug-and-play AppDelegate see here - https://gist.github.com/nevosegal/5669ae8fb6f3fba44505543e43b5d54b.
class RCAudioEngine {
​
private let audioEngine = AVAudioEngine()
init() {
setup()
start()
NotificationCenter.default.addObserver(self, selector: #selector(handleConfigurationChange), name: .AVAudioEngineConfigurationChange, object: nil)
}
​
#objc func handleConfigurationChange() {
//attempt to call start()
//or to audioEngine.reset(), setup() and start()
//or any other combination that involves starting the audioEngine
//results in an error 561145187.
//Not calling start() doesn't return this error, but also doesn't restart
//the recording.
}
public func setup() {
​
//Setup nodes
let inputNode = audioEngine.inputNode
let inputFormat = inputNode.inputFormat(forBus: 0)
let mainMixerNode = audioEngine.mainMixerNode
​
//Mute output to avoid feedback
mainMixerNode.outputVolume = 0.0
​
inputNode.installTap(onBus: 0, bufferSize: 4096, format: inputFormat) { (buffer, _) -> Void in
//Do audio conversion and use buffers
}
}
​
public func start() {
RCLog.debug("Starting audio engine")
guard !audioEngine.isRunning else {
RCLog.debug("Audio Engine is already running")
return
}
​
do {
audioEngine.prepare()
try audioEngine.start()
} catch {
RCLog.error("Unable to start audio engine \(error.localizedDescription)")
}
}
}
I see only a fix that had gone into iOS 12.4. I am not sure if that causes the issue.
With the release notes https://developer.apple.com/documentation/ios_ipados_release_notes/ios_12_4_release_notes
"Resolved an issue where running an app in iOS 12.2 or later under the Leaks instrument resulted in random numbers of false-positive leaks for every leak check after the first one in a given run. You might still encounter this issue in Simulator, or in macOS apps when using Instruments from Xcode 10.2 and later. (48549361)"
You can raise issue with Apple , if you are a signed developer. They might help you if the defect is on their part.
You can also test with upcoming iOS release to check if your code works in the future release (with the apple beta program)

Altbeacon - Samsung Galaxy s9 not ranging beacons as expected when locked and power cable unplugged

I'm using the Altbeacon library and implementing the foreground service to allow for faster ranging. My app is designed to send a notification to the user whenever a matching beacon is ranged. The goal is that this happens no matter what, phone locked, unlocked, app open, app closed, and app cleared from task manager.
The app works as expected with a Samsung Galaxy s7 running Android 8.0. The issue I'm experiencing with the Samsung Galaxy s9 running Android 8.0, is when the power button is pressed to lock the phone. The phone no longer receives the notifications as often as it should, as if the foreground beacon scanning is being blocked.
The device sending the beacons can transmit a new beacon continuously at a 25ms rate for 12 seconds, for testing purposes, at the end of the 12 seconds it is set to repeat that process. The user should receive a new notification every 12 seconds, however the s9 may only receive 1 notification and then 5 could be missed before is sees another. The s7 will receive every single notification as expected.
The background scan rate is set to scan for 1.1 secs and wait for 10 seconds. I wish I could provide logs for the issue but when the phone is plugged in the issue doesn't occur, so I can't really pin point why the s9 would be acting this way when the s7 doesn't. I assume it has to be something with doze mode or sleep mode since when the power cord is plugged in, the s9 receives all the notifications as expected. Those are the only two phones I have been able to test so I don't know if it is also an issue with the s8.
What could be causing the s9 to not range the same as the s7 when locked by the power button? If the phone just goes to sleep on its own, it acts the same as if the power button were pressed to put it to sleep. Code snippet below.
Thanks!
mBeaconManager = BeaconManager.getInstanceForApplication(this.getApplicationContext());
set_forground_notification(true);
logManager.setLogger(Loggers.verboseLogger());
logManager.setVerboseLoggingEnabled(true);
mBeaconManager.setAndroidLScanningDisabled(false); // Setting to false allows low latency scanning
mBeaconManager.setRegionStatePersistenceEnabled(false);
mBeaconManager.setBackgroundScanPeriod(1100);
mBeaconManager.setForegroundScanPeriod(1100);
mBeaconManager.setForegroundBetweenScanPeriod(2000);
mBeaconManager.setBackgroundBetweenScanPeriod(10000);
mBeaconManager.setBackgroundMode(true); // this is being set to true here so that on app termination
// or reboot when the app starts back up because of the service, the scanning period
// is set to background and not foreground
private void set_forground_notification(boolean post)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (post) {
String CHANNEL_ID = "Scanning_for_device";
CharSequence name = "Scanning_for_device";
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, android.app.NotificationManager.IMPORTANCE_HIGH);
mChannel.setShowBadge(false);
mChannel.setSound(null,null);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_foreground_logo)
.setContentTitle("Scanning for Device")
.setSound(null)
.setOnlyAlertOnce(true);
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(pendingIntent);
android.app.NotificationManager mNotificationManager =
(android.app.NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(mChannel);
// sends foreground notification and starts foreground scanning?
mBeaconManager.enableForegroundServiceScanning(mBuilder.build(), 457);
} else {
// removes foreground notification and stops foreground scanning?
mBeaconManager.disableForegroundServiceScanning();
}
}
}

Chromecast Sleep/Background issue in iOS app

I am facing a very big issue while using Chromecast in my application. I am using normal GCKUICastButton to connect to the Chromecast. The video plays well.
I am using the default Cast receiver for my application. When the device goes to sleep, sometimes, Chromecast stops and sometimes, after sleep mode, the device disconnects after some time. After going through lot of forums and Stack Overflow questions, I implemented the below code
extension GCKSessionManager {
static func ignoreAppBackgroundModeChange() {
let oldMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSession(with:)))
let newMethod = class_getInstanceMethod(GCKSessionManager.self, #selector(GCKSessionManager.suspendSessionIgnoringAppBackgrounded(with:)))
method_exchangeImplementations(oldMethod, newMethod)
}
func suspendSessionIgnoringAppBackgrounded(with reason: GCKConnectionSuspendReason) -> Bool {
guard reason != .appBackgrounded else { return false }
return suspendSession(with:reason)
}
}
Then in my code I wrote the below line
GCKSessionManager.ignoreAppBackgroundModeChange()
Now suddenly, the Chromecast does not disconnect however after few minutes of sleep, it disconnects as well as, kill the app as well. How can I retain the Chromecast play session even if the device goes to sleep or goes to background.
As I am using GCKUICastButton so I am not using the GCKDeviceManager so I am unable to use the ignoreAppStateNotification using GCKDeviceManager, can you advice if I can use that as well.
I have also added the GCKCastOption code as well in AppDelegate.

iOS Application not Writing to BLE Mini

I am designing an application which will communicate with a TI LaunchPad through a BLE Mini by utilizing CoreBluetooth, however I am struggling to transmit data between my iPhone and the Red Bear BLE Mini. Currently, I am trying to send a command which will instruct the Launchpad to turn an LED on and off. I have implemented all of the CoreBluetooth methods and confirmed that I am connected to the BLE Mini. I also have discovered this device's singular service and the five characteristics associated with this device with my iPhone application, so I know I am connected to the device. After confirming this connection, I attempted to write to the write characteristic, but I'm not sure if I wrote to this characteristic properly. Also, I'm not sure how I should be encoding the data. I have tried both ascii and utf8. Here is what I wrote:
let string = "LED-ON"
let data = string.data(using: .ascii)
if manager.write_char != nil{
print("trying")
print(manager.write_char.uuid)
peripheral.writeValue(data!, for: manager.write_char, type: CBCharacteristicWriteType.withoutResponse)
The print statement confirms that this characteristic has the uuid that I defined as being the write characteristic
let WRITE_CHAR = "713D0004-503E-4C75-BA94-3148F18D941E"
I believe this is the correct write characteristic. I have also tried 71230003. On the Launchpad side, I have uploaded the following code:
int incomingByte = 0; // for incoming serial data
void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
Serial1.begin(9600);
pinMode(7, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
//if (Serial1.available()){
// Serial.print("available");
//Read in data
Serial.print(Serial1.available());
Serial.print(" ");
Serial.print(Serial1.read());
Serial.print("\n");
if (Serial1.available() > 0) {
// read the incoming byte:
incomingByte = Serial1.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
In the serial monitor, all I receive are 0 from the available check and -1 from the read method both of which signify that no data is being received. Am I transmitting data to the BLE Mini correctly? If so, am I reading it incorrectly? Additionally, is there something I'm supposed to do to tell the BLE Mini to transmit data? Sorry for the long winded question. Thank you so much for the help.

UDPClient not receiving packets on HTC G2

I'm attempting to receive a UDP Broadcast under Mono for Android and I am seeing no data coming in. This is somewhat perplexing because it works fine on the Galaxy Tab 7 and Galaxy Tab 10 (Android v 3.2) I have, but fails on an HTC G2 (Android v2.3.4).
The code is straightforward:
public void BeginDiscover()
{
var packet = new DiscoverPacket();
lock (m_syncRoot)
{
var localEndpoint = new IPEndPoint(m_local, 0);
using (var udp = new UdpClient(localEndpoint))
{
var remoteEndpoint = new IPEndPoint(IPAddress.Broadcast, DiscoverPort);
udp.Send(packet.Data, packet.Data.Length, remoteEndpoint);
Thread.Sleep(100);
}
}
}
I have verified that the manifest includes this line:
<uses-permission android:name="android.permission.INTERNET" />
Though this is happening in Debug, so that should be implicitly set anyway.
Other very strange observations:
Again, this is working just fine on another type of device
The handler listening for UDP broadcasts (which list listening for the response) does see this outbound packet. The code for this listener is also straightforward:
[listener code]
private void Start()
{
m_discoverListener = new UdpClient(DiscoverPort);
m_discoverListener.BeginReceive(DiscoverCallback, m_discoverListener);
}
private void DiscoverCallback(IAsyncResult result)
{
try
{
var ep = new IPEndPoint(IPAddress.Any, DiscoverPort);
var data = m_discoverListener.EndReceive(result, ref ep);
// filter out what we send
var add = AddressWithoutPort(ep.Address);
if (add == m_local.ToString()) return;
// parse discover response
// [clipped for clarity]
}
finally
{
m_discoverListener.BeginReceive(DiscoverCallback, m_discoverListener);
}
}
Wireshark running on a separate PC on the same network does see the discover request packet (from above)
The "discovered" device is also seeing it, because Wireshark is also seeing the reply
The Android device UDP listener is not receiving the response packet
The only major differences between devices that I can think of (other than different OEMs implementing the platform) is that the G2 has a cellular radio built in and the Galaxy Tab does not. In my specific test case, I have no SIM card in the phone, though, so no cellular connection is being made. Note that the code above is explicitly using the local endpoint that is on the WiFi network.
Is there a known issue with UDP on the G2 specifically or generally on older implementations of the Android platform?
It took a bit of work as the UDP response in question is coming from a microcontroller on the device and I wanted to make absolutely certain that it wasn't an issue on the micro end (though I suspected it wasn't). I created a PC-based simulator for the microcontroller device that handles my Android UDP request and that sends back the exact same UDP response that the microcontroller does, then verified all of the traffic looks fine with Wireshark.
The net result is that I see he exact same behavior with the simulator. The Galaxy Tab 7 and 10 devices receive the UDP response no problem. The HTC G2 never does. This leads me to conclude that one of the following is true:
a) The HTC G2 specifically has an implementation bug preventing it from receiving (or at least passing along) UDP broadcasts on the network
or
b) The older Android build has his bug.
Until I find different hardware with the same Android version as the G2 (v2.3) I can't tell which is the case. In either event, it's a bug that makes this (and potentially other) hardware unusable for my specific solution.
I have a couple of applications on the market based on UDP communication.
I have problems with HTC phones not receiving the UDP broadcast packets sent from another device... if sent from the same device, the packets arrive.
so, I think the problem is in HTC, and I found a possible solutions online (even though I have not tried it):
http://www.flattermann.net/2010/09/fix-udp-broadcasts-on-htc-phones-running-stock-firmware/

Resources