How to keep track of changed values - java

I have a bluetooth device which keeps emitting data when it is started and stops emitting data when it pauses, I have RXJava subscriber attached to it to get the values.
What I want to do is check if the device is still running or paused. So for this I have a method getTotalizerChangedTime, this gives me the last updated time.
Based on getTotalizerChangedTime I want to check if the device is still running or not.
I want to check lastUpdatedTotalizerChangeTime and calculator.getLastTotalizerChangeTime() and if they both are same and time difference between them is 8 seconds (as every 8 seconds or so I get a value)
lastTotalizerChangeTime - 2019-09-04T18:33:40.781+01:00
lastTotalizerChangeTime - 2019-09-04T18:33:47.080+01:00
lastTotalizerChangeTime - 2019-09-04T18:33:57.592+01:00
lastTotalizerChangeTime - 2019-09-04T18:34:03.683+01:00
What I have tried is, I declared a variable to keep the last updated
private DateTime lastUpdatedTotalizerChangeTime = new DateTime();
I created a function which get the lastTotalizerChangeTime from getLastTotalizerChangeTime and does the following but does not work as expected.
Function that get the actual value
public DateTime getLastTotalizerChangeTime() {
return lastTotalizerChangeTime;
}
I have declared a variable to keep the lastUpdatedChangedTime
private DateTime lastUpdatedTotalizerChangeTime = new DateTime();
Bellow is the function that gets called on button click which checks if the device is still running
private boolean hasFlowMeterFinishedPumping(){
DateTime currentTime = new DateTime();
Period differenceX = new Period(calculator.getLastTotalizerChangeTime(), currentTime);
if(differenceX.getSeconds() >= 8 && lastUpdatedTotalizerChangeTime.equals(calculator.getLastTotalizerChangeTime())){
Log.d("totaliserSenseCheck", "IF");
lastUpdatedTotalizerChangeTime = calculator.getLastTotalizerChangeTime();
return true;
}else{
Log.d("totaliserSenseCheck", "else");
lastUpdatedTotalizerChangeTime = calculator.getLastTotalizerChangeTime();
return false;
}
}
Logic I have written to track if the device stopped does not work as expected.
Your help much appreciated.
R

Related

Cache2K auto refreshAhead does'nt work as expected

