error handling when reading from buffer - network-programming

I have a tablet sending a 5 byte message to a device, the message i delivered ok but sometimes the data is written to the wrong part of the buffer.
the code i have for reading the buffer is as follows, buffer is an int[25]
if((tempByte != 0) && (tempByte != 0xEE)) // If 'ready' returned..
{
tempByte &= 0x3F;
if(tempByte > 0)
{
for(i = 0; i < tempByte; i++)
{
buffer[bufferWrite] = periph_irxdata() ;
bufferWrite++;
bufferContents++;
if(bufferWrite > 24)
{
bufferWrite = 0;
}
}
}
}
if(bufferContents >= 5)
{
for(i = 0; i < 5; i++)
{
readings[i] = buffer[bufferRead];
bufferRead++;
bufferContents--;
if(bufferRead > 24)
{
bufferRead = 0;
}
}
if(readings[0] == 0x18)
{
tabletValue = readings[2];
OnOff = readings[1];
}
}
The idea being that if you start at [0] and write 5 bytes each time a message of 18, 01, 02, 00, 00 would repeat starting at the values [0], [5], [10] [15] [20].
This would read 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 | 18, 01, 02, 00, 00 after 5 messages have been sent.
The problem is that occasionally an error occurs and the buffer ends up off bt one ot tow bytes and looks like this 02, 00, 00, 18, 01 | 02, 00, 00, 18, 01 | 02, 00, 00, 18, 01 02, 00, 00, 18, 01.
The messages are being sent find but the device ignores them as it see the messages as garbage as the do not line up with the reading blocks.
What can I do error handling wise to automatically fix this when it happens ?
I was thinking of moving the read to search for the next 18 and read 5 bytes or maybe try to find the next 18 and get the bytes written back into the correct blocks.

Related

How to use DateComponents to represent the extra 1 hour period at the end of day light saving?

Usually, during end of day light saving, we will be gaining extra 1 hours.
Take Tehran timezone as an example.
During 22 September 2021, Tehran will backward by 1 hour from 00:00
AM, to 11:00 PM.
I wrote the following code to demonstrate such.
import UIKit
func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) -> Date {
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = second
let date = Calendar.current.date(from: dateComponents)!
return date
}
// During 22 September 2021, Tehran will backward by 1 hour from 00:00 AM, to 11:00 PM.
let tehranTimeZone = TimeZone(identifier: "Asia/Tehran")!
let oldDefault = NSTimeZone.default
NSTimeZone.default = tehranTimeZone
defer {
NSTimeZone.default = oldDefault
}
let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59)
let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00)
let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01)
// STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Tuesday, September 21, 2021 at 11:59:59 PM Iran Daylight Time
print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(date1.description(with: .current))")
// STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Wednesday, September 22, 2021 at 12:00:00 AM Iran Standard Time
print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(date2.description(with: .current))")
// STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Wednesday, September 22, 2021 at 12:00:01 AM Iran Standard Time
print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(date3.description(with: .current))")
From STEP 1 transits to STEP 2, instead for their timeIntervalSince1970 different by +1 seconds, their difference are +3601 seconds, due to the extra 1 hour gain.
Now, my question is, how can we use DateComponents to represent the extra 1 hour period at the end of day light saving?
In another, how can I use DateComponents to generate a Date which is capable to print the following?
2021 Sep 21 23:00:00 => 1632252600.0, Tuesday, September 21, 2021 at 11:00:00 PM Iran Standard Time
Now, we understand that, in Tehran, during 2021 Sept 21, there are 2 type of 23:00:00 time
23:00:00 Iran Daylight time (Epoch is 1632249000)
23:00:00 Iran Standard time (Epoch is 1632252600)
23:00:00 Iran Daylight time (Epoch is 1632249000)
I can represent the above using
let date = date(year: 2021, month: 09, day: 21, hour: 23, minute: 00, second: 00)
23:00:00 Iran Standard time (Epoch is 1632252600)
I have no idea how to represent the above. As, I do not find a way in DateComponents, to enable us to specific whether the local time is belong to standard time, or daylight time.
DateComponents do not have a time zone. The time zone comes into it when you convert DateComponents to a Date, using the call Calendar.date(from:). It's the calendar's time zone that determines how those DateComponents are converted to a Date.
Instead of using Calendar.current, create a custom calendar and set it to the IRST time zone. (I couldn't figure out the time zone for Iran Daylight time. I would have expected it to have the abbreviation "IRDT", but that doesn't work.)
Let's say we have a calendar irstCalendar that's set to Iran Standard Time ("IRST").
If you use irstCalendar.date(from: dateComponents) you'll always get the Date based on standard time.
Consider this code:
func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, calendar: Calendar = Calendar.current) -> Date {
var dateComponents = DateComponents()
dateComponents.year = year
dateComponents.month = month
dateComponents.day = day
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = second
let date = calendar.date(from: dateComponents)!
return date
}
guard let tehranStandardTimeZone = TimeZone(abbreviation: "IRST") else {
fatalError("Can't create time zones")
}
var tehranSTCalendar = Calendar(identifier: .gregorian)
tehranSTCalendar.timeZone = tehranStandardTimeZone
let tehranDateFormatter = DateFormatter()
tehranDateFormatter.dateStyle = .medium
tehranDateFormatter.timeStyle = .medium
tehranDateFormatter.timeZone = tehranStandardTimeZone
let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59, calendar: tehranSTCalendar)
let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00, calendar: tehranSTCalendar)
let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01, calendar: tehranSTCalendar)
print("STEP 1: 2021 Sep 21 23:59:59 => \(date1.timeIntervalSince1970), \(tehranDateFormatter.string(from:date1))")
print("STEP 2: 2021 Sep 22 00:00:00 => \(date2.timeIntervalSince1970), \(tehranDateFormatter.string(from:date2))")
print("STEP 3: 2021 Sep 22 00:00:01 => \(date3.timeIntervalSince1970), \(tehranDateFormatter.string(from:date3))")
That outputs:
STEP 1: 2021 Sep 21 23:59:59 => 1632252599.0, Sep 21, 2021 at 11:59:59 PM
STEP 2: 2021 Sep 22 00:00:00 => 1632256200.0, Sep 22, 2021 at 12:00:00 AM
STEP 3: 2021 Sep 22 00:00:01 => 1632256201.0, Sep 22, 2021 at 12:00:01 AM

Why isn't the offset of Samoa +13 or +14 when using pytz?

I've just read
BBC: Samoa and Tokelau skip a day for dateline change, 30.12.2011
I wanted to see this with pytz, but everything I tried only showed an offset of -11, but not of +13 or +14:
>>> import pytz
>>> tz = pytz.timezone('Pacific/Samoa')
>>> tz_us = pytz.timezone('US/Samoa')
>>> import datetime
>>> datetime.datetime(2011, 12, 30, 9, 00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-29T22:00:00-11:00'
>>> datetime.datetime(2011, 12, 30, 10,00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-29T23:00:00-11:00'
>>> datetime.datetime(2011, 12, 30, 11, 00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-30T00:00:00-11:00'
>>> datetime.datetime(2011, 12, 31, 15, 00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-31T04:00:00-11:00'
>>> datetime.datetime(2015, 12, 31, 15, 00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2015-12-31T04:00:00-11:00'
>>> datetime.datetime(2011, 12, 31, 15, 00, tzinfo=datetime.timezone.utc).astimezone(tz_us).isoformat()
'2011-12-31T04:00:00-11:00'
>>> datetime.datetime(2015, 12, 31, 15, 00, tzinfo=datetime.timezone.utc).astimezone(tz_us).isoformat()
'2015-12-31T04:00:00-11:00'
Why can't I see the offset +13 / +14?
Both Pacific/Samoa and US/Samoa are aliases of Pacific/Pago_Pago, representing American Samoa, which is UTC-11 and did not skip that day.
For American Samoa, use Pacific/Pago_Pago
For the Independent State of Samoa, use Pacific/Apia
For Tokelau, use Pacific/Fakaofo
Personally, I prefer to only use canonical zone names. See the list on Wikipedia for reference.
See the timezone change with pytz
UTC time with offset:
>>> import pytz
>>> tz = pytz.timezone('Pacific/Apia')
>>> import datetime
>>> datetime.datetime(2011, 12, 30, 9, 59, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-29T23:59:00-10:00'
>>> datetime.datetime(2011, 12, 30, 10, 00, tzinfo=datetime.timezone.utc).astimezone(tz).isoformat()
'2011-12-31T00:00:00+14:00'
Local time:
>>> '{:%Y-%m-%d %H:%M}'.format(datetime.datetime(2011, 12, 30, 9, 59, tzinfo=datetime.timezone.utc).astimezone(tz))
'2011-12-29 23:59'
>>> '{:%Y-%m-%d %H:%M}'.format(datetime.datetime(2011, 12, 30, 10, 00, tzinfo=datetime.timezone.utc).astimezone(tz))
'2011-12-31 00:00'

Check if time is between two times ruby

I'm looking to check if the DateTime.now is between 2 particular date and times on Ruby on Rails.
I can't seem to figure it out
def closed?
(DateTime.now > DateTime.new(2018, 6, 28, 13, 00, 00)) && (DateTime.now < DateTime.new(2018, 6, 28, 14, 00, 00))
end
I would use the between?(min, max) function from ActiveSupport:
def closed?
DateTime.now.between?(DateTime.new(2018, 6, 28, 13, 00, 00), DateTime.new(2018, 6, 28, 14, 00, 00))
end
You can use cover? method for that
now = DateTime.now
start = DateTime.new(2018, 6, 28, 13, 00, 00)
stop = DateTime.new(2018, 6, 28, 14, 00, 00)
p (start..stop).cover? now
Hope it will help you :)
If you want to only compare time then you can simply do
Time.zone.now.between?(Time.zone.parse("12:00"), Time.zone.parse("18:00"))
Time zone is a important factor here.

how to send hexadecimal values using gcdasyncsocket?

I have an array with nsstring like:
<__NSArrayM 0x20860370>(
3a,
4d,
00,
03,
04,
00,
07,
00,
0d,
0a
)
how can i send this data as real hexadecimal values using GCDAsyncsocket? I need to send all this values for every time i call the function for write to socket (es: 3a,
4d,
00,
03,
04,
00,
07,
00,
0d,
0a
)
I try using a function like:
[socket writeData:[array dataUsingEncoding:NSUTF8StringEncoding] withTimeout:1 tag:0];
But in this way i send character, not hex values...
thanks for your help!

How to identify if the given day, month, and year, combine a legal date?

Given 3 numbers: DD, MM, YYYY, what is the easiest way to know if they combine a legal date ?
Examples:
14, 05, 2011 => Legal
29, 02, 2011 => Illegal
29, 02, 2012 => Legal
35, 11, 1989 => Illegal
14, 18, 2011 => Illegal
14, 00, 2011 => Illegal
00, 11, 1979 => Illegal
31, 11, 1979 => Illegal
You can use valid_date? But it's YYYY, MM, DD:
irb(main):015:0> require 'date'
=> true
irb(main):021:0> Date::valid_date?(2011,05,14)
=> true
irb(main):022:0> Date::valid_date?(2011,02,29)
=> false
irb(main):023:0> Date::valid_date?(2012,02,29)
=> true
Date has a method valid_civil? .
require 'date'
dates = DATA.readlines.map{|line| line.split(', ').map(&:to_i)}
dates.each do |date|
d, m, y = date
puts Date.valid_civil?(y, m, d)
end
__END__
14, 05, 2011
29, 02, 2011
29, 02, 2012
35, 11, 1989
14, 18, 2011
14, 00, 2011
00, 11, 1979
31, 11, 1979
One option is to use something like:
require 'time'
def valid(year,month,day)
Time.parse "#{year}#{month}#{day}" rescue return false
return true
end

Resources