diff --git a/config.fish b/config.fish
index 3d22e3b499d026785dbad707f68a1dbed47de238..69c14dbc10811a3dcd9ab9a18793017b1e433db6 100644
--- a/config.fish
+++ b/config.fish
@@ -3,11 +3,18 @@ set _audio_player "mpg123"
 #set _audio_player "cvlc --play-and-exit"
 
 # Where should I signin ?
+# West XII
 set _NorthLatitude "30.508914"
 set _EastLongitude "114.40718"
+# South I
+#set _NorthLatitude "30.509595"
+#set _EastLongitude "114.41374"
 
 # How many seconds should I sleep after every check ?
 set _monitor_interval "10"
 
 # How many seconds should I delay before autosign ?
-set _autosign_delay "10"
+set _autosign_delay "1"
+
+# Notifier. Call Format: $notifier "Title" "Message"
+set _notify "notify-send"
diff --git a/daemon.sh b/daemon.sh
index ed5ac4921b1ecaf77a907a698cd5d112efc234b6..e4d37dc23c92e429e2f1f6b4d42922d718f76712 100755
--- a/daemon.sh
+++ b/daemon.sh
@@ -3,7 +3,7 @@
 [[ $1 == '' ]] && echo "usage: $0 sign/ans/all" && exit 1
 
 [[ $_openid == "" ]] && echo 'Give openid or url please:' && read _openid
-_openid=$(echo "$_openid" | sed 's/^.*openid=//g')
+_openid=$(echo "$_openid" | sed 's/^.*openid=//g' | sed 's/&.*$//g')
 echo "Set openid to $_openid"
 
 function _segfault_detected () {
diff --git a/impl/daemon-answer.fish b/impl/daemon-answer.fish
index 5e1079cd50b2115333c42d455a23e72952d84460..6a1116c3bca0842d3040eeaf2cd6934ca193e86b 100755
--- a/impl/daemon-answer.fish
+++ b/impl/daemon-answer.fish
@@ -12,19 +12,20 @@ function _check_and_warn
         return 0
     end
     eval $_audio_player answer.mp3 > /dev/null 2>&1
-    notify-send "Warning: Question opened!" "Question opened!"
+    echo "test"
+    eval $_notify "'Teachermate answer'" "'Question opened!'"
     echo "LOG> Detected!"
 end
 
 function _on_unknown_error
     eval $_audio_player error.mp3 > /dev/null 2>&1
-    notify-send "Warning: Error occurred!" "Error occurred!"
+    eval $_notify "'Teachermate answer'" "'Error occurred!'"
     echo "LOG> Error occurred!"
 end
 
 function _on_openid_error
     eval $_audio_player badid.mp3 > /dev/null 2>&1
-    notify-send "Warning: Invalid openid!" "Error: Invalid openid."
+    eval $_notify "'Teachermate answer'" "'Error: Invalid openid.'"
     echo "LOG> Invalid openid."
 end
 
diff --git a/impl/daemon-signin.fish b/impl/daemon-signin.fish
index 835d9a85fc07c5e404c54ec6ef04c1e6a2eb855d..44930467f2de03259c91071a6326b4409e3a8ea9 100755
--- a/impl/daemon-signin.fish
+++ b/impl/daemon-signin.fish
@@ -6,8 +6,8 @@ set _url "https://www.teachermate.com.cn/wechat/wechat/guide/signin?openid=$_ope
 source ../config.fish
 
 # Where should I signin ?
-test -z $_NorthLatitude; and set _NorthLatitude "30.509604"
-test -z $_EastLongitude; and set _EastLongitude "114.41374"
+test -z $_NorthLatitude; and echo "Warning: signin location _NorthLatitude not set. Rejecting dangerous operation..."; and exit 4
+test -z $_EastLongitude; and echo "Warning: signin location _EastLongitude not set. Rejecting dangerous operation..."; and exit 4
 
 # How many seconds should I delay before autosign ?
 test -z $_autosign_delay; and set _autosign_delay "10"
@@ -19,6 +19,22 @@ rm $tmpfl
 
 set signed_in false
 
+function on_signin_success
+    eval $_audio_player autosignin-success.mp3
+    eval $_notify "'Teachermate signin'" "'Signin success'"
+end
+
+function on_signin_fail
+    # will retry automatically
+    eval $_audio_player signin.mp3
+    eval $_notify "'Teachermate signin'" "'Signin failed'"
+end
+
+function on_badid
+    eval $_audio_player badid.mp3
+    eval $_notify "'Teachermate signin'" "'OpenID expired. Please restart the program with new openID'"
+end
+
 function do_signin
     if test $signed_in = true
         return
@@ -29,7 +45,7 @@ function do_signin
     set _wx_csrf (grep 'Set-Cookie' $cookiefl | sed 's/^.*wx_csrf_cookie=//' | sed 's/;.*$//')
     curl "https://www.teachermate.com.cn/wechat-api/v1/class-attendance/student-sign-in" --data "openid=$_openid&course_id=$_courseid&lon=$_EastLongitude&lat=$_NorthLatitude&wx_csrf_name=$_wx_csrf" > $cookiefl
     grep -F 'repeat sign in' $cookiefl; and set signed_in true; and return
-    grep -F '":["OK",' $cookiefl; and set signed_in true; and eval $_audio_player autosignin-success.mp3; or eval $_audio_player signin.mp3
+    grep -F '":["OK",' $cookiefl; and set signed_in true; and on_signin_success; or on_signin_fail
 end
 
 while true
@@ -37,7 +53,7 @@ while true
     date
     curl -L "$_url" -v 2>$cookiefl > $tmpfl
     if grep '{"data":\[\],"msg":"unauthorized"}' $tmpfl
-        eval $_audio_player badid.mp3
+        on_signin_fail
         continue
     end
     if grep '签到中...' $tmpfl