I'm trying to create cache with auto refreshing elements using org.cache2k library.
For example I define element loader with duration of 5 seconds.
I set expire time 5 seconds. And I set keepDataAfterExpired and refreshAhead options to true.
First calling get method lasts approximatelly 5 seconds. It's ok.
Then I expect that element will be expired and auto reloaded during next 15 seconds
and second get will take element without delay. But my output is:
result
5011
result
5000
Second get as first lasts also 5 seconds as first.
My goal is to make element refresh automatically and only first get would take delay.
Is it reachable and how? Thank you.
static String expensiveOperation(String name) throws InterruptedException {
Thread.sleep(5000);
return "result";
}
public static void main (String... args) throws InterruptedException {
Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
.expireAfterWrite(5000, TimeUnit.MILLISECONDS) // expire/refresh after 5 seconds
.keepDataAfterExpired(true)
.refreshAhead(true) // keep fresh when expiring
.loader(s->expensiveOperation(s)) // auto populating function
.build();
Instant i1 = Instant.now();
System.out.println(cache.get("a"));
Instant i2 = Instant.now();
System.out.println(Duration.between(i1,i2).toMillis());
Thread.sleep(15000);
Instant i11 = Instant.now();
System.out.println(cache.get("a"));
Instant i22 = Instant.now();
System.out.println(Duration.between(i11,i22).toMillis());
I found the answer in documentation about refreshAhead in Cache2k:
"Once refreshed, the entry is in a trail period. If it is not accessed until the next expiry, no refresh will be done, the entry expires and will be removed from the cache. This means that the time an entry stays within the trail period is determined by the configured expiry time or the the ExpiryPolicy."
So in my case 15 seconds is enough for entry to be auto refreshed and then expired and removed, so next get triggers a new load.

Show system time upto minute on UWP UI

I want to show current Time on upto minute only in UWP. Time needs to be sync with system time so that system time and App time will show exact time upto minute .
I am using timer for this. Initial interval is based in current time.
private const string TIME_FORMAT = "hh:mm";
private static int TIMER_INTERVAL_ONE_MINUTE = 60 * 1000;
private static Timer countdownTimer;
private static DateTime liveDateTime = DateTime.Now;
private static bool isTimerRunning = false;
static ViewModel()
{
countdownTimer = new Timer();
countdownTimer.Elapsed += CountdownTimer_Elapsed;
countdownTimer.Interval = TIMER_INTERVAL_ONE_MINUTE - DateTime.Now.Second;
countdownTimer.Start();
isTimerRunning = true;
}
private static void CountdownTimer_Elapsed(object sender, ElapsedEventArgs e)
{
ApplicationDispatcher.RunOnUIThread(() =>
{
liveDateTime = DateTime.Now;
countdownTimer.Interval = TIMER_INTERVAL_ONE_MINUTE;
});
}
But sometimes my UI is not in sync with System because statements needs some times to execute also which cases initial to set incorrectly with small fraction.
I don't want to run my timer too frequently.
How can I show time upto minute uwith sync System time.
Regards
From your code, you are only assigning variables, which does not need to be done with Thread.
In UWP, the way to get the current time is through DateTime.Now. If you want to save the current time as a variable and keep it updated, you need a timer.
We recommend using DispatcherTimer in UWP app, it is a timer running on the UI thread, which can be written like this:
private DispatcherTimer _timer;
private static DateTime liveDateTime = DateTime.Now;
public ViewModel()
{
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(1);
_timer.Tick += Timer_Tick;
_timer.Start();
// other code ...
}
private void Timer_Tick(object sender, object e)
{
liveDateTime = DateTime.Now;
}
Since it is not known when to start the timer, using one minute as the timing interval may cause delay. It is recommended to shorten the timer interval to 10 seconds or less.
Best regards.

How to create a single thread cooldown

I'm finding the way to make a Single thread cooldown but get stuck.
In the class who manages the cooldown I created a:
private HashMap<UUID,Integer> players = new HashMap<>();
//UUID = Player UUID
//Integer = Time in cooldown (Seconds)
public void run(){
for(UUID player : players){
//WHAT I NEED TO DO HERE?
if(//Time == 0){
players.remove(player);
}
}
}
Didn't use an IDE hopefully I didn't miss an error that eclipse would have picked up.
But how I can get the integer and save it with a second less?
TimeUnit is used for delaying a process, as it could be used as followed:
TimeUnit.SECONDS.sleep(1);
This will delay the current thread by one second.
I won't suggest using it, because your situation sounds more like a thread is working in the background and you want to wait till it has finished! Therefore use the new feature isAlive, which could be used in a (while) loop.
Edit
If you do want to delay a thread from another thread over the instance, then I'd suggest using the sleep method.
Example:
myThread.sleep(1000);
This will delay myThread by one second.
Edit #2
To change a value for a certain key of a HashMap, use the put and get method.
Example:
// Get the time of a player and subtract it by one
Integer value = players.get(player) - 1;
// Update the value
players.put(player, value);
// If the time runs out, than delete the player
if (value == 0){
players.remove(player);
}

Adding scheduled items to multi-slot crafting queue

I'm working on an Android game.
Areas in the game have crafting slots which determine how many items can be crafted at once. If there are no slots available, the item is given a scheduled start date which correlates to when a slot will become available.
The problem I'm encountering is that the current code only considers when the first slot will become available, not when any slot will.
Adding scheduled item:
long timeSlotAvailable = getTimeSlotAvailable(location);
Pending_Inventory newScheduledItem = new Pending_Inventory(itemId, state, timeSlotAvailable, quantity, craftTime, location);
Getting the time a slot is available:
public static long getTimeSlotAvailable(Long location) {
List<Pending_Inventory> pendingItems = getPendingItems(location, true);
int locationSlots = Slot.getUnlockedSlots(location);
long timeAvailable = System.currentTimeMillis();
// Works for single slots, not for multi though. Needs to consider slot count.
for (Pending_Inventory pending_inventory : pendingItems) {
long finishTime = pending_inventory.getTimeCreated() + pending_inventory.getCraftTime();
if (finishTime > timeAvailable) {
timeAvailable = finishTime;
}
}
return timeAvailable;
}
The code works by looking through every item currently being crafted or scheduled to craft, and getting the time the last one finishes.
locationSlots is currently unused, but I believe it will be required to calculate the correct time a slot will be available.
I've tried a few approaches (adding all finish times to an array & getting the n value showed promise, but I couldn't get my head around it), but am all out of ideas.
Thanks!
Eventually took another go at the array approach, and succeeded.
public static long getTimeSlotAvailable(Long location) {
List<Pending_Inventory> pendingItems = getPendingItems(location, true);
int numSlots = Slot.getUnlockedSlots(location);
// Add all of the times a slot will become available to a list
List<Long> finishTimes = new ArrayList<>();
for (Pending_Inventory pending_inventory : pendingItems) {
long finishTime = pending_inventory.getTimeCreated() + pending_inventory.getCraftTime();
finishTimes.add(finishTime);
}
// Sort these times so the latest time is first
Collections.sort(finishTimes, Collections.<Long>reverseOrder());
if (finishTimes.size() >= numSlots) {
// If we're all full up, get the first time a slot will become available
return finishTimes.get(numSlots-1);
} else {
// Otherwise, it can go in now
return System.currentTimeMillis();
}
}
Hopefully that helps someone in the future with a similar problem.

Java: If-else statement

I made a twitch irc bot.
I have setup a little "system" to turn itself on whenever the stream is going online and should turn off when the stream isnt online anymore.
im using the following code:
if (TwitchStatus.isstreamlive && multistartprepare == false && multistartprepare2 == false){
livemode = true;
multistartprepare = true;
startedAt = DateTime.now();
startup();
}else{
if (TwitchStatus.isstreamlive == false && multistartprepare){
livemode = false;
multistartprepare = false;
multistartprepare2 = false;
TTmsg.cancel();
TTmsg.purge();
}
}
isstreamlive is a boolean which is either true when a stream is live or false when the stream is offline.
isstreamlive gets updated every 5 secons by making a JSON request and holds the right value the whole time.
the problem now is that the startup() Method will activate a timer for a greeting message in the irc chat. Somehow it happens the timer got executed 2 or 3 times when i start my bot so i guess something is wrong with my if else statement.
the booleans multistartprepare and multistartprepare2 are false on start and are there for the bot to start only once a time, til the stream is over and he can get offline.
is there something wrong above? Guess the code gets executed to many times.
greetings and sorry for bad english :D
It might help if you use your livemode variable in the if as well
if (TwitchStatus.isstreamlive &&
!multistartprepare &&
!multistartprepare2 &&
!livemode) {
You might be able work around this by setting up a timeout that prevents your bot from sending the message if it's been sent in the past few seconds.
long lastSent = 0;
...
if (System.currentTimeMillis() - lastSent > 1000*5) { // 5 seconds elapsed
...
// send message
lastSent = System.currentTimeMillis();
}
You might have something wrong with your setup method, or the server might be sending you multiple went-online messages, but it's hard to tell based on the info you have so far.

Categories