Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timezone within Neolink #296

Closed
nevilth opened this issue Aug 30, 2024 Discussed in #105 · 2 comments
Closed

Timezone within Neolink #296

nevilth opened this issue Aug 30, 2024 Discussed in #105 · 2 comments

Comments

@nevilth
Copy link

nevilth commented Aug 30, 2024

Discussed in #105

Problem:
When neolink sets the camera time it sets the the timezone as GMT rather than in the local time zone. This means the onscreen timestamp as displayed by the camera to be in GMT. Not a functional error but leads to possibility of the time as displayed being misinterpreted.

Environment:

OS: Debian 12
Camera: Swann NHD-819

Internal Model # IPC_388M
Firmware: 541_17051800

Client: Synology NAS running Surveillance Station 9.2.0

Neolink: Docker container; quantumentangledandy/neolink

Docker configuration

  neolink:
    container_name: neolink
    image: quantumentangledandy/neolink
    mem_limit: 250M
    cpus: 0.5
    ports:
      - 8554:8554
    environment:
      - TZ=Australia/Melbourne
      - RUST_LOG=debug
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /opt/docker/neolink/config/neolink.toml:/etc/neolink.toml
    restart: unless-stopped

neolink configuration:

# A bind value of 0.0.0.0 means any network this computer can access
# You can chage this to a specfic network e.g. "192.168.1.101" here
# Or to no networks e.g. this computer only "127.0.0.1"
bind = "0.0.0.0"

# Default port is 8554 but you can change it by uncommenting the following
# bind_port = 8554

# Uncomment the following and supply a path to a valid PEM
# to activate TLS encryption.
# The PEM should contain the certificate and the private key
# If TLS is activated you must connect with "rtsps://" and not "rtsp://"
# certificate = "/path/to/pem/with/cert/and/key"

# Choose if the client is required to provide a certificate signed by the server                                                                                                                                                             's CA.
# none|requested|required - default none
# tls_client_auth = "required"

# You can password protect the rtsp server mount points by adding users
# like the following me and someone. If you do not add [[users]]
# then anyone can connect without a password or username
# To access such a stream try using a url such as "rtsp://me:[email protected]                                                                                                                                                             1/driveway"

#[[users]]
#name = "admin"
#pass = "mepass"
#
# [[users]]
# name = "someone"
# pass = "someonepass"


[[cameras]]
name = "Camera_1"
username = "admin"
password = "12345"
address = "192.168.80.160:9000"
stream = "mainStream"
push_notifications=false
[cameras.pause]
  on_client = true # Should pause when no rtsp client

[[cameras]]
name = "Camera_2"
username = "admin"
password = "12345"
address = "192.168.80.161:9000"
stream = "mainStream"
push_notifications = false
[cameras.pause]
  on_client = true # Should pause when no rtsp client

[[cameras]]
name = "Camera_3"
username = "admin"
password = "12345"
address = "192.168.80.162:9000"
stream = "mainStream"
push_notifications = false
[cameras.pause]
  on_client = true # Should pause when no rtsp client

[[cameras]]
name = "Camera_4"
username = "admin"
password = "12345"
address = "192.168.80.163:9000"
stream = "subStream"
push_notifications = false
[cameras.pause]
  on_client = true # Should pause when no rtsp client

[[cameras]]
name = "Camera_5"
username = "admin"
password = "12345"
address = "192.168.80.164:9000"
stream = "subStream"
push_notifications = false
[cameras.pause]
  on_client = true # Should pause when no rtsp client

Getting a bash shell in the container shows that the date time appears to be set correctly and the TZ variable is set.

nevil@THASRVR:/opt/docker$ docker compose run -it neolink bash
Running: bash

root@64b19fe89cff:/# date
Thu Aug 15 17:24:51 AEST 2024

root@64b19fe89cff:/# echo $TZ
Australia/Melbourne

Camera time is currently configured with local timezone and the time is in sync with the time on neolink server:

neolink  | [2024-08-30T02:22:46Z INFO  neolink::common::camthread] Camera_3: Camera time is already set: 2024-08-30 12:22:46.0 -10:00:00

Camera time is currently configured with local timezone and the time is NOT in sync with time on neolink server:

neolink | [2024-08-15T07:29:51Z WARN neolink::common::camthread] Camera_3: Camera has no time set, Updating
neolink | [2024-08-15T07:29:51Z INFO neolink::common::camthread] Camera_3: Setting time to SystemTime { tv_sec: 1723706991, tv_nsec: 577389491 }
neolink | [2024-08-15T07:29:51Z INFO neolink::common::camthread] Camera_3: Camera time is now set: 2024-08-15 7:29:51.0 +00:00:00

The camera is now set with time zone GMT (the on screen display shows the time as GMT).

Investigation by Andrew: (from original thread)

QuantumEntangledAndy
2 weeks ago
Maintainer
Just spent the last 10 mins looking into this and since we use std::time to handle the time part of the code (which is not geared towards time display) it will always be in gmt.

If I wanted to fix this I'd probably just need to swap to the time-rs crate instead. Not sure it's something I'd want to do as it's just formatting, but maybe something to clean up if I'm ever editing that part.

If you want to PR it then the relevant part is in

[neolink/src/common/camthread.rs](https://github.com/QuantumEntangledAndy/neolink/blob/f15fdaefbcfe5cde3b0289c1e106cb85f6d3d39b/src/common/camthread.rs#L197-L231)
Lines 197 to 231 in [f15fdae](https://github.com/QuantumEntangledAndy/neolink/commit/f15fdaefbcfe5cde3b0289c1e106cb85f6d3d39b)

 async fn update_camera_time(camera: &BcCamera, name: &str, update_time: bool) -> AnyResult<()> { 
     let cam_time = camera.get_time().await?; 
     let mut update = false; 
     if let Some(time) = cam_time { 
         log::info!("{}: Camera time is already set: {}", name, time); 
         if update_time { 
             update = true; 
         } 
     } else { 
         update = true; 
         log::warn!("{}: Camera has no time set, Updating", name); 
     } 
     if update { 
         use std::time::SystemTime; 
         let new_time = SystemTime::now(); 
  
         log::info!("{}: Setting time to {:?}", name, new_time); 
         match camera.set_time(new_time.into()).await { 
             Ok(_) => { 
                 let cam_time = camera.get_time().await?; 
                 if let Some(time) = cam_time { 
                     log::info!("{}: Camera time is now set: {}", name, time); 
                 } 
             } 
             Err(e) => { 
                 log::error!( 
                     "{}: Camera did not accept new time (is user an admin?): Error: {:?}", 
                     name, 
                     e 
                 ); 
             } 
         } 
     } 
     Ok(()) 
 }
@Arjenlodder
Copy link

Agree, I'd really like to see the local time.

@QuantumEntangledAndy
Copy link
Owner

@Arjenlodder It's nice and I wouldn't mind it either but it's something I'm just going to leave to standard logging tools rather than write my own

@QuantumEntangledAndy QuantumEntangledAndy closed this as not planned Won't fix, can't repro, duplicate, stale Jan 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants