TTCE-K750 Card DISPENSER WITH RECYCLABLE APPLICATION - kiosk

I am using the rfid card dispenser module which is connected as usb serial and certain commands are are passed to get senor status using the following serial communication data but issue is we can't able to find any status for card insertion in sensor status is there a way to find this status from the dispenser sensors as below
fun getStatus(context: Context,type: String) {
val nRet: Int
val StateInfo = ByteArray(4)
val SendBuf = ByteArray(3)
val RecordInfo = arrayOfNulls<String>(2)
nRet = if (Connectflag) {
k720_usb!!.K720_SensorQuery(MacAddr, StateInfo)
} else {
K720_SensorQuery(MacAddr, StateInfo, RecordInfo)
}
if (nRet == 0) {
var str = ""
when (StateInfo[0].toInt()) {
48 ->{
Log.d(TAG, "boxstatus7")
str = """${str}Machine Status: Idle """.trimIndent()
}
49 ->{
Log.d(TAG, "boxstatus8")
str = """ $str Machine status: card box is full""".trimIndent()
}
50 ->{
Log.d(TAG, "boxstatus9")
str = """${str}Machine status: Failed to prepare card, please click "Reset"" """.trimIndent()
}
52 ->{
Log.d(TAG, "boxstatus10")
str = """ $str Machine status: command cannot be executed, please click "Reset""""".trimIndent()
}
56 ->{
Log.d(TAG, "boxstatus11")
str = """${str}Machine status: Recycle bin is full """.trimIndent()
}
57 ->{
Log.d(TAG, "boxstatus12")
str = """${str} Machine status: recycle bin is full/card bin pre-full""".trimIndent()
}
}
when (StateInfo[1].toInt()) {
48 ->{
str = """ ${str}Action status: idle """.trimIndent()
Log.d(TAG, "boxstatus11")
}
49 ->{
Log.d(TAG, "boxstatus12")
str = """ ${str}Action status: There is an error in receiving the card, please click "Reset"" """.trimIndent()
}
50 ->{
Log.d(TAG, "boxstatus13")
str = """${str}Action status: Card issuance error, please click "Reset""""".trimIndent()
}
52 ->{
Log.d(TAG, "boxstatus14")
str = """${str}Action status: receiving card""".trimIndent()
}
56 ->{
Log.d(TAG, "boxstatus15")
str = """${str}Action Status: Issuing Cards""".trimIndent()
}
}
when (StateInfo[2].toInt()) {
48 -> {
Log.d(TAG, "boxstatus1")
str = """$str Card box status: The card box is in a non-preemptive state""".trimIndent()
}
49 -> {
Log.d(TAG, "boxstatus2")
str = """$str Card box status: card box pre-empty""".trimIndent()
}
50 ->{
Log.d(TAG, "boxstatus3")
str = """$str Card box status: Card jammed """.trimIndent()
}
52 -> {
Log.d(TAG, "boxstatus4")
str = """ ${str}Card Box Status: Overlapping Cards""".trimIndent()
}
56 -> {
Log.d(TAG, "boxstatus5")
str = """$str Card box status: The card issuing box is full and can no longer be recycled to the issuing box/card box pre-empty""".trimIndent()
}
57 -> {
Log.d(TAG, "boxstatus6")
str = """${str}Card box status: The card issuing box is full and can no longer be recycled to the issuing box""".trimIndent()
}
}
when (StateInfo[3].toInt()) {
48 -> {
Log.d(TAG, "boxstatus")
str = """${str}Card Box Status: Idle""".trimIndent()
SendBuf[0] = 76
SendBuf[1] = 70
SendBuf[2] = 3
if (Connectflag) {
K720_SendCmd(MacAddr, SendBuf, 2, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 2)
}
}
49 -> {
Log.d(TAG, "stuck in the position of sensor 1 card pickup posi")
str = """$str Card box status: stuck in the sensor 1 position (card pickup position""".trimIndent()
Log.d(TAG, "getStatus"+type)
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 3
if (Connectflag){
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
50 -> {
str = """$str Card box status: stuck in sensor 2 position""".trimIndent()
Log.d(TAG, "stuck in the position of sensor 2 card")
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag){
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
51 ->{
Log.d(TAG, "stuck in the position of sensor 1-2 card reading posi")
str = "${str}Card box status: stuck in sensor 1-2 position (card reading posi".trimIndent()
if(type=="CONTRACTOR"){
verifyPassword(context,type)
}else{
}
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag){
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
52 -> {
str = """ ${str}Card status: stuck in sensor 3 position""".trimIndent()
Log.d(TAG, "stuck in the position 3")
}
53 -> {
str = "$str Card status: stuck at the sensor pick-up position".trimIndent()
Log.d(TAG, "stuck in the position of sensor PICK-UP")
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 3
if (Connectflag) {
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
54 ->{
str = """${str}Card status: stuck in the position of sensor 2-3""".trimIndent()
Log.d(TAG, "stuck in the position of sensor 2-3")
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag) {
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
55 -> { str = """$str Card status: stuck in the position of sensor 1-2-3""".trimIndent()
Log.d(TAG, "stuck in the position of sensor 1-2-3")
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag){
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
56 -> {
Log.d(TAG, "getStatus: EMPTY")
str = """$str Card Status: Card box is empty""".trimIndent()
}
57 ->{
str = """$str Card Status: Only one card is in the sensor 1 position""".trimIndent()
Log.d(TAG, "getStatus: sensor 1 position")
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 3
if (Connectflag) {
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
59 -> {
Log.d(TAG, "getStatus: sensor 1-2 position")
str = """$str Card Status: Only one card is in the sensor 1-2 position""".trimIndent()
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag){
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
62 ->{
Log.d(TAG, "getStatus: sensor 2-3 position")
str = """$str Card Status: Only one card is in the sensor 2-3 position\r""".trimIndent()
SendBuf[0] = 76
SendBuf[1] = 80
SendBuf[2] = 0
if (Connectflag) {
K720_SendCmd(MacAddr, SendBuf, 3, RecordInfo)
} else {
k720_usb!!.K720_SendCmd(MacAddr, SendBuf, 3)
}
}
}
Log.d(TAG, "onClick: $str")
// ShowMessage(str,context)
} else {
// ShowMessage("Sensor status query failed with error code:" + ErrorCode(nRet, 0),context)
}
}

Related

Remove redundant also calls

I'm working with TCP communication and use Ktor library.
I have packets that come, and the first byte is the packet's lengths.
Likewise, I read the packet from what is documented on the protocol API, and sometimes I have to skip the remaining bytes of the packet, so I subtract what I have read to this message length.
At the present time, I call also { messageLength -= length } on each reading, but the code is unreadable.
#Test
fun ktorTests() {
runBlocking {
val selectorManager = SelectorManager(Dispatchers.IO)
val socket = aSocket(selectorManager).tcp().connect("server.slsknet.org", 2242)
val openReadChannel = socket.openReadChannel()
val openWriteChannel = socket.openWriteChannel(autoFlush = true)
val login = "Test"
val pwd = "159753"
openWriteChannel.write {
it.put(
ByteMessage().writeInt32(1)
.writeStr(login)
.writeStr(pwd)
.writeInt32(160)
.writeStr((login + pwd).toMD5())
.writeInt32(1)
.getBuff()
)
}
while (true) {
var messageLength = openReadChannel.readIntLittleEndian()
val code = openReadChannel.readIntLittleEndian()
println("ServerClient received: Message code:" + code + " Packet Size:" + (messageLength + 4))
when (code) {
1 -> {
if (openReadChannel.readBoolean().also { messageLength -= 1 }) {
val greetingLength = openReadChannel.readIntLittleEndian().also { messageLength -= 4 }
val greeting = ByteArray(greetingLength)
openReadChannel.readFully(greeting, 0, greetingLength)
.also { messageLength -= greetingLength }
val ip = openReadChannel.readIntLittleEndian().also { messageLength -= 4 }
println("Logged In.")
}
openReadChannel.discardExact(messageLength.toLong())
}
}
}
Any ideas on ho could it be done ?

Get Address from current location Kotlin

I get the current location like this:
val fusedLocationClient: FusedLocationProviderClient =
LocationServices.getFusedLocationProviderClient(LocalContext.current)
fun getLastKnownLocation() {
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
if (location != null) {
longitude.value = location.longitude
latitude.value = location.latitude
}
}
}
How I can get the Address from it?
Update
I implemented like this:
fun getLastKnownLocation() {
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
if (location != null) {
longitude.value = location.longitude
latitude.value = location.latitude
val geocoder = Geocoder(app)
if (Build.VERSION.SDK_INT >= 33) {
geocoder.getFromLocation(
location.latitude, location.longitude, 1
) { addresses ->
address.value = addresses.first().toString()
}
}
else {
try {
val addresses = geocoder.getFromLocation(location.latitude, location.longitude, 1
)?.firstOrNull()
address.value = addresses.toString()
} catch (Exp: Exception) {
address.value = "No Address found"
println("$Exp")
}
}
}
}
}
But got this exception: java.io.IOException: eccc: DEADLINE_EXCEEDED: deadline exceeded after 4.907678698s
val geocoder = Geocoder(this, Locale.getDefault())
val addresses = geocoder.getFromLocation(location.latitude, location.longitude, 1)
https://developer.android.com/reference/kotlin/android/location/Geocoder

State flow Android Kotlin

I have a god view model for every thing I know this is wrong
but I am just experimenting with Flow
I have these two State flow variables in view model
private val _currentRestroMenu = MutableStateFlow<State<Menu>>(State.loading())
private val _userCart = MutableStateFlow(CustomerCart())
val currentRestroMenu: StateFlow<State<Menu>> = _currentRestroMenu
val userCart: StateFlow<CustomerCart> = _userCart
Below functions get data from server and update above state flow
private fun getRestroMenuFromCloudAndUpdateData(restroId: String) = viewModelScope.launch {
fireStoreRepository.getRestroMenu(restroId).collect { state ->
when (state) {
is State.Success -> {
_currentRestroMenu.value = State.success(state.data)
dataHolderMenuOnSearch = state.data
if (!viewedRestroMenu.contains(state.data)) {
viewedRestroMenu.add(state.data)
}
}
is State.Failed -> {
_currentRestroMenu.value = State.failed(state.message)
}
is State.Loading -> {
_currentRestroMenu.value = State.loading()
}
}
}
}
private fun getCart() = viewModelScope.launch(Dispatchers.IO) {
if (currentCart.cartEmpty) {
fireStoreRepository.getUserCartInfoFromCloud(dataStoreRepository.readFileDataStoreValue.first().savedUserId)
.collect { cartState ->
when (cartState) {
is State.Success -> {
_userCart.update {
it.copy(
cartId = cartState.data.cartId,
cartEmpty = cartState.data.cartEmpty,
cartItem = cartState.data.getCartItem(),
restroId = cartState.data.restroId,
cartTotalAmount = cartState.data.cartTotalAmount,
cartAddressId = cartState.data.cartAddressId,
cartDeliveryTime = cartState.data.cartDeliveryTime,
cartCookingInstructions = cartState.data.cartCookingInstructions,
cartAppliedOfferId = cartState.data.cartAppliedOfferId,
deliveryPartnerTipAmount = cartState.data.deliveryPartnerTipAmount,
cartDeliveryCharge = cartState.data.cartDeliveryCharge,
cartTax = cartState.data.cartTax,
deliveryInstructionId = cartState.data.deliveryInstructionId,
foodHandlingCharge = cartState.data.foodHandlingCharge,
cartNumberOfItems = cartState.data.cartNumberOfItems,
cartRestroName = cartState.data.cartRestroName
)
}
currentCart = cartState.data
}
is State.Failed -> {
if (cartState.message == "Result null") {
Log.d(
ContentValues.TAG,
"getCartFromCloud: No cart details found in cloud creating new cart"
)
_userCart.update {
it.copy(
cartId = dataStoreRepository.readFileDataStoreValue.first().savedUserId,
cartEmpty = true
)
}
currentCart = CustomerCart(
cartId = dataStoreRepository.readFileDataStoreValue.first().savedUserId,
cartEmpty = true
)
}
}
is State.Loading -> {
Log.d(ContentValues.TAG, "getCartFromCloud: Loading")
}
}
}
} else {
_userCart.value = currentCart
Log.d(ContentValues.TAG, "getCart: $currentCart ")
}
}
I am collecting these state flow from different fragments
every thing works fine except one fragment
here is the code
in on create method
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
godCustomerViewModel.currentRestroMenu.collectLatest { menuState ->
Log.d(TAG, "currentRestroMenu ::: mENUSELECT FIRED: ")
when (menuState) {
is State.Success -> {
restroMenu = menuState.data
binding.recyclerView2.hideShimmer()
getCartDetails(restroMenu)
}
is State.Failed -> {
Log.d(TAG, "currentRestroMenu: ")
}
is State.Loading -> {
binding.recyclerView2.showShimmer()
}
}
}
}
}
private fun getCartDetails(restroMenu: Menu) = viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
godCustomerViewModel.userCart.collectLatest {
if (it.restroId == restroMenu.restroId) {
categoryAdapterRestroDetails.setData(
restroMenu.menuCategories,
it.getCartItem()
)
} else {
categoryAdapterRestroDetails.setData(
restroMenu.menuCategories,
ArrayList()
)
}
}
}
}
I am passing the two collected values to adapter (retro menu and item in cart )
when the fragment is loaded for the first time everything works fine
I have add dish to cart function which updates the value of user cart
fun addDishToCart(dish: Dish) = viewModelScope.launch {
Log.d(ContentValues.TAG, "addDishToCart: view model invoked")
if (currentCart.checkIfCartBelongsToThisRestro(dish.dishRestroId)) {
currentCart.addDishToCart(dish).collect {
Log.d(ContentValues.TAG, "addDishToCartcollect: $currentCart")
_userCart.update {
it.copy(
cartEmpty = currentCart.cartEmpty,
cartItem = currentCart.getCartItem(),
restroId = currentCart.restroId,
cartTotalAmount = currentCart.cartTotalAmount,
cartNumberOfItems = currentCart.cartNumberOfItems,
)
}
}
} else {
// restro Conflict
Log.d(ContentValues.TAG, "addDishToCart: $currentCart")
_restroConflict.value = CartConflict(true, currentCart.cartRestroName, dish)
}
Log.d(ContentValues.TAG, "addDishToCart current cart: ${currentCart.getCartItem()}")
Log.d(ContentValues.TAG, "addDishToCart: user Cart : ${_userCart.value.getCartItem()} ")
}
Which also work fine initially
I also have a button to filter menu to veg non veg
fun filterMenuForVeg(value: Boolean, showAll: Boolean) = viewModelScope.launch {
if (!showAll) {
Log.d(ContentValues.TAG, "filterMenuForVeg: Entered veg :$value")
var filteredMenu = Menu()
filteredMenu.restroId = dataHolderMenuOnSearch.restroId
for (menuCategory in dataHolderMenuOnSearch.menuCategories) {
Log.d(ContentValues.TAG, "filterMenuForVeg: $dataHolderMenuOnSearch ")
for (dish in menuCategory.dishes) {
if (dish.dishVeg == value) {
Log.d(ContentValues.TAG, "found dish with veg $value: ")
var categoryAlreadySaved = false
filteredMenu.menuCategories.filter {
categoryAlreadySaved = it.categoryId == menuCategory.categoryId
true
}
if (!categoryAlreadySaved) {
Log.d(ContentValues.TAG, "menu category not found in filtered list ")
val menuCategoryToAdd = MenuCategories()
menuCategoryToAdd.menuCategoryName = menuCategory.menuCategoryName
menuCategoryToAdd.categoryId = menuCategory.categoryId
menuCategoryToAdd.restroId = menuCategory.restroId
menuCategoryToAdd.dishes.add(dish)
filteredMenu.menuCategories.add(menuCategoryToAdd)
} else {
Log.d(ContentValues.TAG, "menu category found in filtered list ")
filteredMenu.menuCategories.find {
if (it.categoryId == menuCategory.categoryId) {
it.restroId = menuCategory.restroId
it.dishes.add(dish)
}
true
}
}
}
}
}
Log.d(ContentValues.TAG, "filterMenuForVeg : $filteredMenu ")
_currentRestroMenu.value = State.success(filteredMenu)
} else {
// set to all data
_currentRestroMenu.value = State.success(dataHolderMenuOnSearch)
}
When I filter dish for veg or non veg then add dish to cart (Which only changes userCart State flow) the place where I am collecting these state flow
get fired twice
so set data to adapter is getting called twice
What Iam doing wrong
Could you collect the items with onEach instead of collectLatest? It would solve your problem probably.

Problem creating user with email and password with Firebase

i'm new to android dev and Kotlin, the code was working fine till i added some validations. I don't know if i have too many if statements or i'm dong the validations all wrong even though they seems to be working. Any help would be appreciated
reg.setOnClickListener {
val eml = email.text.toString()
val passwr = password.text.toString()
val confirmPsw = confirmPsswrd.text.toString()
val fName = findViewById<EditText>(R.id.f_name).text.toString()
val lName = findViewById<EditText>(R.id.l_name).text.toString()
if (Patterns.EMAIL_ADDRESS.matcher(eml).matches()) {
if (passwr == confirmPsw && passwr.length >= 4) {
if (fName != "" || lName != "") {
auth.createUserWithEmailAndPassword(eml, passwr)
.addOnCompleteListener (this) { task ->
//if task isn't successful
if (task.isSuccessful) {
Toast.makeText(
this#Register,
" Successfully Registered, Login to continue",
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
this#Register,
" Registration error",
Toast.LENGTH_SHORT
).show()
}
}
} else {
val builder = AlertDialog.Builder(this)
with(builder)
{
setTitle("Some Fields Were Left Empty!!")
setMessage("*Please Enter Your First and Last Name(s)")
setPositiveButton(
"OK",
DialogInterface.OnClickListener(function = buttonClick)
)
show()
}
}
} else if (passwr.length < 4) {
password.error = "Password must be at least 4 characters long"
password.requestFocus()
} else {
confirmPsswrd.error = "Passwords don't match"
confirmPsswrd.requestFocus()
}
} else {
email.error = "Please enter a valid Email Address"
email.requestFocus()
}
}
Better do it with your addTextChangedListener
private fun passwordchanged(){
binding.passwordTextForSignUp.addTextChangedListener(object: TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val pass = binding.passwordTextForSignUp.text.toString().trim()
try {
if (PASSWORD_PATTERN.matcher(pass).matches()){
}
else{
binding.passwordTextForSignUp.setError("Invalid Password!")
binding.passwordTextForSignUpLayout.helperText = "Must be at least one number, at least one special character and at least 8 characters."
}
}catch (e : Exception){
Toast.makeText(this#SignUpActivity,e.localizedMessage,Toast.LENGTH_LONG).show()
}
}
and
private val PASSWORD_PATTERN: Pattern = Pattern.compile(
"^" + "(?=.*[0-9])" + //at least 1 digit
//"(?=.*[a-z])" + //at least 1 lower case letter
//"(?=.*[A-Z])" + //at least 1 upper case letter
"(?=.*[a-zA-Z])" + //any letter
"(?=.*[##$%^&+=.])" + //at least 1 special character
"(?=\\S+$)" + //no white spaces
".{8,}" + //at least 8 characters
"$"
)
Add Regex under "class SignUpActivity : AppCompatActivity() {"
If you want to check them again later, you can add an if to the button and query whether it is empty.

Cannot format given Object as a Number in Kotlin

An error occurred while using the ConverPrice function as follows for information about the price.
The price of the item in the recycler view adapter onBindViewHolder.
As a result of debugging, the error occurs in the following code.
priceText =
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
Please check my code and answer.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is DataViewHolder -> {
val item = dataList[position]
item.price.let {
holder.price.text = ConvertPrice(item, holder.price)
}
}
}
}
fun ConvertPrice(productDetail: ProductDetail?, tv: TextView? = null, setPrice: Boolean = false): String {
val disableColor = Color.parseColor("#aaaaaa")
val enableColor = Color.parseColor("#3692ff")
tv?.setTextColor(disableColor)
if (ProductDetail != null) {
val priceMin = productDetail.priceMin
val priceMax = productDetail.priceMax
var priceText = ""
val dec = DecimalFormat("##,###")
productDetail.enabledRetail?.let {
if (productDetail.enabledRetail == true) {
if (setPrice) {
priceText = if (priceMin == null || priceMax == null) {
"No pricing information"
} else {
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
}
tv?.setTextColor(disableColor)
}
else {
priceText = dec.format(wineDetail.price).toString()
tv?.setTextColor(enableColor)
}
return priceText
} else if (productDetail.cntRating!! > 0) {
if ((priceMin == null && priceMax == null) || (priceMin == 0 && priceMax == 0)) {
priceText = "No pricing information"
} else {
priceText =
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
tv?.setTextColor(disableColor)
}
return priceText
}
}
}
return "No pricing information"
}
DecimalFormat.format() only works fine with long or double. You should convert "priceMin" and "priceMax" to Long.
val priceMin = productDetail.priceMin.toLong()
val priceMax = productDetail.priceMax.toLong()
I recommend to use NumberFormat instead of DecimalFormat because it is locale-sensitive
val decFormat = NumberFormat.getInstance() // or getCurrencyInstance()
decFormat.maximumFractionDigits = 3
decFormat.format(priceMin)
decFormat.format(priceMax)